config.hpp 8.7 KB

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