Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers smallest.h Source File

smallest.h

Go to the documentation of this file.
00001 ///\file
00002 
00003 /******************************************************************************
00004 The MIT License(MIT)
00005 
00006 Embedded Template Library.
00007 https://github.com/ETLCPP/etl
00008 https://www.etlcpp.com
00009 
00010 Copyright(c) 2014 jwellbelove
00011 
00012 Permission is hereby granted, free of charge, to any person obtaining a copy
00013 of this software and associated documentation files(the "Software"), to deal
00014 in the Software without restriction, including without limitation the rights
00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
00016 copies of the Software, and to permit persons to whom the Software is
00017 furnished to do so, subject to the following conditions :
00018 
00019 The above copyright notice and this permission notice shall be included in all
00020 copies or substantial portions of the Software.
00021 
00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00028 SOFTWARE.
00029 ******************************************************************************/
00030 
00031 #if 0
00032 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE.
00033 #endif
00034 
00035 //***************************************************************************
00036 // This file has been auto generated. Do not edit this file.
00037 //***************************************************************************
00038 
00039 //***************************************************************************
00040 // To generate to header file, run this at the command line.
00041 // Note: You will need Python and COG installed.
00042 //
00043 // python -m cogapp -d -e -osmallest.h -DNTypes=<n> smallest_generator.h
00044 // Where <n> is the number of types to support.
00045 //
00046 // e.g.
00047 // To generate handlers for up to 16 types...
00048 // python -m cogapp -d -e -osmallest.h -DNTypes=16 smallest_generator.h
00049 //
00050 // See generate.bat
00051 //***************************************************************************
00052 
00053 #ifndef __ETL_SMALLEST__
00054 #define __ETL_SMALLEST__
00055 
00056 #include <stdint.h>
00057 
00058 #include "platform.h "
00059 #include "integral_limits.h "
00060 
00061 ///\defgroup smallest smallest
00062 ///\ingroup utilities
00063 
00064 namespace etl
00065 {
00066   /* 7.18.2.1  Limits of exact-width integer types */
00067     #define INT8_MIN (-128) 
00068     #define INT16_MIN (-32768)
00069     #define INT32_MIN (-2147483647 - 1)
00070     #define INT64_MIN  (-9223372036854775807LL - 1)
00071      
00072     #define INT8_MAX 127
00073     #define INT16_MAX 32767
00074     #define INT32_MAX 2147483647
00075     #define INT64_MAX 9223372036854775807LL
00076  
00077     
00078     #define UINT8_MAX 0xff /* 255U */
00079     #define UINT16_MAX 0xffff /* 65535U */
00080     #define UINT32_MAX 0xffffffff  /* 4294967295U */
00081     #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
00082      
00083     /* 7.18.2.2  Limits of minimum-width integer types */
00084     #define INT_LEAST8_MIN INT8_MIN
00085     #define INT_LEAST16_MIN INT16_MIN
00086     #define INT_LEAST32_MIN INT32_MIN
00087     #define INT_LEAST64_MIN INT64_MIN
00088     
00089     #define INT_LEAST8_MAX INT8_MAX
00090     #define INT_LEAST16_MAX INT16_MAX
00091     #define INT_LEAST32_MAX INT32_MAX
00092     #define INT_LEAST64_MAX INT64_MAX
00093      
00094     #define UINT_LEAST8_MAX UINT8_MAX
00095     #define UINT_LEAST16_MAX UINT16_MAX
00096     #define UINT_LEAST32_MAX UINT32_MAX
00097     #define UINT_LEAST64_MAX UINT64_MAX
00098   
00099   
00100   //***************************************************************************
00101   /// Template to determine the smallest type and size.
00102   /// Supports up to 16 types.
00103   /// Defines 'value_type' which is the type of the smallest parameter.
00104   /// Defines 'size' which is the size of the smallest parameter.
00105   ///\ingroup smallest
00106   //***************************************************************************
00107   template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void, 
00108             typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void, 
00109             typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void, 
00110             typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
00111   struct smallest_type
00112   {
00113   private:
00114 
00115     // Declaration.
00116     template <const bool Boolean, typename TrueType, typename FalseType>
00117     struct choose_type;
00118 
00119     // Specialisation for 'true'.
00120     // Defines 'type' as 'TrueType'.
00121     template <typename TrueType, typename FalseType>
00122     struct choose_type<true, TrueType, FalseType>
00123     {
00124       typedef TrueType type;
00125     };
00126 
00127     // Specialisation for 'false'. 
00128     // Defines 'type' as 'FalseType'.
00129     template <typename TrueType, typename FalseType>
00130     struct choose_type<false, TrueType, FalseType>
00131     {
00132       typedef FalseType type;
00133     };
00134 
00135   public:
00136 
00137     // Define 'smallest_other' as 'smallest_type' with all but the first parameter. 
00138     typedef typename smallest_type<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::type smallest_other;
00139 
00140     // Set 'type' to be the smallest of the first parameter and any of the others.
00141     // This is recursive.
00142     typedef typename choose_type<(sizeof(T1) < sizeof(smallest_other)), // Boolean
00143                                   T1,                                   // TrueType
00144                                   smallest_other>                       // FalseType
00145                                   ::type type;                          // The smallest type of the two.
00146 
00147     // The size of the smallest type.
00148     enum
00149     {
00150       size = sizeof(type)
00151     };
00152   };
00153 
00154   //***************************************************************************
00155   // Specialisation for one template parameter.
00156   //***************************************************************************
00157   template <typename T1>
00158   struct smallest_type<T1,   void, void, void, void, void, void, void, 
00159                        void, void, void, void, void, void, void, void>
00160   {
00161     typedef T1 type;
00162 
00163     enum
00164     {
00165       size = sizeof(type)
00166     };
00167   };
00168   
00169   namespace __private_smallest__
00170   {
00171     //*************************************************************************
00172     // Determine the type to hold the number of bits based on the index.
00173     //*************************************************************************
00174     template <const int index>
00175     struct best_fit_uint_type;
00176     
00177     //*************************************************************************
00178     // Less than or equal to 8 bits.
00179     //*************************************************************************
00180     template <>
00181     struct best_fit_uint_type<0>
00182     {
00183       typedef uint_least8_t type;
00184     };
00185 
00186     //*************************************************************************
00187     // 9 to 16 bits.
00188     //*************************************************************************
00189     template <>
00190     struct best_fit_uint_type<1>
00191     {
00192       typedef uint_least16_t type;
00193     };
00194 
00195     //*************************************************************************
00196     // 17 to 31 bits.
00197     //*************************************************************************
00198     template <>
00199     struct best_fit_uint_type<2>
00200     {
00201       typedef uint_least32_t type;
00202     };
00203 
00204     //*************************************************************************
00205     // Greater than 32 bits.
00206     //*************************************************************************
00207     template <>
00208     struct best_fit_uint_type<3>
00209     {
00210       typedef uint_least64_t type;
00211     };
00212 
00213     //*************************************************************************
00214     // Determine the type to hold the number of bits based on the index.
00215     //*************************************************************************
00216     template <const int index>
00217     struct best_fit_int_type;
00218 
00219     //*************************************************************************
00220     // Less than or equal to 8 bits.
00221     //*************************************************************************
00222     template <>
00223     struct best_fit_int_type<0>
00224     {
00225       typedef int_least8_t type;
00226     };
00227 
00228     //*************************************************************************
00229     // 9 to 16 bits.
00230     //*************************************************************************
00231     template <>
00232     struct best_fit_int_type<1>
00233     {
00234       typedef int_least16_t type;
00235     };
00236 
00237     //*************************************************************************
00238     // 17 to 31 bits.
00239     //*************************************************************************
00240     template <>
00241     struct best_fit_int_type<2>
00242     {
00243       typedef int_least32_t type;
00244     };
00245 
00246     //*************************************************************************
00247     // Greater than 32 bits.
00248     //*************************************************************************
00249     template <>
00250     struct best_fit_int_type<3>
00251     {
00252       typedef int_least64_t type;
00253     };
00254   }
00255 
00256   //***************************************************************************
00257   /// Template to determine the smallest unsigned int type that can contain a 
00258   /// value with the specified number of bits.
00259   /// Defines 'type' which is the type of the smallest unsigned integer.
00260   ///\ingroup smallest
00261   //***************************************************************************
00262   template <const size_t NBITS>
00263   struct smallest_uint_for_bits
00264   {
00265   private:
00266     
00267     // Determines the index of the best unsigned type for the required number of bits.
00268     static const int TYPE_INDEX = ((NBITS >  8) ? 1 : 0) + 
00269                                   ((NBITS > 16) ? 1 : 0) +
00270                                   ((NBITS > 32) ? 1 : 0);
00271 
00272   public:
00273 
00274     typedef typename __private_smallest__::best_fit_uint_type<TYPE_INDEX>::type type;
00275   };
00276 
00277   //***************************************************************************
00278   /// Template to determine the smallest signed int type that can contain a 
00279   /// value with the specified number of bits.
00280   /// Defines 'type' which is the type of the smallest signed integer.
00281   ///\ingroup smallest
00282   //***************************************************************************
00283   template <const size_t NBITS>
00284   struct smallest_int_for_bits
00285   {
00286   private:
00287 
00288     // Determines the index of the best unsigned type for the required number of bits.
00289     static const int TYPE_INDEX = ((NBITS >  8) ? 1 : 0) +
00290                                   ((NBITS > 16) ? 1 : 0) +
00291                                   ((NBITS > 32) ? 1 : 0);
00292 
00293   public:
00294 
00295     typedef typename __private_smallest__::best_fit_int_type<TYPE_INDEX>::type type;
00296   };
00297 
00298   //***************************************************************************
00299   /// Template to determine the smallest unsigned int type that can contain the
00300   /// specified unsigned value.
00301   /// Defines 'type' which is the type of the smallest unsigned integer.
00302   ///\ingroup smallest
00303   //***************************************************************************
00304   template <const uintmax_t VALUE>
00305   struct smallest_uint_for_value
00306   {
00307   private:
00308 
00309     // Determines the index of the best unsigned type for the required value.
00310     static const int TYPE_INDEX = ((VALUE > UINT_LEAST8_MAX)  ? 1 : 0) +
00311                                   ((VALUE > UINT16_MAX) ? 1 : 0) + 
00312                                   ((VALUE > UINT32_MAX) ? 1 : 0);
00313 
00314   public:
00315 
00316     typedef typename __private_smallest__::best_fit_uint_type<TYPE_INDEX>::type type;
00317   };
00318 
00319   //***************************************************************************
00320   /// Template to determine the smallest int type that can contain the
00321   /// specified signed value.
00322   /// Defines 'type' which is the type of the smallest signed integer.
00323   ///\ingroup smallest
00324   //***************************************************************************
00325   template <const intmax_t VALUE>
00326   struct smallest_int_for_value
00327   {
00328   private:
00329 
00330     // Determines the index of the best signed type for the required value.
00331     static const int TYPE_INDEX = (((VALUE > INT_LEAST8_MAX)  || (VALUE < INT_LEAST8_MIN))  ? 1 : 0) + 
00332                                   (((VALUE > INT16_MAX) || (VALUE < INT16_MIN)) ? 1 : 0) +
00333                                   (((VALUE > INT32_MAX) || (VALUE < INT32_MIN)) ? 1 : 0);
00334 
00335   public:
00336 
00337     typedef typename __private_smallest__::best_fit_int_type<TYPE_INDEX>::type type;
00338   };
00339 }
00340 
00341 #endif
00342