LLVM API Documentation
00001 //===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides useful additions to the standard type_traits library. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_SUPPORT_TYPE_TRAITS_H 00015 #define LLVM_SUPPORT_TYPE_TRAITS_H 00016 00017 #include <type_traits> 00018 #include <utility> 00019 00020 #ifndef __has_feature 00021 #define LLVM_DEFINED_HAS_FEATURE 00022 #define __has_feature(x) 0 00023 #endif 00024 00025 namespace llvm { 00026 00027 /// isPodLike - This is a type trait that is used to determine whether a given 00028 /// type can be copied around with memcpy instead of running ctors etc. 00029 template <typename T> 00030 struct isPodLike { 00031 #if __has_feature(is_trivially_copyable) 00032 // If the compiler supports the is_trivially_copyable trait use it, as it 00033 // matches the definition of isPodLike closely. 00034 static const bool value = __is_trivially_copyable(T); 00035 #else 00036 // If we don't know anything else, we can (at least) assume that all non-class 00037 // types are PODs. 00038 static const bool value = !std::is_class<T>::value; 00039 #endif 00040 }; 00041 00042 // std::pair's are pod-like if their elements are. 00043 template<typename T, typename U> 00044 struct isPodLike<std::pair<T, U> > { 00045 static const bool value = isPodLike<T>::value && isPodLike<U>::value; 00046 }; 00047 00048 /// \brief Metafunction that determines whether the given type is either an 00049 /// integral type or an enumeration type. 00050 /// 00051 /// Note that this accepts potentially more integral types than is_integral 00052 /// because it is based on merely being convertible implicitly to an integral 00053 /// type. 00054 template <typename T> class is_integral_or_enum { 00055 typedef typename std::remove_reference<T>::type UnderlyingT; 00056 00057 public: 00058 static const bool value = 00059 !std::is_class<UnderlyingT>::value && // Filter conversion operators. 00060 !std::is_pointer<UnderlyingT>::value && 00061 !std::is_floating_point<UnderlyingT>::value && 00062 std::is_convertible<UnderlyingT, unsigned long long>::value; 00063 }; 00064 00065 /// \brief If T is a pointer, just return it. If it is not, return T&. 00066 template<typename T, typename Enable = void> 00067 struct add_lvalue_reference_if_not_pointer { typedef T &type; }; 00068 00069 template <typename T> 00070 struct add_lvalue_reference_if_not_pointer< 00071 T, typename std::enable_if<std::is_pointer<T>::value>::type> { 00072 typedef T type; 00073 }; 00074 00075 /// \brief If T is a pointer to X, return a pointer to const X. If it is not, 00076 /// return const T. 00077 template<typename T, typename Enable = void> 00078 struct add_const_past_pointer { typedef const T type; }; 00079 00080 template <typename T> 00081 struct add_const_past_pointer< 00082 T, typename std::enable_if<std::is_pointer<T>::value>::type> { 00083 typedef const typename std::remove_pointer<T>::type *type; 00084 }; 00085 00086 } 00087 00088 #ifdef LLVM_DEFINED_HAS_FEATURE 00089 #undef __has_feature 00090 #endif 00091 00092 #endif