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 2418883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#ifndef __has_feature 2518883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#define LLVM_DEFINED_HAS_FEATURE 2618883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#define __has_feature(x) 0 2718883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#endif 2818883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer 295c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// This is actually the conforming implementation which works with abstract 305c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// classes. However, enough compilers have trouble with it that most will use 315c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// the one in boost/type_traits/object_traits.hpp. This implementation actually 325c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner// works with VC7.0, but other interactions seem to fail when we use it. 335c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 345c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnernamespace llvm { 354bbf4ee1491637c247e195e19e3e4a8ee5ad72faChris Lattner 365c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnernamespace dont_use 375c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner{ 385c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // These two functions should never be used. They are helpers to 3963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman // the is_class template below. They cannot be located inside 405c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // is_class because doing so causes at least GCC to think that 415c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // the value of the "value" enumerator is not constant. Placing 4263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman // them out here (for some strange reason) allows the sizeof 435c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // operator against them to magically be constant. This is 445c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // important to make the is_class<T>::value idiom zero cost. it 4563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman // evaluates to a constant 1 or 0 depending on whether the 465c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // parameter T is a class or not (respectively). 47a9ad04191cb56c42944b17980b8b2bb2afe11ab2Dan Gohman template<typename T> char is_class_helper(void(T::*)()); 485c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner template<typename T> double is_class_helper(...); 495c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner} 505c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 515c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnertemplate <typename T> 525c4d53a4d1bce60051fd71af1791791acb2000daChris Lattnerstruct is_class 535c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner{ 545c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For 555c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // more details: 565c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 575c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner public: 585c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) }; 595c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner}; 60dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 61dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 62dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner/// isPodLike - This is a type trait that is used to determine whether a given 63dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner/// type can be copied around with memcpy instead of running ctors etc. 64dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnertemplate <typename T> 65dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnerstruct isPodLike { 6618883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#if __has_feature(is_trivially_copyable) 6718883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer // If the compiler supports the is_trivially_copyable trait use it, as it 6818883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer // matches the definition of isPodLike closely. 6918883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer static const bool value = __is_trivially_copyable(T); 7018883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#else 71dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner // If we don't know anything else, we can (at least) assume that all non-class 72dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner // types are PODs. 73dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner static const bool value = !is_class<T>::value; 7418883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#endif 75dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner}; 76dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 77dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner// std::pair's are pod-like if their elements are. 78dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnertemplate<typename T, typename U> 79dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattnerstruct isPodLike<std::pair<T, U> > { 804e58263459d7f9ae862b52adafe585b66411272fBenjamin Kramer static const bool value = isPodLike<T>::value && isPodLike<U>::value; 81dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner}; 82dc2e570411bb1b1345a6b9840050aca823835a81Chris Lattner 835c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 840b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <class T, T v> 850b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthstruct integral_constant { 860b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth typedef T value_type; 870b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth static const value_type value = v; 880b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth typedef integral_constant<T,v> type; 890b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth operator value_type() { return value; } 900b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth}; 910b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 920b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtypedef integral_constant<bool, true> true_type; 930b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtypedef integral_constant<bool, false> false_type; 940b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 95404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor/// \brief Metafunction that determines whether the two given types are 96404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor/// equivalent. 970b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate<typename T, typename U> struct is_same : public false_type {}; 980b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate<typename T> struct is_same<T, T> : public true_type {}; 990b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 1000b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that removes const qualification from a type. 1010b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_const { typedef T type; }; 1020b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_const<const T> { typedef T type; }; 103404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor 1040b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that removes volatile qualification from a type. 1050b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_volatile { typedef T type; }; 1060b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_volatile<volatile T> { typedef T type; }; 1070b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 1080b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that removes both const and volatile qualification from 1090b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// a type. 1100b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct remove_cv { 1110b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth typedef typename remove_const<typename remove_volatile<T>::type>::type type; 112404aa26b26eb62c57daac8246159220eb173ae94Douglas Gregor}; 1130b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 1140b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Helper to implement is_integral metafunction. 1150b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> struct is_integral_impl : false_type {}; 1160b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< bool> : true_type {}; 1170b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< char> : true_type {}; 1180b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< signed char> : true_type {}; 1190b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned char> : true_type {}; 1200b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< wchar_t> : true_type {}; 1210b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< short> : true_type {}; 1220b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned short> : true_type {}; 1230b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< int> : true_type {}; 1240b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned int> : true_type {}; 1250b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< long> : true_type {}; 1260b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned long> : true_type {}; 1270b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl< long long> : true_type {}; 1280b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <> struct is_integral_impl<unsigned long long> : true_type {}; 1290b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 1300b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// \brief Metafunction that determines whether the given type is an integral 1310b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth/// type. 1320b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthtemplate <typename T> 1330b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruthstruct is_integral : is_integral_impl<T> {}; 1340b66c6fca22e85f732cf58f459a06c06833d1882Chandler Carruth 135cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// \brief Metafunction to remove reference from a type. 136cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct remove_reference { typedef T type; }; 137cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct remove_reference<T&> { typedef T type; }; 138cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth 139cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// \brief Metafunction that determines whether the given type is a pointer 140cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// type. 141cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer : false_type {}; 142cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T*> : true_type {}; 143cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T* const> : true_type {}; 144cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T* volatile> : true_type {}; 145cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> struct is_pointer<T* const volatile> : true_type {}; 146d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth 147ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// \brief Metafunction that determines whether the given type is either an 148ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// integral type or an enumeration type. 149ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// 150ff12877a6f4db734cf0a156dc2ef815a839a79ecChandler Carruth/// Note that this accepts potentially more integral types than we whitelist 151cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// above for is_integral because it is based on merely being convertible 152cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth/// implicitly to an integral type. 153cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthtemplate <typename T> class is_integral_or_enum { 154cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // Provide an overload which can be called with anything implicitly 155cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // convertible to an unsigned long long. This should catch integer types and 156cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // enumeration types at least. We blacklist classes with conversion operators 157cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth // below. 158cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth static double check_int_convertible(unsigned long long); 159cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth static char check_int_convertible(...); 160cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth 161cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth typedef typename remove_reference<T>::type UnderlyingT; 162cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth static UnderlyingT &nonce_instance; 163cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth 164cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruthpublic: 165d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth enum { 166cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value && 167cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth !is_same<UnderlyingT, float>::value && 168cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth !is_same<UnderlyingT, double>::value && 169cbfc117674be7ff70b4682c525d6fcb4827a74edChandler Carruth sizeof(char) != sizeof(check_int_convertible(nonce_instance))) 170d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth }; 171d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth}; 172d4d8b2a7f6d29b44cbc084b49042f44ef109da0cChandler Carruth 173c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor// enable_if_c - Enable/disable a template based on a metafunction 174c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<bool Cond, typename T = void> 175c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregorstruct enable_if_c { 176c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor typedef T type; 177c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor}; 178c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 179c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<typename T> struct enable_if_c<false, T> { }; 180c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 181c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor// enable_if - Enable/disable a template based on a metafunction 182c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<typename Cond, typename T = void> 183c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregorstruct enable_if : public enable_if_c<Cond::value, T> { }; 184c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 185c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregornamespace dont_use { 186c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor template<typename Base> char base_of_helper(const volatile Base*); 187c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor template<typename Base> double base_of_helper(...); 188c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor} 189c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 190c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor/// is_base_of - Metafunction to determine whether one type is a base class of 191c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor/// (or identical to) another type. 192c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregortemplate<typename Base, typename Derived> 193c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregorstruct is_base_of { 194c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor static const bool value 195c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor = is_class<Base>::value && is_class<Derived>::value && 196c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0)); 197c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor}; 198c7a6da6e1469100937851cc3741a36b5850e54daDouglas Gregor 19971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// remove_pointer - Metafunction to turn Foo* into Foo. Defined in 20071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// C++0x [meta.trans.ptr]. 20171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer { typedef T type; }; 20271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*> { typedef T type; }; 20371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*const> { typedef T type; }; 20471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*volatile> { typedef T type; }; 20571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate <typename T> struct remove_pointer<T*const volatile> { 20671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin typedef T type; }; 20771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 20881cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskintemplate <bool, typename T, typename F> 20981cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskinstruct conditional { typedef T type; }; 21081cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin 21181cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskintemplate <typename T, typename F> 21281cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskinstruct conditional<false, T, F> { typedef F type; }; 21381cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin 2145c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner} 2155c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner 21618883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#ifdef LLVM_DEFINED_HAS_FEATURE 21718883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#undef __has_feature 21818883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer#endif 21918883037a98240a7831c0d7c01dbe502fc5cfbd9Benjamin Kramer 2205c4d53a4d1bce60051fd71af1791791acb2000daChris Lattner#endif 221