diff --git a/webrtc/base/safe_compare.h b/webrtc/base/safe_compare.h index 39fb917a70..494a0c1404 100644 --- a/webrtc/base/safe_compare.h +++ b/webrtc/base/safe_compare.h @@ -37,6 +37,8 @@ #include #include +#include "webrtc/base/type_traits.h" + namespace rtc { namespace safe_cmp { @@ -145,81 +147,21 @@ RTC_SAFECMP_MAKE_OP(GtOp, >) RTC_SAFECMP_MAKE_OP(GeOp, >=) #undef RTC_SAFECMP_MAKE_OP -// Determines if the given type is an enum that converts implicitly to -// an integral type. -template -struct IsIntEnum { - private: - // This overload is used if the type is an enum, and unary plus - // compiles and turns it into an integral type. - template ::value && - std::is_integral())>::value>::type* = - nullptr> - static int Test(int); - - // Otherwise, this overload is used. - template - static char Test(...); - - public: - static constexpr bool value = - std::is_same::type>(0)), - int>::value; -}; - -// Determines if the given type is integral, or an enum that -// converts implicitly to an integral type. -template -struct IsIntlike { - private: - using X = typename std::remove_reference::type; - - public: - static constexpr bool value = - std::is_integral::value || IsIntEnum::value; -}; - -namespace test_enum_intlike { - -enum E1 { e1 }; -enum { e2 }; -enum class E3 { e3 }; -struct S {}; - -static_assert(IsIntEnum::value, ""); -static_assert(IsIntEnum::value, ""); -static_assert(!IsIntEnum::value, ""); -static_assert(!IsIntEnum::value, ""); -static_assert(!IsIntEnum::value, ""); -static_assert(!IsIntEnum::value, ""); - -static_assert(IsIntlike::value, ""); -static_assert(IsIntlike::value, ""); -static_assert(!IsIntlike::value, ""); -static_assert(IsIntlike::value, ""); -static_assert(!IsIntlike::value, ""); -static_assert(!IsIntlike::value, ""); - -} // test_enum_intlike } // namespace safe_cmp_impl -#define RTC_SAFECMP_MAKE_FUN(name) \ - template ::value && \ - safe_cmp_impl::IsIntlike::value>::type* = nullptr> \ - inline bool name(T1 a, T2 b) { \ - /* Unary plus here turns enums into real integral types. */ \ - return safe_cmp_impl::Cmp(+a, +b); \ - } \ - template ::value || \ - !safe_cmp_impl::IsIntlike::value>::type* = nullptr> \ - inline bool name(T1&& a, T2&& b) { \ - return safe_cmp_impl::name##Op::Op(a, b); \ +#define RTC_SAFECMP_MAKE_FUN(name) \ + template ::value && \ + IsIntlike::value>::type* = nullptr> \ + inline bool name(T1 a, T2 b) { \ + /* Unary plus here turns enums into real integral types. */ \ + return safe_cmp_impl::Cmp(+a, +b); \ + } \ + template ::value || \ + !IsIntlike::value>::type* = nullptr> \ + inline bool name(T1&& a, T2&& b) { \ + return safe_cmp_impl::name##Op::Op(a, b); \ } RTC_SAFECMP_MAKE_FUN(Eq) RTC_SAFECMP_MAKE_FUN(Ne) diff --git a/webrtc/base/type_traits.h b/webrtc/base/type_traits.h index d6a6c37334..a57bead6c1 100644 --- a/webrtc/base/type_traits.h +++ b/webrtc/base/type_traits.h @@ -72,6 +72,69 @@ static_assert(!HasDataAndSize::value, } // namespace test_has_data_and_size +namespace type_traits_impl { + +// Determines if the given type is an enum that converts implicitly to +// an integral type. +template +struct IsIntEnum { + private: + // This overload is used if the type is an enum, and unary plus + // compiles and turns it into an integral type. + template ::value && + std::is_integral())>::value>::type* = + nullptr> + static int Test(int); + + // Otherwise, this overload is used. + template + static char Test(...); + + public: + static constexpr bool value = + std::is_same::type>(0)), + int>::value; +}; + +} // namespace type_traits_impl + +// Determines if the given type is integral, or an enum that +// converts implicitly to an integral type. +template +struct IsIntlike { + private: + using X = typename std::remove_reference::type; + + public: + static constexpr bool value = + std::is_integral::value || type_traits_impl::IsIntEnum::value; +}; + +namespace test_enum_intlike { + +enum E1 { e1 }; +enum { e2 }; +enum class E3 { e3 }; +struct S {}; + +static_assert(type_traits_impl::IsIntEnum::value, ""); +static_assert(type_traits_impl::IsIntEnum::value, ""); +static_assert(!type_traits_impl::IsIntEnum::value, ""); +static_assert(!type_traits_impl::IsIntEnum::value, ""); +static_assert(!type_traits_impl::IsIntEnum::value, ""); +static_assert(!type_traits_impl::IsIntEnum::value, ""); + +static_assert(IsIntlike::value, ""); +static_assert(IsIntlike::value, ""); +static_assert(!IsIntlike::value, ""); +static_assert(IsIntlike::value, ""); +static_assert(!IsIntlike::value, ""); +static_assert(!IsIntlike::value, ""); + +} // test_enum_intlike + } // namespace rtc #endif // WEBRTC_BASE_TYPE_TRAITS_H_