|
Sierra Toolkit
Version of the Day
|
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