common_arithmetic_type.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED
  2. #define BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED
  3. //
  4. // Copyright 2015 Peter Dimov
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt
  9. //
  10. #include <boost/config.hpp>
  11. namespace boost
  12. {
  13. namespace type_traits_detail
  14. {
  15. template<int I> struct arithmetic_type;
  16. // Types bool, char, char16_t, char32_t, wchar_t,
  17. // and the signed and unsigned integer types are
  18. // collectively called integral types
  19. template<> struct arithmetic_type<1>
  20. {
  21. typedef bool type;
  22. typedef char (&result_type) [1];
  23. };
  24. template<> struct arithmetic_type<2>
  25. {
  26. typedef char type;
  27. typedef char (&result_type) [2];
  28. };
  29. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  30. template<> struct arithmetic_type<3>
  31. {
  32. typedef wchar_t type;
  33. typedef char (&result_type) [3];
  34. };
  35. #endif
  36. // There are five standard signed integer types:
  37. // "signed char", "short int", "int", "long int", and "long long int".
  38. template<> struct arithmetic_type<4>
  39. {
  40. typedef signed char type;
  41. typedef char (&result_type) [4];
  42. };
  43. template<> struct arithmetic_type<5>
  44. {
  45. typedef short type;
  46. typedef char (&result_type) [5];
  47. };
  48. template<> struct arithmetic_type<6>
  49. {
  50. typedef int type;
  51. typedef char (&result_type) [6];
  52. };
  53. template<> struct arithmetic_type<7>
  54. {
  55. typedef long type;
  56. typedef char (&result_type) [7];
  57. };
  58. template<> struct arithmetic_type<8>
  59. {
  60. typedef boost::long_long_type type;
  61. typedef char (&result_type) [8];
  62. };
  63. // For each of the standard signed integer types, there exists a corresponding
  64. // (but different) standard unsigned integer type: "unsigned char", "unsigned short int",
  65. // "unsigned int", "unsigned long int", and "unsigned long long int"
  66. template<> struct arithmetic_type<9>
  67. {
  68. typedef unsigned char type;
  69. typedef char (&result_type) [9];
  70. };
  71. template<> struct arithmetic_type<10>
  72. {
  73. typedef unsigned short type;
  74. typedef char (&result_type) [10];
  75. };
  76. template<> struct arithmetic_type<11>
  77. {
  78. typedef unsigned int type;
  79. typedef char (&result_type) [11];
  80. };
  81. template<> struct arithmetic_type<12>
  82. {
  83. typedef unsigned long type;
  84. typedef char (&result_type) [12];
  85. };
  86. template<> struct arithmetic_type<13>
  87. {
  88. typedef boost::ulong_long_type type;
  89. typedef char (&result_type) [13];
  90. };
  91. // There are three floating point types: float, double, and long double.
  92. template<> struct arithmetic_type<14>
  93. {
  94. typedef float type;
  95. typedef char (&result_type) [14];
  96. };
  97. template<> struct arithmetic_type<15>
  98. {
  99. typedef double type;
  100. typedef char (&result_type) [15];
  101. };
  102. template<> struct arithmetic_type<16>
  103. {
  104. typedef long double type;
  105. typedef char (&result_type) [16];
  106. };
  107. #if !defined( BOOST_NO_CXX11_CHAR16_T )
  108. template<> struct arithmetic_type<17>
  109. {
  110. typedef char16_t type;
  111. typedef char (&result_type) [17];
  112. };
  113. #endif
  114. #if !defined( BOOST_NO_CXX11_CHAR32_T )
  115. template<> struct arithmetic_type<18>
  116. {
  117. typedef char32_t type;
  118. typedef char (&result_type) [18];
  119. };
  120. #endif
  121. #if defined( BOOST_HAS_INT128 )
  122. template<> struct arithmetic_type<19>
  123. {
  124. typedef boost::int128_type type;
  125. typedef char (&result_type) [19];
  126. };
  127. template<> struct arithmetic_type<20>
  128. {
  129. typedef boost::uint128_type type;
  130. typedef char (&result_type) [20];
  131. };
  132. #endif
  133. template<class T, class U> class common_arithmetic_type
  134. {
  135. private:
  136. static arithmetic_type<1>::result_type select( arithmetic_type<1>::type );
  137. static arithmetic_type<2>::result_type select( arithmetic_type<2>::type );
  138. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  139. static arithmetic_type<3>::result_type select( arithmetic_type<3>::type );
  140. #endif
  141. static arithmetic_type<4>::result_type select( arithmetic_type<4>::type );
  142. static arithmetic_type<5>::result_type select( arithmetic_type<5>::type );
  143. static arithmetic_type<6>::result_type select( arithmetic_type<6>::type );
  144. static arithmetic_type<7>::result_type select( arithmetic_type<7>::type );
  145. static arithmetic_type<8>::result_type select( arithmetic_type<8>::type );
  146. static arithmetic_type<9>::result_type select( arithmetic_type<9>::type );
  147. static arithmetic_type<10>::result_type select( arithmetic_type<10>::type );
  148. static arithmetic_type<11>::result_type select( arithmetic_type<11>::type );
  149. static arithmetic_type<12>::result_type select( arithmetic_type<12>::type );
  150. static arithmetic_type<13>::result_type select( arithmetic_type<13>::type );
  151. static arithmetic_type<14>::result_type select( arithmetic_type<14>::type );
  152. static arithmetic_type<15>::result_type select( arithmetic_type<15>::type );
  153. static arithmetic_type<16>::result_type select( arithmetic_type<16>::type );
  154. #if !defined( BOOST_NO_CXX11_CHAR16_T )
  155. static arithmetic_type<17>::result_type select( arithmetic_type<17>::type );
  156. #endif
  157. #if !defined( BOOST_NO_CXX11_CHAR32_T )
  158. static arithmetic_type<18>::result_type select( arithmetic_type<18>::type );
  159. #endif
  160. #if defined( BOOST_HAS_INT128 )
  161. static arithmetic_type<19>::result_type select( arithmetic_type<19>::type );
  162. static arithmetic_type<20>::result_type select( arithmetic_type<20>::type );
  163. #endif
  164. static bool cond();
  165. BOOST_STATIC_CONSTANT(int, selector = sizeof(select(cond() ? T() : U())));
  166. public:
  167. typedef typename arithmetic_type<selector>::type type;
  168. };
  169. } // namespace type_traits_detail
  170. } // namespace boost
  171. #endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED