X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2Ftype_traits.h;h=7b97547be52af409574587e6d3c1e9ff321e9c65;hb=a00b80b04c5edb08639c1c6b32e9231fd8b066f7;hp=1f3f1e4f8936c2449d1743e43f00e6c4fa79f3eb;hpb=4bbf4ee1491637c247e195e19e3e4a8ee5ad72fa;p=oota-llvm.git diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 1f3f1e4f893..7b97547be52 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -17,41 +17,21 @@ #ifndef LLVM_SUPPORT_TYPE_TRAITS_H #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 // works with VC7.0, but other interactions seem to fail when we use it. namespace llvm { - -/// isPodLike - This is a type trait that is used to determine whether a given -/// type can be copied around with memcpy instead of running ctors etc. -template -struct isPodLike { - static const bool value = false; -}; - -// pointers are all pod-like. -template -struct isPodLike { static const bool value = true; }; - -// builtin types are pod-like as well. -// There is probably a much better way to do this. -template <> struct isPodLike { static const bool value = true; }; -template <> struct isPodLike { static const bool value = true; }; -template <> struct isPodLike { static const bool value = true; }; -template <> struct isPodLike { - static const bool value = true; -}; - - -// pairs are pod-like if their elements are. -template -struct isPodLike > { - static const bool value = isPodLike::value & isPodLike::value; -}; namespace dont_use { @@ -77,19 +57,119 @@ struct is_class public: enum { value = sizeof(char) == sizeof(dont_use::is_class_helper(0)) }; }; + + +/// isPodLike - This is a type trait that is used to determine whether a given +/// 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; +}; + + +template +struct integral_constant { + typedef T value_type; + static const value_type value = v; + typedef integral_constant type; + operator value_type() { return value; } +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; /// \brief Metafunction that determines whether the two given types are /// equivalent. -template -struct is_same { - static const bool value = false; +template struct is_same : public false_type {}; +template struct is_same : public true_type {}; + +/// \brief Metafunction that removes const qualification from a type. +template struct remove_const { typedef T type; }; +template struct remove_const { typedef T type; }; + +/// \brief Metafunction that removes volatile qualification from a type. +template struct remove_volatile { typedef T type; }; +template struct remove_volatile { typedef T type; }; + +/// \brief Metafunction that removes both const and volatile qualification from +/// a type. +template struct remove_cv { + typedef typename remove_const::type>::type type; }; -template -struct is_same { - static const bool value = true; +/// \brief Helper to implement is_integral metafunction. +template struct is_integral_impl : false_type {}; +template <> struct is_integral_impl< bool> : true_type {}; +template <> struct is_integral_impl< char> : true_type {}; +template <> struct is_integral_impl< signed char> : true_type {}; +template <> struct is_integral_impl : true_type {}; +template <> struct is_integral_impl< wchar_t> : true_type {}; +template <> struct is_integral_impl< short> : true_type {}; +template <> struct is_integral_impl : true_type {}; +template <> struct is_integral_impl< int> : true_type {}; +template <> struct is_integral_impl : true_type {}; +template <> struct is_integral_impl< long> : true_type {}; +template <> struct is_integral_impl : true_type {}; +template <> struct is_integral_impl< long long> : true_type {}; +template <> struct is_integral_impl : true_type {}; + +/// \brief Metafunction that determines whether the given type is an integral +/// 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 { @@ -133,4 +213,8 @@ struct conditional { typedef F type; }; } +#ifdef LLVM_DEFINED_HAS_FEATURE +#undef __has_feature +#endif + #endif