OpenWalnut  1.4.0
WTypeTraits.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WTYPETRAITS_H
00026 #define WTYPETRAITS_H
00027 
00028 #include <stdint.h>
00029 
00030 /**
00031  * All kinds of type traits and policies like type priorities and type combinations.
00032  */
00033 namespace WTypeTraits
00034 {
00035     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00036     // Type promitions
00037     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00038 
00039     /**
00040      * Class for checking the "better" type if two integral types are known.
00041      *
00042      * \tparam T1 the first type
00043      * \tparam T2 the second type
00044      */
00045     template < typename T1, typename T2 >
00046     class TypePromotion;    // leaving this one empty is a good idea in most cases as there is no "natural order" in all c++ types.
00047 
00048     /**
00049      * Class for checking the "better" type if two integral types are known. Specialization if both types are equal
00050      *
00051      * \tparam T the types
00052      */
00053     template < typename T >
00054     class TypePromotion< T, T >
00055     {
00056     public:
00057         typedef T Result;       //!< if both types are the same, the "better" type is obvious.
00058     };
00059 
00060     // we assume macros to be evil but it helps us here!
00061 #define CREATEPROMOTION( T1, T2, ResultType )               \
00062     template <>                                             \
00063     class TypePromotion< T1, T2 >                           \
00064     {                             /*NOLINT*/                \
00065     public:                                                 \
00066         typedef ResultType Result;                          \
00067     };                            /*NOLINT*/                \
00068                                                             \
00069     template <>                                             \
00070     class TypePromotion< T2, T1 >                           \
00071     {                             /*NOLINT*/                \
00072     public:                                                 \
00073         typedef ResultType Result;                          \
00074     };                            /*NOLINT*/                \
00075 
00076     // Create the promotions we need. Please check this list. But do not change arbitrarily if you need a different mapping. Instead, specialize
00077     // the template TypePromotion locally.
00078 
00079     // Exclusion of this macro stuff from doxygen:
00080     // \cond HIDDEN_SYMBOLS
00081 
00082     // long double is the better choice for these
00083     CREATEPROMOTION( long double, double,   long double )
00084     CREATEPROMOTION( long double, float,    long double )
00085     CREATEPROMOTION( long double, int64_t,  long double )
00086     CREATEPROMOTION( long double, int32_t,  long double )
00087     CREATEPROMOTION( long double, int16_t,  long double )
00088     CREATEPROMOTION( long double, int8_t,   long double )
00089     CREATEPROMOTION( long double, uint64_t, long double )
00090     CREATEPROMOTION( long double, uint32_t, long double )
00091     CREATEPROMOTION( long double, uint16_t, long double )
00092     CREATEPROMOTION( long double, uint8_t,  long double )
00093 
00094     // double is the better choice for these
00095     CREATEPROMOTION( double, float,    double )
00096     CREATEPROMOTION( double, int64_t,  double )
00097     CREATEPROMOTION( double, int32_t,  double )
00098     CREATEPROMOTION( double, int16_t,  double )
00099     CREATEPROMOTION( double, int8_t,   double )
00100     CREATEPROMOTION( double, uint64_t, double )
00101     CREATEPROMOTION( double, uint32_t, double )
00102     CREATEPROMOTION( double, uint16_t, double )
00103     CREATEPROMOTION( double, uint8_t,  double )
00104 
00105     // float is the better choice for these (?)
00106     CREATEPROMOTION( float, int64_t,   float )
00107     CREATEPROMOTION( float, int32_t,   float )
00108     CREATEPROMOTION( float, int16_t,   float )
00109     CREATEPROMOTION( float, int8_t,    float )
00110     CREATEPROMOTION( float, uint64_t,  float )
00111     CREATEPROMOTION( float, uint32_t,  float )
00112     CREATEPROMOTION( float, uint16_t,  float )
00113     CREATEPROMOTION( float, uint8_t,   float )
00114 
00115     // int64_t is the better choice for these (?)
00116     CREATEPROMOTION( int64_t, int32_t,  int64_t )
00117     CREATEPROMOTION( int64_t, int16_t,  int64_t )
00118     CREATEPROMOTION( int64_t, int8_t,   int64_t )
00119     CREATEPROMOTION( int64_t, uint64_t, double ) // ?
00120     CREATEPROMOTION( int64_t, uint32_t, int64_t )
00121     CREATEPROMOTION( int64_t, uint16_t, int64_t )
00122     CREATEPROMOTION( int64_t, uint8_t,  int64_t )
00123 
00124     // int32_t is the better choice for these (?)
00125     CREATEPROMOTION( int32_t, int16_t,  int32_t )
00126     CREATEPROMOTION( int32_t, int8_t,   int32_t )
00127     CREATEPROMOTION( int32_t, uint64_t, double ) // ?
00128     CREATEPROMOTION( int32_t, uint32_t, int64_t ) // ?
00129     CREATEPROMOTION( int32_t, uint16_t, int32_t )
00130     CREATEPROMOTION( int32_t, uint8_t,  int32_t )
00131 
00132     // int16_t is the better choice for these (?)
00133     CREATEPROMOTION( int16_t, int8_t,   int16_t )
00134     CREATEPROMOTION( int16_t, uint64_t, double ) // ?
00135     CREATEPROMOTION( int16_t, uint32_t, int64_t ) // ?
00136     CREATEPROMOTION( int16_t, uint16_t, int32_t )  // ?
00137     CREATEPROMOTION( int16_t, uint8_t,  int16_t )
00138 
00139     // int8_t is the better choice for these (?)
00140     CREATEPROMOTION( int8_t, uint64_t, double ) // ?
00141     CREATEPROMOTION( int8_t, uint32_t, int64_t ) // ?
00142     CREATEPROMOTION( int8_t, uint16_t, int32_t )  // ?
00143     CREATEPROMOTION( int8_t, uint8_t,  int16_t ) // ?
00144 
00145     // uint64_t is the better choice for these (?)
00146     CREATEPROMOTION( uint64_t, uint32_t, uint64_t )
00147     CREATEPROMOTION( uint64_t, uint16_t, uint64_t )
00148     CREATEPROMOTION( uint64_t, uint8_t,  uint64_t )
00149 
00150     // uint32_t is the better choice for these (?)
00151     CREATEPROMOTION( uint32_t, uint16_t, uint32_t )
00152     CREATEPROMOTION( uint32_t, uint8_t,  uint32_t )
00153 
00154     // uint16_t is the better choice for these (?)
00155     CREATEPROMOTION( uint16_t, uint8_t, uint16_t )
00156 
00157     // uint8_t is the better choice for these (?)
00158     // promoted already
00159 
00160     // Exclusion of this macro stuff from doxygen: end
00161     // \endcond
00162 }
00163 
00164 #endif  // WTYPETRAITS_H
00165