X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2Ftype_traits.h;h=7b97547be52af409574587e6d3c1e9ff321e9c65;hb=cbeb8d9869aafec3c2c1ee0922f0a4d5bb4a916a;hp=03f85e99971a6d09a6d0407043931e0a351b375b;hpb=0b66c6fca22e85f732cf58f459a06c06833d1882;p=oota-llvm.git diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 03f85e99971..7b97547be52 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -18,8 +18,14 @@ #define LLVM_SUPPORT_TYPE_TRAITS_H #include "llvm/Support/DataTypes.h" +#include #include +#ifndef __has_feature +#define LLVM_DEFINED_HAS_FEATURE +#define __has_feature(x) 0 +#endif + // This is actually the conforming implementation which works with abstract // classes. However, enough compilers have trouble with it that most will use // the one in boost/type_traits/object_traits.hpp. This implementation actually @@ -57,15 +63,21 @@ struct is_class /// type can be copied around with memcpy instead of running ctors etc. template struct isPodLike { +#if __has_feature(is_trivially_copyable) + // If the compiler supports the is_trivially_copyable trait use it, as it + // matches the definition of isPodLike closely. + static const bool value = __is_trivially_copyable(T); +#else // If we don't know anything else, we can (at least) assume that all non-class // types are PODs. static const bool value = !is_class::value; +#endif }; // std::pair's are pod-like if their elements are. template struct isPodLike > { - static const bool value = isPodLike::value & isPodLike::value; + static const bool value = isPodLike::value && isPodLike::value; }; @@ -120,12 +132,44 @@ template <> struct is_integral_impl : true_type {}; template struct is_integral : is_integral_impl {}; +/// \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 struct enable_if_c { @@ -169,4 +213,8 @@ struct conditional { typedef F type; }; } +#ifdef LLVM_DEFINED_HAS_FEATURE +#undef __has_feature +#endif + #endif