Sierra Toolkit Version of the Day
type_pod_eastl.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends