diff options
-rw-r--r-- | include/llvm/Support/type_traits.h | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 241883a02c..0cb8e9789d 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -121,46 +121,44 @@ template <> struct is_integral_impl<unsigned long long> : true_type {}; template <typename T> struct is_integral : is_integral_impl<T> {}; -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 <typename U, U u = U()> struct check_nontype_temp_param_return_type { - char c[2]; - }; - template <typename U> - check_nontype_temp_param_return_type<U> check_nontype_temp_param(U*); - template <typename U> 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 <typename U, nonce* u = U()> - struct check_nullptr_t_like_return_type { char c[2]; }; - template <typename U> - check_nullptr_t_like_return_type<U> check_nullptr_t_like(U*); - template <typename U> char check_nullptr_t_like(...); -} // namespace dont_use +/// \brief Metafunction to remove reference from a type. +template <typename T> struct remove_reference { typedef T type; }; +template <typename T> struct remove_reference<T&> { typedef T type; }; + +/// \brief Metafunction that determines whether the given type is a pointer +/// type. +template <typename T> struct is_pointer : false_type {}; +template <typename T> struct is_pointer<T*> : true_type {}; +template <typename T> struct is_pointer<T* const> : true_type {}; +template <typename T> struct is_pointer<T* volatile> : true_type {}; +template <typename T> struct is_pointer<T* const volatile> : 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, it should accept essentially anything the compiler -/// believes is an integral type. -template <typename T> struct is_integral_or_enum { +/// above for is_integral because it is based on merely being convertible +/// implicitly to an integral type. +template <typename T> 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<T>::type UnderlyingT; + static UnderlyingT &nonce_instance; + +public: enum { - value = (sizeof(char) != sizeof(dont_use::check_nontype_temp_param<T>(0)) && - sizeof(char) == sizeof(dont_use::check_nullptr_t_like<T>(0))) + value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value && + !is_same<UnderlyingT, float>::value && + !is_same<UnderlyingT, double>::value && + sizeof(char) != sizeof(check_int_convertible(nonce_instance))) }; }; -/// \brief Metafunction that determines whether the given type is a pointer -/// type. -template <typename T> struct is_pointer : false_type {}; -template <typename T> struct is_pointer<T*> : true_type {}; - // enable_if_c - Enable/disable a template based on a metafunction template<bool Cond, typename T = void> struct enable_if_c { |