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