|
Sierra Toolkit
Version of the Day
|
00001 /* 00002 Copyright (C) 2005,2009-2010 Electronic Arts, Inc. All rights reserved. 00003 00004 Redistribution and use in source and binary forms, with or without 00005 modification, are permitted provided that the following conditions 00006 are met: 00007 00008 1. Redistributions of source code must retain the above copyright 00009 notice, this list of conditions and the following disclaimer. 00010 2. Redistributions in binary form must reproduce the above copyright 00011 notice, this list of conditions and the following disclaimer in the 00012 documentation and/or other materials provided with the distribution. 00013 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of 00014 its contributors may be used to endorse or promote products derived 00015 from this software without specific prior written permission. 00016 00017 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY 00018 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00020 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY 00021 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00022 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00023 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00024 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00030 // EASTL/internal/type_pod.h 00031 // Written and maintained by Paul Pedriana - 2005. 00033 00034 00035 #ifndef EASTL_INTERNAL_TYPE_POD_H 00036 #define EASTL_INTERNAL_TYPE_POD_H 00037 00038 00039 #include <limits.h> 00040 00041 00042 namespace eastl 00043 { 00044 00045 00046 // The following properties or relations are defined here. If the given 00047 // item is missing then it simply hasn't been implemented, at least not yet. 00048 // is_empty 00049 // is_pod 00050 // has_trivial_constructor 00051 // has_trivial_copy 00052 // has_trivial_assign 00053 // has_trivial_destructor 00054 // has_trivial_relocate -- EA extension to the C++ standard proposal. 00055 // has_nothrow_constructor 00056 // has_nothrow_copy 00057 // has_nothrow_assign 00058 // has_virtual_destructor 00059 00060 00061 00062 00064 // is_empty 00065 // 00066 // is_empty<T>::value == true if and only if T is an empty class or struct. 00067 // is_empty may only be applied to complete types. 00068 // 00069 // is_empty cannot be used with union types until is_union can be made to work. 00071 template <typename T> 00072 struct is_empty_helper_t1 : public T { char m[64]; }; 00073 struct is_empty_helper_t2 { char m[64]; }; 00074 00075 // The inheritance in empty_helper_t1 will not work with non-class types 00076 template <typename T, bool is_a_class = false> 00077 struct is_empty_helper : public false_type{}; 00078 00079 template <typename T> 00080 struct is_empty_helper<T, true> : public integral_constant<bool, 00081 sizeof(is_empty_helper_t1<T>) == sizeof(is_empty_helper_t2) 00082 >{}; 00083 00084 template <typename T> 00085 struct is_empty_helper2 00086 { 00087 typedef typename remove_cv<T>::type _T; 00088 typedef is_empty_helper<_T, is_class<_T>::value> type; 00089 }; 00090 00091 template <typename T> 00092 struct is_empty : public is_empty_helper2<T>::type {}; 00093 00094 00096 // is_pod 00097 // 00098 // is_pod<T>::value == true if and only if, for a given type T: 00099 // - is_scalar<T>::value == true, or 00100 // - T is a class or struct that has no user-defined copy 00101 // assignment operator or destructor, and T has no non-static 00102 // data members M for which is_pod<M>::value == false, and no 00103 // members of reference type, or 00104 // - T is a class or struct that has no user-defined copy assignment 00105 // operator or destructor, and T has no non-static data members M for 00106 // which is_pod<M>::value == false, and no members of reference type, or 00107 // - T is the type of an array of objects E for which is_pod<E>::value == true 00108 // 00109 // is_pod may only be applied to complete types. 00110 // 00111 // Without some help from the compiler or user, is_pod will not report 00112 // that a struct or class is a POD, but will correctly report that 00113 // built-in types such as int are PODs. The user can help the compiler 00114 // by using the EASTL_DECLARE_POD macro on a class. 00116 template <typename T> // There's not much we can do here without some compiler extension. 00117 struct is_pod : public integral_constant<bool, is_void<T>::value || is_scalar<T>::value>{}; 00118 00119 template <typename T, size_t N> 00120 struct is_pod<T[N]> : public is_pod<T>{}; 00121 00122 template <typename T> 00123 struct is_POD : public is_pod<T>{}; 00124 00125 #define EASTL_DECLARE_POD(T) namespace eastl{ template <> struct is_pod<T> : public true_type{}; template <> struct is_pod<const T> : public true_type{}; } 00126 00127 00128 00129 00131 // has_trivial_constructor 00132 // 00133 // has_trivial_constructor<T>::value == true if and only if T is a class 00134 // or struct that has a trivial constructor. A constructor is trivial if 00135 // - it is implicitly defined by the compiler, and 00136 // - is_polymorphic<T>::value == false, and 00137 // - T has no virtual base classes, and 00138 // - for every direct base class of T, has_trivial_constructor<B>::value == true, 00139 // where B is the type of the base class, and 00140 // - for every nonstatic data member of T that has class type or array 00141 // of class type, has_trivial_constructor<M>::value == true, 00142 // where M is the type of the data member 00143 // 00144 // has_trivial_constructor may only be applied to complete types. 00145 // 00146 // Without from the compiler or user, has_trivial_constructor will not 00147 // report that a class or struct has a trivial constructor. 00148 // The user can use EASTL_DECLARE_TRIVIAL_CONSTRUCTOR to help the compiler. 00149 // 00150 // A default constructor for a class X is a constructor of class X that 00151 // can be called without an argument. 00153 00154 // With current compilers, this is all we can do. 00155 template <typename T> 00156 struct has_trivial_constructor : public is_pod<T> {}; 00157 00158 #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{}; } 00159 00160 00161 00162 00164 // has_trivial_copy 00165 // 00166 // has_trivial_copy<T>::value == true if and only if T is a class or 00167 // struct that has a trivial copy constructor. A copy constructor is 00168 // trivial if 00169 // - it is implicitly defined by the compiler, and 00170 // - is_polymorphic<T>::value == false, and 00171 // - T has no virtual base classes, and 00172 // - for every direct base class of T, has_trivial_copy<B>::value == true, 00173 // where B is the type of the base class, and 00174 // - for every nonstatic data member of T that has class type or array 00175 // of class type, has_trivial_copy<M>::value == true, where M is the 00176 // type of the data member 00177 // 00178 // has_trivial_copy may only be applied to complete types. 00179 // 00180 // Another way of looking at this is: 00181 // A copy constructor for class X is trivial if it is implicitly 00182 // declared and if all the following are true: 00183 // - Class X has no virtual functions (10.3) and no virtual base classes (10.1). 00184 // - Each direct base class of X has a trivial copy constructor. 00185 // - For all the nonstatic data members of X that are of class type 00186 // (or array thereof), each such class type has a trivial copy constructor; 00187 // otherwise the copy constructor is nontrivial. 00188 // 00189 // Without from the compiler or user, has_trivial_copy will not report 00190 // that a class or struct has a trivial copy constructor. The user can 00191 // use EASTL_DECLARE_TRIVIAL_COPY to help the compiler. 00193 00194 template <typename T> 00195 struct has_trivial_copy : public integral_constant<bool, is_pod<T>::value && !is_volatile<T>::value>{}; 00196 00197 #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{}; } 00198 00199 00201 // has_trivial_assign 00202 // 00203 // has_trivial_assign<T>::value == true if and only if T is a class or 00204 // struct that has a trivial copy assignment operator. A copy assignment 00205 // operator is trivial if: 00206 // - it is implicitly defined by the compiler, and 00207 // - is_polymorphic<T>::value == false, and 00208 // - T has no virtual base classes, and 00209 // - for every direct base class of T, has_trivial_assign<B>::value == true, 00210 // where B is the type of the base class, and 00211 // - for every nonstatic data member of T that has class type or array 00212 // of class type, has_trivial_assign<M>::value == true, where M is 00213 // the type of the data member. 00214 // 00215 // has_trivial_assign may only be applied to complete types. 00216 // 00217 // Without from the compiler or user, has_trivial_assign will not 00218 // report that a class or struct has trivial assignment. The user 00219 // can use EASTL_DECLARE_TRIVIAL_ASSIGN to help the compiler. 00221 00222 template <typename T> 00223 struct has_trivial_assign : public integral_constant<bool, 00224 is_pod<T>::value && !is_const<T>::value && !is_volatile<T>::value 00225 >{}; 00226 00227 #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{}; } 00228 00229 00230 00231 00233 // has_trivial_destructor 00234 // 00235 // has_trivial_destructor<T>::value == true if and only if T is a class 00236 // or struct that has a trivial destructor. A destructor is trivial if 00237 // - it is implicitly defined by the compiler, and 00238 // - for every direct base class of T, has_trivial_destructor<B>::value == true, 00239 // where B is the type of the base class, and 00240 // - for every nonstatic data member of T that has class type or 00241 // array of class type, has_trivial_destructor<M>::value == true, 00242 // where M is the type of the data member 00243 // 00244 // has_trivial_destructor may only be applied to complete types. 00245 // 00246 // Without from the compiler or user, has_trivial_destructor will not 00247 // report that a class or struct has a trivial destructor. 00248 // The user can use EASTL_DECLARE_TRIVIAL_DESTRUCTOR to help the compiler. 00250 00251 // With current compilers, this is all we can do. 00252 template <typename T> 00253 struct has_trivial_destructor : public is_pod<T>{}; 00254 00255 #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{}; } 00256 00257 00259 // has_trivial_relocate 00260 // 00261 // This is an EA extension to the type traits standard. 00262 // 00263 // A trivially relocatable object is one that can be safely memmove'd 00264 // to uninitialized memory. construction, assignment, and destruction 00265 // properties are not addressed by this trait. A type that has the 00266 // is_fundamental trait would always have the has_trivial_relocate trait. 00267 // A type that has the has_trivial_constructor, has_trivial_copy or 00268 // has_trivial_assign traits would usally have the has_trivial_relocate 00269 // trait, but this is not strictly guaranteed. 00270 // 00271 // The user can use EASTL_DECLARE_TRIVIAL_RELOCATE to help the compiler. 00273 00274 // With current compilers, this is all we can do. 00275 template <typename T> 00276 struct has_trivial_relocate : public integral_constant<bool, is_pod<T>::value && !is_volatile<T>::value>{}; 00277 00278 #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{}; } 00279 00280 00281 } // namespace eastl 00282 00283 00284 #endif // Header include guard