type_traits.h revision 4e58263459d7f9ae862b52adafe585b66411272f
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===// 263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// 35c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// The LLVM Compiler Infrastructure 45c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// 85c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner//===----------------------------------------------------------------------===// 95c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// 105c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// This file provides a template class that determines if a type is a class or 115c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// not. The basic mechanism, based on using the pointer to member function of 1263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// a zero argument to a function was "boosted" from the boost type_traits 1363b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// library. See http://www.boost.org/ for all the gory details. 145c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// 155c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner//===----------------------------------------------------------------------===// 165c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 175c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner#ifndef LLVM_SUPPORT_TYPE_TRAITS_H 185c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner#define LLVM_SUPPORT_TYPE_TRAITS_H 195c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 200b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth#include "llvm/Support/DataTypes.h" 2188c48fae6956f17273704da53a2b3ab2981529c1Chandler Carruth#include <cstddef> 224bbf4ee1491637c247e195e19e3e4a8ee5ad72faChris Lattner#include <utility> 234bbf4ee1491637c247e195e19e3e4a8ee5ad72faChris Lattner 245c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// This is actually the conforming implementation which works with abstract 255c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// classes. However, enough compilers have trouble with it that most will use 265c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// the one in boost/type_traits/object_traits.hpp. This implementation actually 275c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// works with VC7.0, but other interactions seem to fail when we use it. 285c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 295c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnernamespace llvm { 304bbf4ee1491637c247e195e19e3e4a8ee5ad72faChris Lattner 315c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnernamespace dont_use 325c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner{ 335c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // These two functions should never be used. They are helpers to 3463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman // the is_class template below. They cannot be located inside 355c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // is_class because doing so causes at least GCC to think that 365c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // the value of the "value" enumerator is not constant. Placing 3763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman // them out here (for some strange reason) allows the sizeof 385c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // operator against them to magically be constant. This is 395c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // important to make the is_class<T>::value idiom zero cost. it 4063b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman // evaluates to a constant 1 or 0 depending on whether the 415c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // parameter T is a class or not (respectively). 42a9ad04191cb56c42944b17980b8b2bb2afe11ab2Dan Gohman template<typename T> char is_class_helper(void(T::*)()); 435c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner template<typename T> double is_class_helper(...); 445c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner} 455c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 465c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnertemplate <typename T> 475c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnerstruct is_class 485c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner{ 495c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For 505c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // more details: 515c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 525c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner public: 535c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) }; 545c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner}; 55dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 56dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 57dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner/// isPodLike - This is a type trait that is used to determine whether a given 58dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner/// type can be copied around with memcpy instead of running ctors etc. 59dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnertemplate <typename T> 60dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnerstruct isPodLike { 61dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner // If we don't know anything else, we can (at least) assume that all non-class 62dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner // types are PODs. 63dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner static const bool value = !is_class<T>::value; 64dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner}; 65dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 66dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner// std::pair's are pod-like if their elements are. 67dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnertemplate<typename T, typename U> 68dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnerstruct isPodLike<std::pair<T, U> > { 694e58263459d7f9ae862b52adafe585b66411272fBenjamin Kramer static const bool value = isPodLike<T>::value && isPodLike<U>::value; 70dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner}; 71dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 725c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 730b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <class T, T v> 740b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthstruct integral_constant { 750b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth typedef T value_type; 760b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth static const value_type value = v; 770b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth typedef integral_constant<T,v> type; 780b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth operator value_type() { return value; } 790b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth}; 800b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 810b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtypedef integral_constant<bool, true> true_type; 820b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtypedef integral_constant<bool, false> false_type; 830b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 84404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor/// \brief Metafunction that determines whether the two given types are 85404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor/// equivalent. 860b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate<typename T, typename U> struct is_same : public false_type {}; 870b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate<typename T> struct is_same<T, T> : public true_type {}; 880b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 890b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that removes const qualification from a type. 900b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_const { typedef T type; }; 910b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_const<const T> { typedef T type; }; 92404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor 930b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that removes volatile qualification from a type. 940b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_volatile { typedef T type; }; 950b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_volatile<volatile T> { typedef T type; }; 960b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 970b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that removes both const and volatile qualification from 980b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// a type. 990b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_cv { 1000b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth typedef typename remove_const<typename remove_volatile<T>::type>::type type; 101404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor}; 1020b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 1030b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Helper to implement is_integral metafunction. 1040b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct is_integral_impl : false_type {}; 1050b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< bool> : true_type {}; 1060b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< char> : true_type {}; 1070b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< signed char> : true_type {}; 1080b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned char> : true_type {}; 1090b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< wchar_t> : true_type {}; 1100b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< short> : true_type {}; 1110b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned short> : true_type {}; 1120b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< int> : true_type {}; 1130b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned int> : true_type {}; 1140b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< long> : true_type {}; 1150b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned long> : true_type {}; 1160b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< long long> : true_type {}; 1170b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned long long> : true_type {}; 1180b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 1190b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that determines whether the given type is an integral 1200b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// type. 1210b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> 1220b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthstruct is_integral : is_integral_impl<T> {}; 1230b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 124cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// \brief Metafunction to remove reference from a type. 125cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct remove_reference { typedef T type; }; 126cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct remove_reference<T&> { typedef T type; }; 127cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth 128cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// \brief Metafunction that determines whether the given type is a pointer 129cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// type. 130cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer : false_type {}; 131cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T*> : true_type {}; 132cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T* const> : true_type {}; 133cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T* volatile> : true_type {}; 134cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T* const volatile> : true_type {}; 135d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth 136ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// \brief Metafunction that determines whether the given type is either an 137ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// integral type or an enumeration type. 138ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// 139ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// Note that this accepts potentially more integral types than we whitelist 140cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// above for is_integral because it is based on merely being convertible 141cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// implicitly to an integral type. 142cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> class is_integral_or_enum { 143cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // Provide an overload which can be called with anything implicitly 144cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // convertible to an unsigned long long. This should catch integer types and 145cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // enumeration types at least. We blacklist classes with conversion operators 146cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // below. 147cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth static double check_int_convertible(unsigned long long); 148cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth static char check_int_convertible(...); 149cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth 150cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth typedef typename remove_reference<T>::type UnderlyingT; 151cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth static UnderlyingT &nonce_instance; 152cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth 153cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthpublic: 154d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth enum { 155cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value && 156cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth !is_same<UnderlyingT, float>::value && 157cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth !is_same<UnderlyingT, double>::value && 158cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth sizeof(char) != sizeof(check_int_convertible(nonce_instance))) 159d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth }; 160d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth}; 161d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth 162c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor// enable_if_c - Enable/disable a template based on a metafunction 163c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<bool Cond, typename T = void> 164c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregorstruct enable_if_c { 165c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor typedef T type; 166c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor}; 167c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 168c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<typename T> struct enable_if_c<false, T> { }; 169c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 170c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor// enable_if - Enable/disable a template based on a metafunction 171c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<typename Cond, typename T = void> 172c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregorstruct enable_if : public enable_if_c<Cond::value, T> { }; 173c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 174c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregornamespace dont_use { 175c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor template<typename Base> char base_of_helper(const volatile Base*); 176c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor template<typename Base> double base_of_helper(...); 177c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor} 178c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 179c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor/// is_base_of - Metafunction to determine whether one type is a base class of 180c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor/// (or identical to) another type. 181c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<typename Base, typename Derived> 182c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregorstruct is_base_of { 183c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor static const bool value 184c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor = is_class<Base>::value && is_class<Derived>::value && 185c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0)); 186c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor}; 187c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 18871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// remove_pointer - Metafunction to turn Foo* into Foo. Defined in 18971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// C++0x [meta.trans.ptr]. 19071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer { typedef T type; }; 19171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*> { typedef T type; }; 19271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*const> { typedef T type; }; 19371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*volatile> { typedef T type; }; 19471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*const volatile> { 19571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin typedef T type; }; 19671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 19781cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskintemplate <bool, typename T, typename F> 19881cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskinstruct conditional { typedef T type; }; 19981cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin 20081cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskintemplate <typename T, typename F> 20181cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskinstruct conditional<false, T, F> { typedef F type; }; 20281cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin 2035c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner} 2045c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 2055c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner#endif 206