Sierra Toolkit Version of the Day
type_traits_eastl.h
00001 /*
00002 Copyright (C) 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/type_traits.h
00031 //
00032 // Copyright (c) 2005, Electronic Arts. All rights reserved.
00033 // Written and maintained by Paul Pedriana.
00035 
00036 
00038 // Specification
00039 //
00040 // This file implements C++ type traits as proposed by the emerging C++ update
00041 // as of May, 2005. This update is known as "Proposed Draft Technical Report
00042 // on C++ Library Extensions" and is document number n1745. It can be found
00043 // on the Internet as n1745.pdf and as of this writing it is updated every
00044 // couple months to reflect current thinking.
00046 
00047 
00049 // Description
00050 //
00051 // EASTL includes a fairly serious type traits library that is on par with the
00052 // one found in Boost but offers some additional performance-enhancing help as well.
00053 // The type_traits library provides information about class types, as opposed to
00054 // class instances. For example, the is_integral type trait tells if a type is
00055 // one of int, short, long, char, uint64_t, etc.
00056 //
00057 // There are three primary uses of type traits:
00058 //     * Allowing for optimized operations on some data types.
00059 //     * Allowing for different logic pathways based on data types.
00060 //     * Allowing for compile-type assertions about data type expectations.
00061 //
00062 // Most of the type traits are automatically detected and implemented by the compiler.
00063 // However, EASTL allows for the user to explicitly give the compiler hints about
00064 // type traits that the compiler cannot know, via the EASTL_DECLARE declarations.
00065 // If the user has a class that is relocatable (i.e. can safely use memcpy to copy values),
00066 // the user can use the EASTL_DECLARE_TRIVIAL_RELOCATE declaration to tell the compiler
00067 // that the class can be copied via memcpy. This will automatically significantly speed
00068 // up some containers and algorithms that use that class.
00069 //
00070 // Here is an example of using type traits to tell if a value is a floating point
00071 // value or not:
00072 //
00073 //    template <typename T>
00074 //    DoSomething(T t) {
00075 //        assert(is_floating_point<T>::value);
00076 //    }
00077 //
00078 // Here is an example of declaring a class as relocatable and using it in a vector.
00079 //
00080 //    EASTL_DECLARE_TRIVIAL_RELOCATE(Widget); // Usually you put this at the Widget class declaration.
00081 //    vector<Widget> wVector;
00082 //    wVector.erase(wVector.begin());         // This operation will be optimized via using memcpy.
00083 //
00084 // The following is a full list of the currently recognized type traits. Most of these
00085 // are implemented as of this writing, but if there is one that is missing, feel free
00086 // to contact the maintainer of this library and request that it be completed.
00087 //
00088 //    Trait                             Description
00089 // ------------------------------------------------------------------------------
00090 //    is_void                           T is void or a cv-qualified (const/void-qualified) void.
00091 //    is_integral                       T is an integral type.
00092 //    is_floating_point                 T is a floating point type.
00093 //    is_arithmetic                     T is an arithmetic type (integral or floating point).
00094 //    is_fundamental                    T is a fundamental type (void, integral, or floating point).
00095 //    is_const                          T is const-qualified.
00096 //    is_volatile                       T is volatile-qualified.
00097 //    is_abstract                       T is an abstract class.
00098 //    is_signed                         T is a signed integral type.
00099 //    is_unsigned                       T is an unsigned integral type.
00100 //    is_array                          T is an array type. The templated array container is not an array type.
00101 //    is_pointer                        T is a pointer type. Includes function pointers, but not pointers to (data or function) members.
00102 //    is_reference                      T is a reference type. Includes references to functions.
00103 //    is_member_object_pointer          T is a pointer to data member.
00104 //    is_member_function_pointer        T is a pointer to member function.
00105 //    is_member_pointer                 T is a pointer to a member or member function.
00106 //    is_enum                           T is an enumeration type.
00107 //    is_union                          T is a union type.
00108 //    is_class                          T is a class type but not a union type.
00109 //    is_polymorphic                    T is a polymorphic class.
00110 //    is_function                       T is a function type.
00111 //    is_object                         T is an object type.
00112 //    is_scalar                         T is a scalar type (arithmetic, enum, pointer, member_pointer)
00113 //    is_compound                       T is a compound type (anything but fundamental).
00114 //    is_same                           T and U name the same type.
00115 //    is_convertible                    An imaginary lvalue of type From is implicitly convertible to type To. Special conversions involving string-literals
00116 //                                      and null-pointer constants are not considered. No function-parameter adjustments are made to type To when determining
00117 //                                      whether From is convertible to To; this implies that if type To is a function type or an array type, then the condition is false.
00118 //    is_base_of                        Base is a base class of Derived or Base and Derived name the same type.
00119 //    is_empty                          T is an empty class.
00120 //    is_pod                            T is a POD type.
00121 //   *is_aligned                        Defined as true if the type has alignment requirements greater than default alignment, which is taken to be 8.
00122 //    has_trivial_constructor           The default constructor for T is trivial.
00123 //    has_trivial_copy                  The copy constructor for T is trivial.
00124 //    has_trivial_assign                The assignment operator for T is trivial.
00125 //    has_trivial_destructor            The destructor for T is trivial.
00126 //   *has_trivial_relocate              T can be moved to a new location via bitwise copy.
00127 //    has_nothrow_constructor           The default constructor for T has an empty exception specification or can otherwise be deduced never to throw an exception.
00128 //    has_nothrow_copy                  The copy constructor for T has an empty exception specification or can otherwise be deduced never to throw an exception.
00129 //    has_nothrow_assign                The assignment operator for T has an empty exception specification or can otherwise be deduced never to throw an exception.
00130 //    has_virtual_destructor            T has a virtual destructor.
00131 //    alignment_of                      An integer value representing the number of bytes of the alignment of objects of type T; an object of type T may be allocated
00132 //                                      at an address that is a multiple of its alignment.
00133 //    rank                              An integer value representing the rank of objects of type T. The term 'rank' here is used to describe the number of dimensions of an array type.
00134 //    extent                            An integer value representing the extent (dimension) of the I'th bound of objects of type T. If the type T is not an array
00135 //                                      type, has rank of less than I, or if I == 0 and T is of type 'array of unknown bound of U,' then value shall evaluate to zero;
00136 //                                      otherwise value shall evaluate to the number of elements in the I'th array bound of T. The term 'extent' here is used to describe
00137 //                                      the number of elements in an array type.
00138 //    remove_const                      The member typedef type shall be the same as T except that any top level const-qualifier has been removed.
00139 //                                      remove_const<const volatile int>::type evaluates to volatile int, whereas remove_const<const int*> is const int*.
00140 //
00141 // * is_aligned is not found in Boost nor the C++ standard update proposal.
00142 //
00143 // * has_trivial_relocate is not found in Boost nor the C++ standard update proposal.
00144 //   However, it is very useful in allowing for the generation of optimized object
00145 //   moving operations. It is similar to the is_pod type trait, but goes further and
00146 //   allows non-pod classes to be categorized as relocatable. Such categorization is
00147 //   something that no compiler can do, as only the user can know if it is such.
00148 //   Thus EASTL_DECLARE_TRIVIAL_RELOCATE is provided to allow the user to give
00149 //   the compiler a hint.
00150 //
00152 
00154 // Requirements
00155 //
00156 // As of this writing (5/2005), type_traits here requires a well-conforming
00157 // C++ compiler with respect to template metaprogramming. To use this library
00158 // you need to have at least one of the following:
00159 //     MSVC++ 7.1       (includes Win32, XBox 360, Win64, and WinCE platforms)
00160 //     GCC 3.2          (includes Playstation 3, and Linux platforms)
00161 //     Metrowerks 8.0   (incluees Playstation 3, Windows, and other platforms)
00162 //     SN Systems       (not the GCC 2.95-based compilers)
00163 //     EDG              (includes any compiler with EDG as a back-end, such as the Intel compiler)
00164 //     Comeau           (this is a C++ to C generator)
00165 //
00166 // It may be useful to list the compilers/platforms the current version of
00167 // type_traits doesn't support:
00168 //     Borland C++      (it simply has too many bugs with respect to templates).
00169 //     GCC 2.96          With a little effort, type_traits can probably be made to work with this compiler.
00171 
00173 // Implementation
00174 //
00175 // The implementation here is almost entirely based on template metaprogramming.
00176 // This is whereby you use the compiler's template functionality to define types
00177 // and values and make compilation decisions based on template declarations.
00178 // Many of the algorithms here are similar to those found in books such as
00179 // "Modern C++ Design" and C++ libraries such as Boost. The implementations here
00180 // are simpler and more straightforward than those found in some libraries, due
00181 // largely to our assumption that the compiler is good at donig template programming.
00183 
00184 
00185 
00186 #ifndef EASTL_TYPE_TRAITS_H
00187 #define EASTL_TYPE_TRAITS_H
00188 
00189 
00190 
00191 #include <stk_util/util/config_eastl.h>
00192 #include <stddef.h>                 // Is needed for size_t usage by some traits.
00193 
00194 
00195 
00196 namespace eastl
00197 {
00198 
00200     // integral_constant
00201     //
00202     // This is the base class for various type traits, as defined by the proposed
00203     // C++ standard. This is essentially a utility base class for defining properties
00204     // as both class constants (value) and as types (type).
00205     //
00206     template <typename T, T v>
00207     struct integral_constant
00208     {
00209         static const T value = v;
00210         typedef T value_type;
00211         typedef integral_constant<T, v> type;
00212     };
00213 
00214 
00216     // true_type / false_type
00217     //
00218     // These are commonly used types in the implementation of type_traits.
00219     // Other integral constant types can be defined, such as those based on int.
00220     //
00221     typedef integral_constant<bool, true>  true_type;
00222     typedef integral_constant<bool, false> false_type;
00223 
00224 
00225 
00227     // yes_type / no_type
00228     //
00229     // These are used as a utility to differentiate between two things.
00230     //
00231     typedef char yes_type;                      // sizeof(yes_type) == 1
00232     struct       no_type { char padding[8]; };  // sizeof(no_type)  != 1
00233 
00234 
00235 
00237     // type_select
00238     //
00239     // This is used to declare a type from one of two type options.
00240     // The result is based on the condition type. This has certain uses
00241     // in template metaprogramming.
00242     //
00243     // Example usage:
00244     //    typedef ChosenType = type_select<is_integral<SomeType>::value, ChoiceAType, ChoiceBType>::type;
00245     //
00246     template <bool bCondition, class ConditionIsTrueType, class ConditionIsFalseType>
00247     struct type_select { typedef ConditionIsTrueType type; };
00248 
00249     template <typename ConditionIsTrueType, class ConditionIsFalseType>
00250     struct type_select<false, ConditionIsTrueType, ConditionIsFalseType> { typedef ConditionIsFalseType type; };
00251 
00252 
00253 
00255     // type_or
00256     //
00257     // This is a utility class for creating composite type traits.
00258     //
00259     template <bool b1, bool b2, bool b3 = false, bool b4 = false, bool b5 = false>
00260     struct type_or;
00261 
00262     template <bool b1, bool b2, bool b3, bool b4, bool b5>
00263     struct type_or { static const bool value = true; };
00264 
00265     template <>
00266     struct type_or<false, false, false, false, false> { static const bool value = false; };
00267 
00268 
00269 
00271     // type_and
00272     //
00273     // This is a utility class for creating composite type traits.
00274     //
00275     template <bool b1, bool b2, bool b3 = true, bool b4 = true, bool b5 = true>
00276     struct type_and;
00277 
00278     template <bool b1, bool b2, bool b3, bool b4, bool b5>
00279     struct type_and{ static const bool value = false; };
00280 
00281     template <>
00282     struct type_and<true, true, true, true, true>{ static const bool value = true; };
00283 
00284 
00285 
00287     // type_equal
00288     //
00289     // This is a utility class for creating composite type traits.
00290     //
00291     template <int b1, int b2>
00292     struct type_equal{ static const bool value = (b1 == b2); };
00293 
00294 
00295 
00297     // type_not_equal
00298     //
00299     // This is a utility class for creating composite type traits.
00300     //
00301     template <int b1, int b2>
00302     struct type_not_equal{ static const bool value = (b1 != b2); };
00303 
00304 
00305 
00307     // type_not
00308     //
00309     // This is a utility class for creating composite type traits.
00310     //
00311     template <bool b>
00312     struct type_not{ static const bool value = true; };
00313 
00314     template <>
00315     struct type_not<true>{ static const bool value = false; };
00316 
00317 
00318 
00320     // empty
00321     //
00322     template <typename T>
00323     struct empty{ };
00324 
00325 
00326 } // namespace eastl
00327 
00328 
00329 // The following files implement the type traits themselves.
00330     #include <stk_util/util/type_fundamental_eastl.h>
00331     #include <stk_util/util/type_transformations_eastl.h>
00332     #include <stk_util/util/type_properties_eastl.h>
00333     #include <stk_util/util/type_compound_eastl.h>
00334     #include <stk_util/util/type_pod_eastl.h>
00335 
00336 
00337 #endif // Header include guard
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines