integer_traits.hpp 8.1 KB

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