1 /* boost integer_traits.hpp header file 2 * 3 * Copyright Jens Maurer 2000 4 * Distributed under the Boost Software License, Version 1.0. (See 5 * accompanying file LICENSE_1_0.txt or copy at 6 * http://www.boost.org/LICENSE_1_0.txt) 7 * 8 * $Id: integer_traits.hpp 80740 2012-09-28 18:34:12Z jewillco $ 9 * 10 * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers 11 */ 12 13 // See http://www.boost.org/libs/integer for documentation. 14 15 16 #ifndef BOOST_INTEGER_TRAITS_HPP 17 #define BOOST_INTEGER_TRAITS_HPP 18 19 #include <boost/config.hpp> 20 #include <boost/limits.hpp> 21 22 // These are an implementation detail and not part of the interface 23 #include <limits.h> 24 // we need wchar.h for WCHAR_MAX/MIN but not all platforms provide it, 25 // and some may have <wchar.h> but not <cwchar> ... 26 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && (!defined(BOOST_NO_CWCHAR) || defined(sun) || defined(__sun) || defined(__QNX__)) 27 #include <wchar.h> 28 #endif 29 30 // 31 // We simply cannot include this header on gcc without getting copious warnings of the kind: 32 // 33 // ../../../boost/integer_traits.hpp:164:66: warning: use of C99 long long integer constant 34 // 35 // And yet there is no other reasonable implementation, so we declare this a system header 36 // to suppress these warnings. 37 // 38 #if defined(__GNUC__) && (__GNUC__ >= 4) 39 #pragma GCC system_header 40 #endif 41 42 namespace boost { 43 template<class T> 44 class integer_traits : public std::numeric_limits<T> 45 { 46 public: 47 BOOST_STATIC_CONSTANT(bool, is_integral = false); 48 }; 49 50 namespace detail { 51 template<class T, T min_val, T max_val> 52 class integer_traits_base 53 { 54 public: 55 BOOST_STATIC_CONSTANT(bool, is_integral = true); 56 BOOST_STATIC_CONSTANT(T, const_min = min_val); 57 BOOST_STATIC_CONSTANT(T, const_max = max_val); 58 }; 59 60 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION 61 // A definition is required even for integral static constants 62 template<class T, T min_val, T max_val> 63 const bool integer_traits_base<T, min_val, max_val>::is_integral; 64 65 template<class T, T min_val, T max_val> 66 const T integer_traits_base<T, min_val, max_val>::const_min; 67 68 template<class T, T min_val, T max_val> 69 const T integer_traits_base<T, min_val, max_val>::const_max; 70 #endif 71 72 } // namespace detail 73 74 template<> 75 class integer_traits<bool> 76 : public std::numeric_limits<bool>, 77 public detail::integer_traits_base<bool, false, true> 78 { }; 79 80 template<> 81 class integer_traits<char> 82 : public std::numeric_limits<char>, 83 public detail::integer_traits_base<char, CHAR_MIN, CHAR_MAX> 84 { }; 85 86 template<> 87 class integer_traits<signed char> 88 : public std::numeric_limits<signed char>, 89 public detail::integer_traits_base<signed char, SCHAR_MIN, SCHAR_MAX> 90 { }; 91 92 template<> 93 class integer_traits<unsigned char> 94 : public std::numeric_limits<unsigned char>, 95 public detail::integer_traits_base<unsigned char, 0, UCHAR_MAX> 96 { }; 97 98 #ifndef BOOST_NO_INTRINSIC_WCHAR_T 99 template<> 100 class integer_traits<wchar_t> 101 : public std::numeric_limits<wchar_t>, 102 // Don't trust WCHAR_MIN and WCHAR_MAX with Mac OS X's native 103 // library: they are wrong! 104 #if defined(WCHAR_MIN) && defined(WCHAR_MAX) && !defined(__APPLE__) 105 public detail::integer_traits_base<wchar_t, WCHAR_MIN, WCHAR_MAX> 106 #elif defined(__BORLANDC__) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__BEOS__) && defined(__GNUC__)) 107 // No WCHAR_MIN and WCHAR_MAX, whar_t is short and unsigned: 108 public detail::integer_traits_base<wchar_t, 0, 0xffff> 109 #elif (defined(__sgi) && (!defined(__SGI_STL_PORT) || __SGI_STL_PORT < 0x400))\ 110 || (defined __APPLE__)\ 111 || (defined(__OpenBSD__) && defined(__GNUC__))\ 112 || (defined(__NetBSD__) && defined(__GNUC__))\ 113 || (defined(__FreeBSD__) && defined(__GNUC__))\ 114 || (defined(__DragonFly__) && defined(__GNUC__))\ 115 || (defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 3) && !defined(__SGI_STL_PORT)) 116 // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as int. 117 // - SGI MIPSpro with native library 118 // - gcc 3.x on HP-UX 119 // - Mac OS X with native library 120 // - gcc on FreeBSD, OpenBSD and NetBSD 121 public detail::integer_traits_base<wchar_t, INT_MIN, INT_MAX> 122 #elif defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 2) && !defined(__SGI_STL_PORT) 123 // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as unsigned int. 124 // - gcc 2.95.x on HP-UX 125 // (also, std::numeric_limits<wchar_t> appears to return the wrong values). 126 public detail::integer_traits_base<wchar_t, 0, UINT_MAX> 127 #else 128 #error No WCHAR_MIN and WCHAR_MAX present, please adjust integer_traits<> for your compiler. 129 #endif 130 { }; 131 #endif // BOOST_NO_INTRINSIC_WCHAR_T 132 133 template<> 134 class integer_traits<short> 135 : public std::numeric_limits<short>, 136 public detail::integer_traits_base<short, SHRT_MIN, SHRT_MAX> 137 { }; 138 139 template<> 140 class integer_traits<unsigned short> 141 : public std::numeric_limits<unsigned short>, 142 public detail::integer_traits_base<unsigned short, 0, USHRT_MAX> 143 { }; 144 145 template<> 146 class integer_traits<int> 147 : public std::numeric_limits<int>, 148 public detail::integer_traits_base<int, INT_MIN, INT_MAX> 149 { }; 150 151 template<> 152 class integer_traits<unsigned int> 153 : public std::numeric_limits<unsigned int>, 154 public detail::integer_traits_base<unsigned int, 0, UINT_MAX> 155 { }; 156 157 template<> 158 class integer_traits<long> 159 : public std::numeric_limits<long>, 160 public detail::integer_traits_base<long, LONG_MIN, LONG_MAX> 161 { }; 162 163 template<> 164 class integer_traits<unsigned long> 165 : public std::numeric_limits<unsigned long>, 166 public detail::integer_traits_base<unsigned long, 0, ULONG_MAX> 167 { }; 168 169 #if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) 170 #if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) 171 172 template<> 173 class integer_traits< ::boost::long_long_type> 174 : public std::numeric_limits< ::boost::long_long_type>, 175 public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX> 176 { }; 177 178 template<> 179 class integer_traits< ::boost::ulong_long_type> 180 : public std::numeric_limits< ::boost::ulong_long_type>, 181 public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> 182 { }; 183 184 #elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG) 185 186 template<> 187 class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ }; 188 template<> 189 class integer_traits< ::boost::ulong_long_type> 190 : public std::numeric_limits< ::boost::ulong_long_type>, 191 public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX> 192 { }; 193 194 #elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG) 195 196 template<> 197 class integer_traits< ::boost::long_long_type> 198 : public std::numeric_limits< ::boost::long_long_type>, 199 public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX> 200 { }; 201 202 template<> 203 class integer_traits< ::boost::ulong_long_type> 204 : public std::numeric_limits< ::boost::ulong_long_type>, 205 public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX> 206 { }; 207 208 #elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG) 209 210 template<> 211 class integer_traits< ::boost::long_long_type> 212 : public std::numeric_limits< ::boost::long_long_type>, 213 public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX> 214 { }; 215 216 template<> 217 class integer_traits< ::boost::ulong_long_type> 218 : public std::numeric_limits< ::boost::ulong_long_type>, 219 public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX> 220 { }; 221 222 #elif defined(BOOST_HAS_LONG_LONG) 223 // 224 // we have long long but no constants, this happens for example with gcc in -ansi mode, 225 // we'll just have to work out the values for ourselves (assumes 2's compliment representation): 226 // 227 template<> 228 class integer_traits< ::boost::long_long_type> 229 : public std::numeric_limits< ::boost::long_long_type>, 230 public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)), ~(1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1))> 231 { }; 232 233 template<> 234 class integer_traits< ::boost::ulong_long_type> 235 : public std::numeric_limits< ::boost::ulong_long_type>, 236 public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL> 237 { }; 238 239 #elif defined(BOOST_HAS_MS_INT64) 240 241 template<> 242 class integer_traits< __int64> 243 : public std::numeric_limits< __int64>, 244 public detail::integer_traits_base< __int64, _I64_MIN, _I64_MAX> 245 { }; 246 247 template<> 248 class integer_traits< unsigned __int64> 249 : public std::numeric_limits< unsigned __int64>, 250 public detail::integer_traits_base< unsigned __int64, 0, _UI64_MAX> 251 { }; 252 253 #endif 254 #endif 255 256 } // namespace boost 257 258 #endif /* BOOST_INTEGER_TRAITS_HPP */ 259 260 261 262