Sierra Toolkit  Version of the Day
type_pod_eastl.h
1 /*
2 Copyright (C) 2005,2009-2010 Electronic Arts, Inc. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 
8 1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
14  its contributors may be used to endorse or promote products derived
15  from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
30 // EASTL/internal/type_pod.h
31 // Written and maintained by Paul Pedriana - 2005.
33 
34 
35 #ifndef EASTL_INTERNAL_TYPE_POD_H
36 #define EASTL_INTERNAL_TYPE_POD_H
37 
38 
39 #include <limits.h>
40 
41 
42 namespace eastl
43 {
44 
45 
46  // The following properties or relations are defined here. If the given
47  // item is missing then it simply hasn't been implemented, at least not yet.
48  // is_empty
49  // is_pod
50  // has_trivial_constructor
51  // has_trivial_copy
52  // has_trivial_assign
53  // has_trivial_destructor
54  // has_trivial_relocate -- EA extension to the C++ standard proposal.
55  // has_nothrow_constructor
56  // has_nothrow_copy
57  // has_nothrow_assign
58  // has_virtual_destructor
59 
60 
61 
62 
64  // is_empty
65  //
66  // is_empty<T>::value == true if and only if T is an empty class or struct.
67  // is_empty may only be applied to complete types.
68  //
69  // is_empty cannot be used with union types until is_union can be made to work.
71  template <typename T>
72  struct is_empty_helper_t1 : public T { char m[64]; };
73  struct is_empty_helper_t2 { char m[64]; };
74 
75  // The inheritance in empty_helper_t1 will not work with non-class types
76  template <typename T, bool is_a_class = false>
77  struct is_empty_helper : public false_type{};
78 
79  template <typename T>
80  struct is_empty_helper<T, true> : public integral_constant<bool,
81  sizeof(is_empty_helper_t1<T>) == sizeof(is_empty_helper_t2)
82  >{};
83 
84  template <typename T>
85  struct is_empty_helper2
86  {
87  typedef typename remove_cv<T>::type _T;
88  typedef is_empty_helper<_T, is_class<_T>::value> type;
89  };
90 
91  template <typename T>
92  struct is_empty : public is_empty_helper2<T>::type {};
93 
94 
96  // is_pod
97  //
98  // is_pod<T>::value == true if and only if, for a given type T:
99  // - is_scalar<T>::value == true, or
100  // - T is a class or struct that has no user-defined copy
101  // assignment operator or destructor, and T has no non-static
102  // data members M for which is_pod<M>::value == false, and no
103  // members of reference type, or
104  // - T is a class or struct that has no user-defined copy assignment
105  // operator or destructor, and T has no non-static data members M for
106  // which is_pod<M>::value == false, and no members of reference type, or
107  // - T is the type of an array of objects E for which is_pod<E>::value == true
108  //
109  // is_pod may only be applied to complete types.
110  //
111  // Without some help from the compiler or user, is_pod will not report
112  // that a struct or class is a POD, but will correctly report that
113  // built-in types such as int are PODs. The user can help the compiler
114  // by using the EASTL_DECLARE_POD macro on a class.
116  template <typename T> // There's not much we can do here without some compiler extension.
117  struct is_pod : public integral_constant<bool, is_void<T>::value || is_scalar<T>::value>{};
118 
119  template <typename T, size_t N>
120  struct is_pod<T[N]> : public is_pod<T>{};
121 
122  template <typename T>
123  struct is_POD : public is_pod<T>{};
124 
125  #define EASTL_DECLARE_POD(T) namespace eastl{ template <> struct is_pod<T> : public true_type{}; template <> struct is_pod<const T> : public true_type{}; }
126 
127 
128 
129 
131  // has_trivial_constructor
132  //
133  // has_trivial_constructor<T>::value == true if and only if T is a class
134  // or struct that has a trivial constructor. A constructor is trivial if
135  // - it is implicitly defined by the compiler, and
136  // - is_polymorphic<T>::value == false, and
137  // - T has no virtual base classes, and
138  // - for every direct base class of T, has_trivial_constructor<B>::value == true,
139  // where B is the type of the base class, and
140  // - for every nonstatic data member of T that has class type or array
141  // of class type, has_trivial_constructor<M>::value == true,
142  // where M is the type of the data member
143  //
144  // has_trivial_constructor may only be applied to complete types.
145  //
146  // Without from the compiler or user, has_trivial_constructor will not
147  // report that a class or struct has a trivial constructor.
148  // The user can use EASTL_DECLARE_TRIVIAL_CONSTRUCTOR to help the compiler.
149  //
150  // A default constructor for a class X is a constructor of class X that
151  // can be called without an argument.
153 
154  // With current compilers, this is all we can do.
155  template <typename T>
156  struct has_trivial_constructor : public is_pod<T> {};
157 
158  #define EASTL_DECLARE_TRIVIAL_CONSTRUCTOR(T) namespace eastl{ template <> struct has_trivial_constructor<T> : public true_type{}; template <> struct has_trivial_constructor<const T> : public true_type{}; }
159 
160 
161 
162 
164  // has_trivial_copy
165  //
166  // has_trivial_copy<T>::value == true if and only if T is a class or
167  // struct that has a trivial copy constructor. A copy constructor is
168  // trivial if
169  // - it is implicitly defined by the compiler, and
170  // - is_polymorphic<T>::value == false, and
171  // - T has no virtual base classes, and
172  // - for every direct base class of T, has_trivial_copy<B>::value == true,
173  // where B is the type of the base class, and
174  // - for every nonstatic data member of T that has class type or array
175  // of class type, has_trivial_copy<M>::value == true, where M is the
176  // type of the data member
177  //
178  // has_trivial_copy may only be applied to complete types.
179  //
180  // Another way of looking at this is:
181  // A copy constructor for class X is trivial if it is implicitly
182  // declared and if all the following are true:
183  // - Class X has no virtual functions (10.3) and no virtual base classes (10.1).
184  // - Each direct base class of X has a trivial copy constructor.
185  // - For all the nonstatic data members of X that are of class type
186  // (or array thereof), each such class type has a trivial copy constructor;
187  // otherwise the copy constructor is nontrivial.
188  //
189  // Without from the compiler or user, has_trivial_copy will not report
190  // that a class or struct has a trivial copy constructor. The user can
191  // use EASTL_DECLARE_TRIVIAL_COPY to help the compiler.
193 
194  template <typename T>
195  struct has_trivial_copy : public integral_constant<bool, is_pod<T>::value && !is_volatile<T>::value>{};
196 
197  #define EASTL_DECLARE_TRIVIAL_COPY(T) namespace eastl{ template <> struct has_trivial_copy<T> : public true_type{}; template <> struct has_trivial_copy<const T> : public true_type{}; }
198 
199 
201  // has_trivial_assign
202  //
203  // has_trivial_assign<T>::value == true if and only if T is a class or
204  // struct that has a trivial copy assignment operator. A copy assignment
205  // operator is trivial if:
206  // - it is implicitly defined by the compiler, and
207  // - is_polymorphic<T>::value == false, and
208  // - T has no virtual base classes, and
209  // - for every direct base class of T, has_trivial_assign<B>::value == true,
210  // where B is the type of the base class, and
211  // - for every nonstatic data member of T that has class type or array
212  // of class type, has_trivial_assign<M>::value == true, where M is
213  // the type of the data member.
214  //
215  // has_trivial_assign may only be applied to complete types.
216  //
217  // Without from the compiler or user, has_trivial_assign will not
218  // report that a class or struct has trivial assignment. The user
219  // can use EASTL_DECLARE_TRIVIAL_ASSIGN to help the compiler.
221 
222  template <typename T>
223  struct has_trivial_assign : public integral_constant<bool,
224  is_pod<T>::value && !is_const<T>::value && !is_volatile<T>::value
225  >{};
226 
227  #define EASTL_DECLARE_TRIVIAL_ASSIGN(T) namespace eastl{ template <> struct has_trivial_assign<T> : public true_type{}; template <> struct has_trivial_assign<const T> : public true_type{}; }
228 
229 
230 
231 
233  // has_trivial_destructor
234  //
235  // has_trivial_destructor<T>::value == true if and only if T is a class
236  // or struct that has a trivial destructor. A destructor is trivial if
237  // - it is implicitly defined by the compiler, and
238  // - for every direct base class of T, has_trivial_destructor<B>::value == true,
239  // where B is the type of the base class, and
240  // - for every nonstatic data member of T that has class type or
241  // array of class type, has_trivial_destructor<M>::value == true,
242  // where M is the type of the data member
243  //
244  // has_trivial_destructor may only be applied to complete types.
245  //
246  // Without from the compiler or user, has_trivial_destructor will not
247  // report that a class or struct has a trivial destructor.
248  // The user can use EASTL_DECLARE_TRIVIAL_DESTRUCTOR to help the compiler.
250 
251  // With current compilers, this is all we can do.
252  template <typename T>
253  struct has_trivial_destructor : public is_pod<T>{};
254 
255  #define EASTL_DECLARE_TRIVIAL_DESTRUCTOR(T) namespace eastl{ template <> struct has_trivial_destructor<T> : public true_type{}; template <> struct has_trivial_destructor<const T> : public true_type{}; }
256 
257 
259  // has_trivial_relocate
260  //
261  // This is an EA extension to the type traits standard.
262  //
263  // A trivially relocatable object is one that can be safely memmove'd
264  // to uninitialized memory. construction, assignment, and destruction
265  // properties are not addressed by this trait. A type that has the
266  // is_fundamental trait would always have the has_trivial_relocate trait.
267  // A type that has the has_trivial_constructor, has_trivial_copy or
268  // has_trivial_assign traits would usally have the has_trivial_relocate
269  // trait, but this is not strictly guaranteed.
270  //
271  // The user can use EASTL_DECLARE_TRIVIAL_RELOCATE to help the compiler.
273 
274  // With current compilers, this is all we can do.
275  template <typename T>
276  struct has_trivial_relocate : public integral_constant<bool, is_pod<T>::value && !is_volatile<T>::value>{};
277 
278  #define EASTL_DECLARE_TRIVIAL_RELOCATE(T) namespace eastl{ template <> struct has_trivial_relocate<T> : public true_type{}; template <> struct has_trivial_relocate<const T> : public true_type{}; }
279 
280 
281 } // namespace eastl
282 
283 
284 #endif // Header include guard
EA Standard Template Library.