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 46namespace { 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 50template<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. 56template<> struct digits10<int, 8, false> { static const int value = 3; }; 57template<> struct digits10<int, 8, true> { static const int value = 3; }; 58template<> struct digits10<int, 16, false> { static const int value = 5; }; 59template<> struct digits10<int, 16, true> { static const int value = 5; }; 60template<> struct digits10<int, 32, false> { static const int value = 10; }; 61template<> struct digits10<int, 32, true> { static const int value = 10; }; 62template<> struct digits10<int, 64, false> { static const int value = 20; }; 63template<> struct digits10<int, 64, true> { static const int value = 19; }; 64} 65 66namespace std { 67 68struct __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. 93template<typename _T> 94struct 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> 106template<> 107struct 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> 122template<> 123struct 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> 138template<> 139struct 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> 154template<> 155struct 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> 170template<> 171struct 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> 186template<> 187struct 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> 202template<> 203struct 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> 218template<> 219struct 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