Add support to the hashing infrastructure for automatically hashing both
[oota-llvm.git] / include / llvm / Support / type_traits.h
index f488a29c7af4d7dee690d0efff8460574c0128db..a76344c098fe179fde5353f1aa03d0b44c7c7c95 100644 (file)
@@ -18,6 +18,7 @@
 #define LLVM_SUPPORT_TYPE_TRAITS_H
 
 #include "llvm/Support/DataTypes.h"
+#include <cstddef>
 #include <utility>
 
 // This is actually the conforming implementation which works with abstract
@@ -120,30 +121,42 @@ template <> struct is_integral_impl<unsigned long long> : true_type {};
 template <typename T>
 struct is_integral : is_integral_impl<T> {};
 
-/// \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 {};
+/// \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> class is_integral_or_enum {
+
+  // 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 check1_return_type { char c[2]; };
+  template <typename U> static check1_return_type<U> checker1(U*);
+  static char checker1(...);
+
+  // 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 check2_return_type { char c[2]; };
+  template <typename U> static check2_return_type<U> checker2(U*);
+  static char checker2(...);
 
-/// \brief Metafunction to compute whether a type requires alignment padding.
-/// When true, an object of this type will have padding bytes inside its
-/// 'sizeof' bytes.
-template <typename T> class is_alignment_padded {
-  struct pod_size_tester { T t; char c; };
 public:
-  enum { value = offsetof(pod_size_tester, c) != sizeof(T) };
+  enum {
+    value = (sizeof(char) != sizeof(checker1((T*)0)) &&
+             sizeof(char) == sizeof(checker2((T*)0)))
+  };
 };
 
-/// \brief Metafunction to determine whether an adjacent pair of two types will
-/// require padding between them due to alignment.
-template <typename T, typename U> class is_pod_pair_padded {
-  struct pod_pair { T t; U u; };
-  struct pod_char_pair { T t; char c; };
-public:
-  enum { value = offsetof(pod_pair, u) != offsetof(pod_char_pair, c) };
-};
+/// \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 {