config.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2023 Matt Borland
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // https://www.boost.org/LICENSE_1_0.txt
  4. #ifndef BOOST_CHARCONV_DETAIL_CONFIG_HPP
  5. #define BOOST_CHARCONV_DETAIL_CONFIG_HPP
  6. #include <boost/config.hpp>
  7. #include <type_traits>
  8. #include <cfloat>
  9. #include <boost/assert.hpp>
  10. #define BOOST_CHARCONV_ASSERT(expr) BOOST_ASSERT(expr)
  11. #define BOOST_CHARCONV_ASSERT_MSG(expr, msg) BOOST_ASSERT_MSG(expr, msg)
  12. #ifdef BOOST_CHARCONV_DEBUG
  13. # define BOOST_CHARCONV_DEBUG_ASSERT(expr) BOOST_CHARCONV_ASSERT(expr)
  14. #else
  15. # define BOOST_CHARCONV_DEBUG_ASSERT(expr)
  16. #endif
  17. // Use 128-bit integers and suppress warnings for using extensions
  18. #if defined(BOOST_HAS_INT128)
  19. # define BOOST_CHARCONV_HAS_INT128
  20. # define BOOST_CHARCONV_INT128_MAX static_cast<boost::int128_type>((static_cast<boost::uint128_type>(1) << 127) - 1)
  21. # define BOOST_CHARCONV_INT128_MIN (-BOOST_CHARCONV_INT128_MAX - 1)
  22. # define BOOST_CHARCONV_UINT128_MAX (2 * static_cast<boost::uint128_type>(BOOST_CHARCONV_INT128_MAX) + 1)
  23. #endif
  24. #ifndef BOOST_NO_CXX14_CONSTEXPR
  25. # define BOOST_CHARCONV_CXX14_CONSTEXPR BOOST_CXX14_CONSTEXPR
  26. # define BOOST_CHARCONV_CXX14_CONSTEXPR_NO_INLINE BOOST_CXX14_CONSTEXPR
  27. #else
  28. # define BOOST_CHARCONV_CXX14_CONSTEXPR inline
  29. # define BOOST_CHARCONV_CXX14_CONSTEXPR_NO_INLINE
  30. #endif
  31. #if defined(__GNUC__) && __GNUC__ == 5
  32. # define BOOST_CHARCONV_GCC5_CONSTEXPR inline
  33. #else
  34. # define BOOST_CHARCONV_GCC5_CONSTEXPR BOOST_CHARCONV_CXX14_CONSTEXPR
  35. #endif
  36. // C++17 allowed for constexpr lambdas
  37. #if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L
  38. # define BOOST_CHARCONV_CXX17_CONSTEXPR constexpr
  39. #else
  40. # define BOOST_CHARCONV_CXX17_CONSTEXPR inline
  41. #endif
  42. // Determine endianness
  43. #if defined(_WIN32)
  44. #define BOOST_CHARCONV_ENDIAN_BIG_BYTE 0
  45. #define BOOST_CHARCONV_ENDIAN_LITTLE_BYTE 1
  46. #elif defined(__BYTE_ORDER__)
  47. #define BOOST_CHARCONV_ENDIAN_BIG_BYTE (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  48. #define BOOST_CHARCONV_ENDIAN_LITTLE_BYTE (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
  49. #else
  50. #error Could not determine endian type. Please file an issue at https://github.com/cppalliance/charconv with your architecture
  51. #endif // Determine endianness
  52. // Inclue intrinsics if available
  53. #if defined(BOOST_MSVC)
  54. # include <intrin.h>
  55. # if defined(_WIN64)
  56. # define BOOST_CHARCONV_HAS_MSVC_64BIT_INTRINSICS
  57. # else
  58. # define BOOST_CHARCONV_HAS_MSVC_32BIT_INTRINSICS
  59. # endif
  60. #endif
  61. static_assert((BOOST_CHARCONV_ENDIAN_BIG_BYTE || BOOST_CHARCONV_ENDIAN_LITTLE_BYTE) &&
  62. !(BOOST_CHARCONV_ENDIAN_BIG_BYTE && BOOST_CHARCONV_ENDIAN_LITTLE_BYTE),
  63. "Inconsistent endianness detected. Please file an issue at https://github.com/cppalliance/charconv with your architecture");
  64. // Suppress additional buffer overrun check.
  65. // I have no idea why MSVC thinks some functions here are vulnerable to the buffer overrun
  66. // attacks. No, they aren't.
  67. #if defined(__GNUC__) || defined(__clang__)
  68. #define BOOST_CHARCONV_SAFEBUFFERS
  69. #elif defined(_MSC_VER)
  70. #define BOOST_CHARCONV_SAFEBUFFERS __declspec(safebuffers)
  71. #else
  72. #define BOOST_CHARCONV_SAFEBUFFERS
  73. #endif
  74. #if defined(__has_builtin)
  75. #define BOOST_CHARCONV_HAS_BUILTIN(x) __has_builtin(x)
  76. #else
  77. #define BOOST_CHARCONV_HAS_BUILTIN(x) false
  78. #endif
  79. // Workaround for errors in MSVC 14.3 with gotos in if constexpr blocks
  80. #if defined(BOOST_MSVC) && (BOOST_MSVC == 1933 || BOOST_MSVC == 1934)
  81. # define BOOST_CHARCONV_IF_CONSTEXPR if
  82. #else
  83. # define BOOST_CHARCONV_IF_CONSTEXPR BOOST_IF_CONSTEXPR
  84. #endif
  85. // Clang < 4 return type deduction does not work with the policy implementation
  86. #ifndef BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION
  87. # if (defined(__clang__) && __clang_major__ < 4) || (defined(_MSC_VER) && _MSC_VER == 1900)
  88. # define BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
  89. # endif
  90. #elif defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)
  91. # define BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
  92. #endif
  93. // Is constant evaluated detection
  94. #ifdef __cpp_lib_is_constant_evaluated
  95. # define BOOST_CHARCONV_HAS_IS_CONSTANT_EVALUATED
  96. #endif
  97. #ifdef __has_builtin
  98. # if __has_builtin(__builtin_is_constant_evaluated) && !defined(BOOST_NO_CXX14_CONSTEXPR)
  99. # define BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED
  100. # endif
  101. #endif
  102. //
  103. // MSVC also supports __builtin_is_constant_evaluated if it's recent enough:
  104. //
  105. #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326)
  106. # define BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED
  107. #endif
  108. //
  109. // As does GCC-9:
  110. //
  111. #if !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(__GNUC__) && (__GNUC__ >= 9) && !defined(BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED)
  112. # define BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED
  113. #endif
  114. #if defined(BOOST_CHARCONV_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR)
  115. # define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) std::is_constant_evaluated()
  116. #elif defined(BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED)
  117. # define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) __builtin_is_constant_evaluated()
  118. #elif !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(__GNUC__) && (__GNUC__ >= 6)
  119. # define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) __builtin_constant_p(x)
  120. # define BOOST_CHARCONV_USING_BUILTIN_CONSTANT_P
  121. #else
  122. # define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) false
  123. # define BOOST_CHARCONV_NO_CONSTEXPR_DETECTION
  124. #endif
  125. #ifdef BOOST_MSVC
  126. # define BOOST_CHARCONV_ASSUME(expr) __assume(expr)
  127. #elif defined(__clang__)
  128. # define BOOST_CHARCONV_ASSUME(expr) __builtin_assume(expr)
  129. #elif defined(__GNUC__)
  130. # define BOOST_CHARCONV_ASSUME(expr) if (expr) {} else { __builtin_unreachable(); }
  131. #elif defined(__has_cpp_attribute)
  132. # if __has_cpp_attribute(assume)
  133. # define BOOST_CHARCONV_ASSUME(expr) [[assume(expr)]]
  134. # else
  135. # define BOOST_CHARCONV_ASSUME(expr)
  136. # endif
  137. #else
  138. # define BOOST_CHARCONV_ASSUME(expr)
  139. #endif
  140. // Detection for C++23 fixed width floating point types
  141. // All of these types are optional so check for each of them individually
  142. #if (defined(_MSVC_LANG) && _MSVC_LANG > 202002L) || __cplusplus > 202002L
  143. # if __has_include(<stdfloat>)
  144. # include <stdfloat>
  145. # endif
  146. #endif
  147. #ifdef __STDCPP_FLOAT16_T__
  148. # define BOOST_CHARCONV_HAS_FLOAT16
  149. #endif
  150. #ifdef __STDCPP_FLOAT32_T__
  151. # define BOOST_CHARCONV_HAS_FLOAT32
  152. #endif
  153. #ifdef __STDCPP_FLOAT64_T__
  154. # define BOOST_CHARCONV_HAS_FLOAT64
  155. #endif
  156. #ifdef __STDCPP_FLOAT128_T__
  157. # define BOOST_CHARCONV_HAS_STDFLOAT128
  158. #endif
  159. #ifdef __STDCPP_BFLOAT16_T__
  160. # define BOOST_CHARCONV_HAS_BRAINFLOAT16
  161. #endif
  162. #endif // BOOST_CHARCONV_DETAIL_CONFIG_HPP