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