Commit 83b597e5 authored by Joe Loser's avatar Joe Loser Committed by Facebook Github Bot

Add to_underlying_type to cast enum to underlying (#1028)

Summary:
- It is verbose at the call sites to cast an enum or enum class to its
  underlying type.
- Introduce `to_underlying_type`, which, given an enum or enum class,
  returns the value from static casting to the underlying type.
Pull Request resolved: https://github.com/facebook/folly/pull/1028

Reviewed By: stevegury

Differential Revision: D14199619

Pulled By: yfeldblum

fbshipit-source-id: fde85b9be50945a390b18ba1448a0137f3d7b63e
parent b66dfacb
......@@ -43,6 +43,7 @@
#include <folly/Range.h>
#include <folly/Traits.h>
#include <folly/Unit.h>
#include <folly/Utility.h>
#include <folly/lang/Exception.h>
#include <folly/lang/Pretty.h>
#include <folly/portability/Math.h>
......@@ -648,15 +649,13 @@ template <class Tgt, class Src>
typename std::enable_if<
std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt* result) {
toAppend(
static_cast<typename std::underlying_type<Src>::type>(value), result);
toAppend(to_underlying_type(value), result);
}
template <class Src>
typename std::enable_if<std::is_enum<Src>::value, size_t>::type
estimateSpaceNeeded(Src value) {
return estimateSpaceNeeded(
static_cast<typename std::underlying_type<Src>::type>(value));
return estimateSpaceNeeded(to_underlying_type(value));
}
/*******************************************************************************
......@@ -1547,8 +1546,7 @@ typename std::enable_if<
!std::is_convertible<Tgt, StringPiece>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) {
using I = typename std::underlying_type<Src>::type;
return tryTo<Tgt>(static_cast<I>(value));
return tryTo<Tgt>(to_underlying_type(value));
}
template <class Tgt, class Src>
......@@ -1567,7 +1565,7 @@ typename std::enable_if<
!std::is_convertible<Tgt, StringPiece>::value,
Tgt>::type
to(const Src& value) {
return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
return to<Tgt>(to_underlying_type(value));
}
template <class Tgt, class Src>
......
......@@ -27,6 +27,7 @@
#include <folly/Likely.h>
#include <folly/Optional.h>
#include <folly/Traits.h>
#include <folly/Utility.h>
#include <folly/dynamic.h>
#include <folly/lang/Exception.h>
......@@ -334,8 +335,7 @@ struct DynamicConstructor<
C,
typename std::enable_if<std::is_enum<C>::value>::type> {
static dynamic construct(const C& x) {
using type = typename std::underlying_type<C>::type;
return dynamic(static_cast<type>(x));
return dynamic(to_underlying_type(x));
}
};
......
......@@ -22,6 +22,7 @@
#include <utility>
#include <folly/CPortability.h>
#include <folly/Portability.h>
#include <folly/Traits.h>
namespace folly {
......@@ -299,4 +300,10 @@ constexpr auto to_unsigned(T const& t) -> typename std::make_unsigned<T>::type {
return static_cast<U>(t);
}
template <class E>
constexpr std::underlying_type_t<E> to_underlying_type(E e) noexcept {
static_assert(std::is_enum<E>::value, "not an enum type");
return static_cast<std::underlying_type_t<E>>(e);
}
} // namespace folly
......@@ -506,7 +506,7 @@ struct IsAvalanchingHasher<hasher<std::string>, K> : std::true_type {};
template <typename T>
struct hasher<T, std::enable_if_t<std::is_enum<T>::value>> {
size_t operator()(T key) const noexcept {
return Hash()(static_cast<std::underlying_type_t<T>>(key));
return Hash()(to_underlying_type(key));
}
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment