]> git.saurik.com Git - apple/objc4.git/blob - runtime/llvm-type_traits.h
objc4-709.tar.gz
[apple/objc4.git] / runtime / llvm-type_traits.h
1 //===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides a template class that determines if a type is a class or
11 // not. The basic mechanism, based on using the pointer to member function of
12 // a zero argument to a function was "boosted" from the boost type_traits
13 // library. See http://www.boost.org/ for all the gory details.
14 //
15 //===----------------------------------------------------------------------===//
16
17 // Taken from llvmCore-3425.0.31.
18
19 #ifndef LLVM_SUPPORT_TYPE_TRAITS_H
20 #define LLVM_SUPPORT_TYPE_TRAITS_H
21
22 #include <cstddef>
23 #include <utility>
24
25 #ifndef __has_feature
26 #define LLVM_DEFINED_HAS_FEATURE
27 #define __has_feature(x) 0
28 #endif
29
30 // This is actually the conforming implementation which works with abstract
31 // classes. However, enough compilers have trouble with it that most will use
32 // the one in boost/type_traits/object_traits.hpp. This implementation actually
33 // works with VC7.0, but other interactions seem to fail when we use it.
34
35 namespace objc {
36
37 namespace dont_use
38 {
39 // These two functions should never be used. They are helpers to
40 // the is_class template below. They cannot be located inside
41 // is_class because doing so causes at least GCC to think that
42 // the value of the "value" enumerator is not constant. Placing
43 // them out here (for some strange reason) allows the sizeof
44 // operator against them to magically be constant. This is
45 // important to make the is_class<T>::value idiom zero cost. it
46 // evaluates to a constant 1 or 0 depending on whether the
47 // parameter T is a class or not (respectively).
48 template<typename T> char is_class_helper(void(T::*)());
49 template<typename T> double is_class_helper(...);
50 }
51
52 template <typename T>
53 struct is_class
54 {
55 // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
56 // more details:
57 // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
58 public:
59 static const bool value =
60 sizeof(char) == sizeof(dont_use::is_class_helper<T>(0));
61 };
62
63
64 /// isPodLike - This is a type trait that is used to determine whether a given
65 /// type can be copied around with memcpy instead of running ctors etc.
66 template <typename T>
67 struct isPodLike {
68 #if __has_feature(is_trivially_copyable)
69 // If the compiler supports the is_trivially_copyable trait use it, as it
70 // matches the definition of isPodLike closely.
71 static const bool value = __is_trivially_copyable(T);
72 #else
73 // If we don't know anything else, we can (at least) assume that all non-class
74 // types are PODs.
75 static const bool value = !is_class<T>::value;
76 #endif
77 };
78
79 // std::pair's are pod-like if their elements are.
80 template<typename T, typename U>
81 struct isPodLike<std::pair<T, U> > {
82 static const bool value = isPodLike<T>::value && isPodLike<U>::value;
83 };
84
85
86 template <class T, T v>
87 struct integral_constant {
88 typedef T value_type;
89 static const value_type value = v;
90 typedef integral_constant<T,v> type;
91 operator value_type() { return value; }
92 };
93
94 typedef integral_constant<bool, true> true_type;
95 typedef integral_constant<bool, false> false_type;
96
97 /// \brief Metafunction that determines whether the two given types are
98 /// equivalent.
99 template<typename T, typename U> struct is_same : public false_type {};
100 template<typename T> struct is_same<T, T> : public true_type {};
101
102 /// \brief Metafunction that removes const qualification from a type.
103 template <typename T> struct remove_const { typedef T type; };
104 template <typename T> struct remove_const<const T> { typedef T type; };
105
106 /// \brief Metafunction that removes volatile qualification from a type.
107 template <typename T> struct remove_volatile { typedef T type; };
108 template <typename T> struct remove_volatile<volatile T> { typedef T type; };
109
110 /// \brief Metafunction that removes both const and volatile qualification from
111 /// a type.
112 template <typename T> struct remove_cv {
113 typedef typename remove_const<typename remove_volatile<T>::type>::type type;
114 };
115
116 /// \brief Helper to implement is_integral metafunction.
117 template <typename T> struct is_integral_impl : false_type {};
118 template <> struct is_integral_impl< bool> : true_type {};
119 template <> struct is_integral_impl< char> : true_type {};
120 template <> struct is_integral_impl< signed char> : true_type {};
121 template <> struct is_integral_impl<unsigned char> : true_type {};
122 template <> struct is_integral_impl< wchar_t> : true_type {};
123 template <> struct is_integral_impl< short> : true_type {};
124 template <> struct is_integral_impl<unsigned short> : true_type {};
125 template <> struct is_integral_impl< int> : true_type {};
126 template <> struct is_integral_impl<unsigned int> : true_type {};
127 template <> struct is_integral_impl< long> : true_type {};
128 template <> struct is_integral_impl<unsigned long> : true_type {};
129 template <> struct is_integral_impl< long long> : true_type {};
130 template <> struct is_integral_impl<unsigned long long> : true_type {};
131
132 /// \brief Metafunction that determines whether the given type is an integral
133 /// type.
134 template <typename T>
135 struct is_integral : is_integral_impl<T> {};
136
137 /// \brief Metafunction to remove reference from a type.
138 template <typename T> struct remove_reference { typedef T type; };
139 template <typename T> struct remove_reference<T&> { typedef T type; };
140
141 /// \brief Metafunction that determines whether the given type is a pointer
142 /// type.
143 template <typename T> struct is_pointer : false_type {};
144 template <typename T> struct is_pointer<T*> : true_type {};
145 template <typename T> struct is_pointer<T* const> : true_type {};
146 template <typename T> struct is_pointer<T* volatile> : true_type {};
147 template <typename T> struct is_pointer<T* const volatile> : true_type {};
148
149 /// \brief Metafunction that determines whether the given type is either an
150 /// integral type or an enumeration type.
151 ///
152 /// Note that this accepts potentially more integral types than we whitelist
153 /// above for is_integral because it is based on merely being convertible
154 /// implicitly to an integral type.
155 template <typename T> class is_integral_or_enum {
156 // Provide an overload which can be called with anything implicitly
157 // convertible to an unsigned long long. This should catch integer types and
158 // enumeration types at least. We blacklist classes with conversion operators
159 // below.
160 static double check_int_convertible(unsigned long long);
161 static char check_int_convertible(...);
162
163 typedef typename remove_reference<T>::type UnderlyingT;
164 static UnderlyingT &nonce_instance;
165
166 public:
167 static const bool
168 value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
169 !is_same<UnderlyingT, float>::value &&
170 !is_same<UnderlyingT, double>::value &&
171 sizeof(char) != sizeof(check_int_convertible(nonce_instance)));
172 };
173
174 // enable_if_c - Enable/disable a template based on a metafunction
175 template<bool Cond, typename T = void>
176 struct enable_if_c {
177 typedef T type;
178 };
179
180 template<typename T> struct enable_if_c<false, T> { };
181
182 // enable_if - Enable/disable a template based on a metafunction
183 template<typename Cond, typename T = void>
184 struct enable_if : public enable_if_c<Cond::value, T> { };
185
186 namespace dont_use {
187 template<typename Base> char base_of_helper(const volatile Base*);
188 template<typename Base> double base_of_helper(...);
189 }
190
191 /// is_base_of - Metafunction to determine whether one type is a base class of
192 /// (or identical to) another type.
193 template<typename Base, typename Derived>
194 struct is_base_of {
195 static const bool value
196 = is_class<Base>::value && is_class<Derived>::value &&
197 sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0));
198 };
199
200 // remove_pointer - Metafunction to turn Foo* into Foo. Defined in
201 // C++0x [meta.trans.ptr].
202 template <typename T> struct remove_pointer { typedef T type; };
203 template <typename T> struct remove_pointer<T*> { typedef T type; };
204 template <typename T> struct remove_pointer<T*const> { typedef T type; };
205 template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
206 template <typename T> struct remove_pointer<T*const volatile> {
207 typedef T type; };
208
209 template <bool, typename T, typename F>
210 struct conditional { typedef T type; };
211
212 template <typename T, typename F>
213 struct conditional<false, T, F> { typedef F type; };
214
215 }
216
217 #ifdef LLVM_DEFINED_HAS_FEATURE
218 #undef __has_feature
219 #endif
220
221 #endif