diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 241883a02cb..0cb8e9789dc 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -121,45 +121,43 @@ template <> struct is_integral_impl : true_type {}; template struct is_integral : is_integral_impl {}; -namespace dont_use { - // Form a return type that can only be instantiated with an integral or enum - // types (or with nullptr_t in C++11). - template struct check_nontype_temp_param_return_type { - char c[2]; - }; - template - check_nontype_temp_param_return_type check_nontype_temp_param(U*); - template char check_nontype_temp_param(...); - - // Form a return type that can only be instantiated with nullptr_t in C++11 - // mode. It's harmless in C++98 mode, but this allows us to filter nullptr_t - // when building in C++11 mode without having to detect that mode for each - // different compiler. - struct nonce {}; - template - struct check_nullptr_t_like_return_type { char c[2]; }; - template - check_nullptr_t_like_return_type check_nullptr_t_like(U*); - template char check_nullptr_t_like(...); -} // namespace dont_use - -/// \brief Metafunction that determines whether the given type is either an -/// integral type or an enumeration type. -/// -/// Note that this accepts potentially more integral types than we whitelist -/// above for is_integral, it should accept essentially anything the compiler -/// believes is an integral type. -template struct is_integral_or_enum { - enum { - value = (sizeof(char) != sizeof(dont_use::check_nontype_temp_param(0)) && - sizeof(char) == sizeof(dont_use::check_nullptr_t_like(0))) - }; -}; +/// \brief Metafunction to remove reference from a type. +template struct remove_reference { typedef T type; }; +template struct remove_reference { typedef T type; }; /// \brief Metafunction that determines whether the given type is a pointer /// type. template struct is_pointer : false_type {}; template struct is_pointer : true_type {}; +template struct is_pointer : true_type {}; +template struct is_pointer : true_type {}; +template struct is_pointer : true_type {}; + +/// \brief Metafunction that determines whether the given type is either an +/// integral type or an enumeration type. +/// +/// Note that this accepts potentially more integral types than we whitelist +/// above for is_integral because it is based on merely being convertible +/// implicitly to an integral type. +template class is_integral_or_enum { + // Provide an overload which can be called with anything implicitly + // convertible to an unsigned long long. This should catch integer types and + // enumeration types at least. We blacklist classes with conversion operators + // below. + static double check_int_convertible(unsigned long long); + static char check_int_convertible(...); + + typedef typename remove_reference::type UnderlyingT; + static UnderlyingT &nonce_instance; + +public: + enum { + value = (!is_class::value && !is_pointer::value && + !is_same::value && + !is_same::value && + sizeof(char) != sizeof(check_int_convertible(nonce_instance))) + }; +}; // enable_if_c - Enable/disable a template based on a metafunction template