config.hpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_DETAIL_CONFIG_HPP
  10. #define BOOST_JSON_DETAIL_CONFIG_HPP
  11. #include <boost/config.hpp>
  12. #include <boost/assert.hpp>
  13. #include <boost/throw_exception.hpp>
  14. #include <cstdint>
  15. #include <type_traits>
  16. #include <utility>
  17. // detect 32/64 bit
  18. #if UINTPTR_MAX == UINT64_MAX
  19. # define BOOST_JSON_ARCH 64
  20. #elif UINTPTR_MAX == UINT32_MAX
  21. # define BOOST_JSON_ARCH 32
  22. #else
  23. # error Unknown or unsupported architecture, please open an issue
  24. #endif
  25. // VFALCO Copied from Boost.Config
  26. // This is a derivative work.
  27. #ifndef BOOST_JSON_NODISCARD
  28. # ifdef __has_cpp_attribute
  29. // clang-6 accepts [[nodiscard]] with -std=c++14, but warns about it -pedantic
  30. # if __has_cpp_attribute(nodiscard) && !(defined(__clang__) && (__cplusplus < 201703L))
  31. # define BOOST_JSON_NODISCARD [[nodiscard]]
  32. # else
  33. # define BOOST_JSON_NODISCARD
  34. # endif
  35. # else
  36. # define BOOST_JSON_NODISCARD
  37. # endif
  38. #endif
  39. #ifndef BOOST_JSON_REQUIRE_CONST_INIT
  40. # define BOOST_JSON_REQUIRE_CONST_INIT
  41. # if __cpp_constinit >= 201907L
  42. # undef BOOST_JSON_REQUIRE_CONST_INIT
  43. # define BOOST_JSON_REQUIRE_CONST_INIT constinit
  44. # elif defined(__clang__) && defined(__has_cpp_attribute)
  45. # if __has_cpp_attribute(clang::require_constant_initialization)
  46. # undef BOOST_JSON_REQUIRE_CONST_INIT
  47. # define BOOST_JSON_REQUIRE_CONST_INIT [[clang::require_constant_initialization]]
  48. # endif
  49. # endif
  50. #endif
  51. #ifndef BOOST_JSON_NO_DESTROY
  52. # if defined(__clang__) && defined(__has_cpp_attribute)
  53. # if __has_cpp_attribute(clang::no_destroy)
  54. # define BOOST_JSON_NO_DESTROY [[clang::no_destroy]]
  55. # endif
  56. # endif
  57. #endif
  58. // BOOST_NORETURN ---------------------------------------------//
  59. // Macro to use before a function declaration/definition to designate
  60. // the function as not returning normally (i.e. with a return statement
  61. // or by leaving the function scope, if the function return type is void).
  62. #if !defined(BOOST_NORETURN)
  63. # if defined(_MSC_VER)
  64. # define BOOST_NORETURN __declspec(noreturn)
  65. # elif defined(__GNUC__)
  66. # define BOOST_NORETURN __attribute__ ((__noreturn__))
  67. # elif defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130)
  68. # if __has_attribute(noreturn)
  69. # define BOOST_NORETURN [[noreturn]]
  70. # endif
  71. # elif defined(__has_cpp_attribute)
  72. # if __has_cpp_attribute(noreturn)
  73. # define BOOST_NORETURN [[noreturn]]
  74. # endif
  75. # endif
  76. #endif
  77. #ifndef BOOST_ASSERT
  78. #define BOOST_ASSERT assert
  79. #endif
  80. #ifndef BOOST_STATIC_ASSERT
  81. #define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__)
  82. #endif
  83. #ifndef BOOST_FALLTHROUGH
  84. #define BOOST_FALLTHROUGH [[fallthrough]]
  85. #endif
  86. #ifndef BOOST_FORCEINLINE
  87. # ifdef _MSC_VER
  88. # define BOOST_FORCEINLINE __forceinline
  89. # elif defined(__GNUC__) || defined(__clang__)
  90. # define BOOST_FORCEINLINE inline __attribute__((always_inline))
  91. # else
  92. # define BOOST_FORCEINLINE inline
  93. # endif
  94. #endif
  95. #ifndef BOOST_NOINLINE
  96. # ifdef _MSC_VER
  97. # define BOOST_NOINLINE __declspec(noinline)
  98. # elif defined(__GNUC__) || defined(__clang__)
  99. # define BOOST_NOINLINE __attribute__((noinline))
  100. # else
  101. # define BOOST_NOINLINE
  102. # endif
  103. #endif
  104. #ifndef BOOST_THROW_EXCEPTION
  105. # ifndef BOOST_NO_EXCEPTIONS
  106. # define BOOST_THROW_EXCEPTION(x) throw(x)
  107. # else
  108. # define BOOST_THROW_EXCEPTION(x) do{}while(0)
  109. # endif
  110. #endif
  111. #if ! defined(BOOST_JSON_NO_SSE2) && \
  112. ! defined(BOOST_JSON_USE_SSE2)
  113. # if (defined(_M_IX86) && _M_IX86_FP == 2) || \
  114. defined(_M_X64) || defined(__SSE2__)
  115. # define BOOST_JSON_USE_SSE2
  116. # endif
  117. #endif
  118. #ifndef BOOST_SYMBOL_VISIBLE
  119. #define BOOST_SYMBOL_VISIBLE
  120. #endif
  121. #if defined(BOOST_JSON_DOCS)
  122. # define BOOST_JSON_DECL
  123. #else
  124. # if (defined(BOOST_JSON_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_JSON_STATIC_LINK)
  125. # if defined(BOOST_JSON_SOURCE)
  126. # define BOOST_JSON_DECL BOOST_SYMBOL_EXPORT
  127. # define BOOST_JSON_CLASS_DECL BOOST_SYMBOL_EXPORT
  128. # define BOOST_JSON_BUILD_DLL
  129. # else
  130. # define BOOST_JSON_DECL BOOST_SYMBOL_IMPORT
  131. # define BOOST_JSON_CLASS_DECL BOOST_SYMBOL_IMPORT
  132. # endif
  133. # endif // shared lib
  134. # ifndef BOOST_JSON_DECL
  135. # define BOOST_JSON_DECL
  136. # endif
  137. # if !defined(BOOST_JSON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_JSON_NO_LIB)
  138. # define BOOST_LIB_NAME boost_json
  139. # if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_JSON_DYN_LINK)
  140. # define BOOST_DYN_LINK
  141. # endif
  142. # include <boost/config/auto_link.hpp>
  143. # endif
  144. #endif
  145. #ifndef BOOST_JSON_DECL
  146. #define BOOST_JSON_DECL
  147. #endif
  148. #ifndef BOOST_JSON_CLASS_DECL
  149. #define BOOST_JSON_CLASS_DECL
  150. #endif
  151. #ifndef BOOST_JSON_LIKELY
  152. # if defined(__GNUC__) || defined(__clang__)
  153. # define BOOST_JSON_LIKELY(x) __builtin_expect(!!(x), 1)
  154. # else
  155. # define BOOST_JSON_LIKELY(x) x
  156. # endif
  157. #endif
  158. #ifndef BOOST_JSON_UNLIKELY
  159. # if defined(__GNUC__) || defined(__clang__)
  160. # define BOOST_JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  161. # else
  162. # define BOOST_JSON_UNLIKELY(x) x
  163. # endif
  164. #endif
  165. #ifndef BOOST_JSON_UNREACHABLE
  166. # ifdef _MSC_VER
  167. # define BOOST_JSON_UNREACHABLE() __assume(0)
  168. # elif defined(__GNUC__) || defined(__clang__)
  169. # define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
  170. # elif defined(__has_builtin)
  171. # if __has_builtin(__builtin_unreachable)
  172. # define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
  173. # endif
  174. # else
  175. # define BOOST_JSON_UNREACHABLE() static_cast<void>(0)
  176. # endif
  177. #endif
  178. #ifndef BOOST_JSON_ASSUME
  179. # define BOOST_JSON_ASSUME(x) (!!(x) ? void() : BOOST_JSON_UNREACHABLE())
  180. # ifdef _MSC_VER
  181. # undef BOOST_JSON_ASSUME
  182. # define BOOST_JSON_ASSUME(x) __assume(!!(x))
  183. # elif defined(__has_builtin)
  184. # if __has_builtin(__builtin_assume)
  185. # undef BOOST_JSON_ASSUME
  186. # define BOOST_JSON_ASSUME(x) __builtin_assume(!!(x))
  187. # endif
  188. # endif
  189. #endif
  190. // older versions of msvc and clang don't always
  191. // constant initialize when they are supposed to
  192. #ifndef BOOST_JSON_WEAK_CONSTINIT
  193. # if defined(_MSC_VER) && ! defined(__clang__) && _MSC_VER < 1920
  194. # define BOOST_JSON_WEAK_CONSTINIT
  195. # elif defined(__clang__) && __clang_major__ < 4
  196. # define BOOST_JSON_WEAK_CONSTINIT
  197. # endif
  198. #endif
  199. // These macros are private, for tests, do not change
  200. // them or else previously built libraries won't match.
  201. #ifndef BOOST_JSON_MAX_STRING_SIZE
  202. # define BOOST_JSON_NO_MAX_STRING_SIZE
  203. # define BOOST_JSON_MAX_STRING_SIZE 0x7ffffffe
  204. #endif
  205. #ifndef BOOST_JSON_MAX_STRUCTURED_SIZE
  206. # define BOOST_JSON_NO_MAX_STRUCTURED_SIZE
  207. # define BOOST_JSON_MAX_STRUCTURED_SIZE 0x7ffffffe
  208. #endif
  209. #ifndef BOOST_JSON_STACK_BUFFER_SIZE
  210. # define BOOST_JSON_NO_STACK_BUFFER_SIZE
  211. # if defined(__i386__) || defined(__x86_64__) || \
  212. defined(_M_IX86) || defined(_M_X64)
  213. # define BOOST_JSON_STACK_BUFFER_SIZE 4096
  214. # else
  215. // If we are not on Intel, then assume we are on
  216. // embedded and use a smaller stack size. If this
  217. // is not suitable, the user can define the macro
  218. // themselves when building the library or including
  219. // src.hpp.
  220. # define BOOST_JSON_STACK_BUFFER_SIZE 256
  221. # endif
  222. #endif
  223. #if ! defined(BOOST_JSON_BIG_ENDIAN) && ! defined(BOOST_JSON_LITTLE_ENDIAN)
  224. // Copied from Boost.Endian
  225. # if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  226. # define BOOST_JSON_LITTLE_ENDIAN
  227. # elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  228. # define BOOST_JSON_BIG_ENDIAN
  229. # elif defined(__LITTLE_ENDIAN__)
  230. # define BOOST_JSON_LITTLE_ENDIAN
  231. # elif defined(__BIG_ENDIAN__)
  232. # define BOOST_JSON_BIG_ENDIAN
  233. # elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__)
  234. # define BOOST_JSON_LITTLE_ENDIAN
  235. # else
  236. # error The Boost.JSON library could not determine the endianness of this platform. Define either BOOST_JSON_BIG_ENDIAN or BOOST_JSON_LITTLE_ENDIAN.
  237. # endif
  238. #endif
  239. namespace boost {
  240. namespace json {
  241. namespace detail {
  242. template<class...>
  243. struct make_void
  244. {
  245. using type =void;
  246. };
  247. template<class... Ts>
  248. using void_t = typename
  249. make_void<Ts...>::type;
  250. template<class T>
  251. using remove_cvref = typename
  252. std::remove_cv<typename
  253. std::remove_reference<T>::type>::type;
  254. template<class T, class U>
  255. T exchange(T& t, U u) noexcept
  256. {
  257. T v = std::move(t);
  258. t = std::move(u);
  259. return v;
  260. }
  261. /* This is a derivative work, original copyright:
  262. Copyright Eric Niebler 2013-present
  263. Use, modification and distribution is subject to the
  264. Boost Software License, Version 1.0. (See accompanying
  265. file LICENSE_1_0.txt or copy at
  266. http://www.boost.org/LICENSE_1_0.txt)
  267. Project home: https://github.com/ericniebler/range-v3
  268. */
  269. template<typename T>
  270. struct static_const
  271. {
  272. static constexpr T value {};
  273. };
  274. template<typename T>
  275. constexpr T static_const<T>::value;
  276. #define BOOST_JSON_INLINE_VARIABLE(name, type) \
  277. namespace { constexpr auto& name = \
  278. ::boost::json::detail::static_const<type>::value; \
  279. } struct _unused_ ## name ## _semicolon_bait_
  280. } // detail
  281. } // namespace json
  282. } // namespace boost
  283. #endif