Home | History | Annotate | Download | only in include
      1 /* -*- c++ -*- */
      2 /*
      3  * Copyright (C) 2010 The Android Open Source Project
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *  * Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *  * Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in
     13  *    the documentation and/or other materials provided with the
     14  *    distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     20  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     23  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #ifndef ANDROID_ASTL_LIMITS__
     31 #define ANDROID_ASTL_LIMITS__
     32 
     33 #include <limits.h>
     34 // GNU C++ compiler?
     35 #ifndef __GNUG__
     36 #error "__GNUG__ is not defined"
     37 #endif
     38 
     39 #ifdef _T
     40 #error "_T is defined"
     41 #endif
     42 
     43 // This is very incomplete partial implementation of the standard
     44 // <limits>. Only partial support for float and double is provided.
     45 
     46 namespace {
     47 // Template to return the number of decimal digits in a number
     48 // representation based on the number of bits and sign.
     49 // e.g  digits10<int,64,true>::value == 19
     50 template<typename T, T bits, bool is_signed> struct digits10 {
     51     static const int value = 0;
     52 };
     53 
     54 // Specialization that can be used to initialize static constant at
     55 // compile time.
     56 template<> struct digits10<int,  8, false> { static const int value = 3; };
     57 template<> struct digits10<int,  8, true>  { static const int value = 3; };
     58 template<> struct digits10<int, 16, false> { static const int value = 5; };
     59 template<> struct digits10<int, 16, true>  { static const int value = 5; };
     60 template<> struct digits10<int, 32, false> { static const int value = 10; };
     61 template<> struct digits10<int, 32, true>  { static const int value = 10; };
     62 template<> struct digits10<int, 64, false> { static const int value = 20; };
     63 template<> struct digits10<int, 64, true>  { static const int value = 19; };
     64 }
     65 
     66 namespace std {
     67 
     68 struct __numeric_limits_base
     69 {
     70     // True for all fundamental types.
     71     static const bool is_specialized = false;
     72 
     73     // True if the type is signed.
     74     static const bool is_signed = false;
     75 
     76     // True if the type is integer.
     77     static const bool is_integer = false;
     78 
     79     // The number of radix digits that be represented without change. For
     80     // integer types, the number of non-sign bits in the representation; for
     81     // floating-point types, the number of radix digits in the mantissa.
     82     // Equivalent to FLT_MANT_DIG, DBL_MANT_DIG.
     83     static const int digits = 0;
     84 
     85     // The number of base 10 digits that can be represented without change.
     86     // Equivalent to FLT_DIG, DBL_DIG, LDBL_MANT_DIG.
     87     static const int digits10 = 0;
     88 };
     89 
     90 
     91 // Properties of fundamental types.
     92 // Only a subset of the properties is supported.
     93 template<typename _T>
     94 struct numeric_limits : public __numeric_limits_base
     95 {
     96     // The minimum finite value.
     97     static _T min() { return static_cast<_T>(0); }
     98 
     99     // The maximum finite value.
    100     static _T max() { return static_cast<_T>(0); }
    101 };
    102 
    103 // Specializations for some fundamental types.
    104 
    105 // numeric_limits<float>
    106 template<>
    107 struct numeric_limits<float>
    108 {
    109     static const bool is_specialized = true;
    110 
    111     static float min() { return __FLT_MIN__; }
    112     static float max() { return __FLT_MAX__; }
    113 
    114     static const bool is_signed = true;
    115     static const bool is_integer = false;
    116 
    117     static const int digits = __FLT_MANT_DIG__;
    118     static const int digits10 = __FLT_DIG__;
    119 };
    120 
    121 // numeric_limits<double>
    122 template<>
    123 struct numeric_limits<double>
    124 {
    125     static const bool is_specialized = true;
    126 
    127     static double min() { return __DBL_MIN__; }
    128     static double max() { return __DBL_MAX__; }
    129 
    130     static const bool is_signed = true;
    131     static const bool is_integer = false;
    132 
    133     static const int digits = __DBL_MANT_DIG__;
    134     static const int digits10 = __DBL_DIG__;
    135 };
    136 
    137 // numeric_limits<int>
    138 template<>
    139 struct numeric_limits<int>
    140 {
    141     static const bool is_specialized = true;
    142 
    143     static int min() { return INT_MIN; }
    144     static int max() { return INT_MAX; }
    145 
    146     static const bool is_signed = true;
    147     static const bool is_integer = true;
    148 
    149     static const int digits = static_cast<int>(sizeof(int) * CHAR_BIT);
    150     static const int digits10 = digits10<int, digits, is_signed>::value;
    151 };
    152 
    153 // numeric_limits<unsigned int>
    154 template<>
    155 struct numeric_limits<unsigned int>
    156 {
    157     static const bool is_specialized = true;
    158 
    159     static unsigned int min() { return 0; }
    160     static unsigned int max() { return UINT_MAX; }
    161 
    162     static const bool is_signed = false;
    163     static const bool is_integer = true;
    164 
    165     static const int digits = static_cast<int>(sizeof(unsigned int) * CHAR_BIT);
    166     static const int digits10 = digits10<int, digits, is_signed>::value;
    167 };
    168 
    169 // numeric_limits<long>
    170 template<>
    171 struct numeric_limits<long>
    172 {
    173     static const bool is_specialized = true;
    174 
    175     static long min() { return LONG_MIN; }
    176     static long max() { return LONG_MAX; }
    177 
    178     static const bool is_signed = true;
    179     static const bool is_integer = true;
    180 
    181     static const int digits = LONG_BIT;
    182     static const int digits10 = digits10<int, digits, is_signed>::value;
    183 };
    184 
    185 // numeric_limits<unsigned long>
    186 template<>
    187 struct numeric_limits<unsigned long>
    188 {
    189     static const bool is_specialized = true;
    190 
    191     static unsigned long min() { return 0; }
    192     static unsigned long max() { return ULONG_MAX; }
    193 
    194     static const bool is_signed = true;
    195     static const bool is_integer = true;
    196 
    197     static const int digits = LONG_BIT;
    198     static const int digits10 = digits10<int, digits, is_signed>::value;
    199 };
    200 
    201 // numeric_limits<long long>
    202 template<>
    203 struct numeric_limits<long long>
    204 {
    205     static const bool is_specialized = true;
    206 
    207     static long long min() { return LLONG_MIN; }
    208     static long long max() { return LLONG_MAX; }
    209 
    210     static const bool is_signed = true;
    211     static const bool is_integer = true;
    212 
    213     static const int digits = static_cast<int>(sizeof(long long) * CHAR_BIT);
    214     static const int digits10 = digits10<int, digits, is_signed>::value;
    215 };
    216 
    217 // numeric_limits<unsigned long long>
    218 template<>
    219 struct numeric_limits<unsigned long long>
    220 {
    221     static const bool is_specialized = true;
    222 
    223     static unsigned long long min() { return 0; }
    224     static unsigned long long max() { return ULLONG_MAX; }
    225 
    226     static const bool is_signed = true;
    227     static const bool is_integer = true;
    228 
    229     static const int digits = static_cast<int>(sizeof(unsigned long long) * CHAR_BIT);
    230     static const int digits10 = digits10<int, digits, is_signed>::value;
    231 };
    232 
    233 }  // namespace std
    234 
    235 
    236 #endif
    237