1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/json
7  
// Official repository: https://github.com/boostorg/json
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_JSON_DETAIL_CONFIG_HPP
10  
#ifndef BOOST_JSON_DETAIL_CONFIG_HPP
11  
#define BOOST_JSON_DETAIL_CONFIG_HPP
11  
#define BOOST_JSON_DETAIL_CONFIG_HPP
12  

12  

13  
#include <boost/config.hpp>
13  
#include <boost/config.hpp>
14  
#include <boost/config/pragma_message.hpp>
14  
#include <boost/config/pragma_message.hpp>
15  
#include <boost/assert.hpp>
15  
#include <boost/assert.hpp>
 
16 +
#include <boost/static_assert.hpp>
16  
#include <boost/throw_exception.hpp>
17  
#include <boost/throw_exception.hpp>
17  
#include <cstdint>
18  
#include <cstdint>
18  
#include <type_traits>
19  
#include <type_traits>
19  
#include <utility>
20  
#include <utility>
20  

21  

21  
// detect 32/64 bit
22  
// detect 32/64 bit
22  
#if UINTPTR_MAX == UINT64_MAX
23  
#if UINTPTR_MAX == UINT64_MAX
23  
# define BOOST_JSON_ARCH 64
24  
# define BOOST_JSON_ARCH 64
24  
#elif UINTPTR_MAX == UINT32_MAX
25  
#elif UINTPTR_MAX == UINT32_MAX
25  
# define BOOST_JSON_ARCH 32
26  
# define BOOST_JSON_ARCH 32
26  
#else
27  
#else
27  
# error Unknown or unsupported architecture, please open an issue
28  
# error Unknown or unsupported architecture, please open an issue
28  
#endif
29  
#endif
29  

30  

30  
#ifndef BOOST_JSON_REQUIRE_CONST_INIT
31  
#ifndef BOOST_JSON_REQUIRE_CONST_INIT
31  
# define BOOST_JSON_REQUIRE_CONST_INIT
32  
# define BOOST_JSON_REQUIRE_CONST_INIT
32  
# if __cpp_constinit >= 201907L
33  
# if __cpp_constinit >= 201907L
33  
#  undef BOOST_JSON_REQUIRE_CONST_INIT
34  
#  undef BOOST_JSON_REQUIRE_CONST_INIT
34  
#  define BOOST_JSON_REQUIRE_CONST_INIT constinit
35  
#  define BOOST_JSON_REQUIRE_CONST_INIT constinit
35  
# elif defined(__clang__) && defined(__has_cpp_attribute)
36  
# elif defined(__clang__) && defined(__has_cpp_attribute)
36  
#  if __has_cpp_attribute(clang::require_constant_initialization)
37  
#  if __has_cpp_attribute(clang::require_constant_initialization)
37  
#   undef BOOST_JSON_REQUIRE_CONST_INIT
38  
#   undef BOOST_JSON_REQUIRE_CONST_INIT
38  
#   define BOOST_JSON_REQUIRE_CONST_INIT [[clang::require_constant_initialization]]
39  
#   define BOOST_JSON_REQUIRE_CONST_INIT [[clang::require_constant_initialization]]
39  
#  endif
40  
#  endif
40  
# endif
41  
# endif
41  
#endif
42  
#endif
42  

43  

43  
#ifndef BOOST_JSON_NO_DESTROY
44  
#ifndef BOOST_JSON_NO_DESTROY
44  
# if defined(__clang__) && defined(__has_cpp_attribute)
45  
# if defined(__clang__) && defined(__has_cpp_attribute)
45  
#  if __has_cpp_attribute(clang::no_destroy)
46  
#  if __has_cpp_attribute(clang::no_destroy)
46  
#   define BOOST_JSON_NO_DESTROY [[clang::no_destroy]]
47  
#   define BOOST_JSON_NO_DESTROY [[clang::no_destroy]]
47  
#  endif
48  
#  endif
48  
# endif
49  
# endif
49  
#endif
50  
#endif
50  

51  

51  
#if ! defined(BOOST_JSON_NO_SSE2) && \
52  
#if ! defined(BOOST_JSON_NO_SSE2) && \
52  
    ! defined(BOOST_JSON_USE_SSE2)
53  
    ! defined(BOOST_JSON_USE_SSE2)
53  
# if (defined(_M_IX86) && _M_IX86_FP == 2) || \
54  
# if (defined(_M_IX86) && _M_IX86_FP == 2) || \
54  
      defined(_M_X64) || defined(__SSE2__)
55  
      defined(_M_X64) || defined(__SSE2__)
55  
#  define BOOST_JSON_USE_SSE2
56  
#  define BOOST_JSON_USE_SSE2
56  
# endif
57  
# endif
57  
#endif
58  
#endif
58  

59  

59  
#if defined(BOOST_JSON_DOCS)
60  
#if defined(BOOST_JSON_DOCS)
60  
# define BOOST_JSON_DECL
61  
# define BOOST_JSON_DECL
61  
#else
62  
#else
62  
# if (defined(BOOST_JSON_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_JSON_STATIC_LINK)
63  
# if (defined(BOOST_JSON_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_JSON_STATIC_LINK)
63  
#  if defined(BOOST_JSON_SOURCE)
64  
#  if defined(BOOST_JSON_SOURCE)
64  
#   define BOOST_JSON_DECL        BOOST_SYMBOL_EXPORT
65  
#   define BOOST_JSON_DECL        BOOST_SYMBOL_EXPORT
65  
#  else
66  
#  else
66  
#   define BOOST_JSON_DECL        BOOST_SYMBOL_IMPORT
67  
#   define BOOST_JSON_DECL        BOOST_SYMBOL_IMPORT
67  
#  endif
68  
#  endif
68  
# endif // shared lib
69  
# endif // shared lib
69  
# ifndef  BOOST_JSON_DECL
70  
# ifndef  BOOST_JSON_DECL
70  
#  define BOOST_JSON_DECL
71  
#  define BOOST_JSON_DECL
71  
# endif
72  
# endif
72  
# if !defined(BOOST_JSON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_JSON_NO_LIB)
73  
# if !defined(BOOST_JSON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_JSON_NO_LIB)
73  
#  define BOOST_LIB_NAME boost_json
74  
#  define BOOST_LIB_NAME boost_json
74  
#  if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_JSON_DYN_LINK)
75  
#  if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_JSON_DYN_LINK)
75  
#   define BOOST_DYN_LINK
76  
#   define BOOST_DYN_LINK
76  
#  endif
77  
#  endif
77  
#  include <boost/config/auto_link.hpp>
78  
#  include <boost/config/auto_link.hpp>
78  
# endif
79  
# endif
79  
#endif
80  
#endif
80  

81  

81  
#ifndef BOOST_JSON_LIKELY
82  
#ifndef BOOST_JSON_LIKELY
82  
# define BOOST_JSON_LIKELY(x) BOOST_LIKELY( !!(x) )
83  
# define BOOST_JSON_LIKELY(x) BOOST_LIKELY( !!(x) )
83  
#endif
84  
#endif
84  

85  

85  
#ifndef BOOST_JSON_UNLIKELY
86  
#ifndef BOOST_JSON_UNLIKELY
86  
# define BOOST_JSON_UNLIKELY(x) BOOST_UNLIKELY( !!(x) )
87  
# define BOOST_JSON_UNLIKELY(x) BOOST_UNLIKELY( !!(x) )
87  
#endif
88  
#endif
88  

89  

89  
#ifndef BOOST_JSON_UNREACHABLE
90  
#ifndef BOOST_JSON_UNREACHABLE
90  
# ifdef _MSC_VER
91  
# ifdef _MSC_VER
91  
#  define BOOST_JSON_UNREACHABLE() __assume(0)
92  
#  define BOOST_JSON_UNREACHABLE() __assume(0)
92  
# elif defined(__GNUC__) || defined(__clang__)
93  
# elif defined(__GNUC__) || defined(__clang__)
93  
#  define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
94  
#  define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
94  
# elif defined(__has_builtin)
95  
# elif defined(__has_builtin)
95  
#  if __has_builtin(__builtin_unreachable)
96  
#  if __has_builtin(__builtin_unreachable)
96  
#   define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
97  
#   define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
97  
#  endif
98  
#  endif
98  
# else
99  
# else
99  
#  define BOOST_JSON_UNREACHABLE() static_cast<void>(0)
100  
#  define BOOST_JSON_UNREACHABLE() static_cast<void>(0)
100  
# endif
101  
# endif
101  
#endif
102  
#endif
102  

103  

103  
#ifndef BOOST_JSON_ASSUME
104  
#ifndef BOOST_JSON_ASSUME
104  
# define BOOST_JSON_ASSUME(x) (!!(x) ? void() : BOOST_JSON_UNREACHABLE())
105  
# define BOOST_JSON_ASSUME(x) (!!(x) ? void() : BOOST_JSON_UNREACHABLE())
105  
# ifdef _MSC_VER
106  
# ifdef _MSC_VER
106  
#  undef BOOST_JSON_ASSUME
107  
#  undef BOOST_JSON_ASSUME
107  
#  define BOOST_JSON_ASSUME(x) __assume(!!(x))
108  
#  define BOOST_JSON_ASSUME(x) __assume(!!(x))
108  
# elif defined(__has_builtin)
109  
# elif defined(__has_builtin)
109  
#  if __has_builtin(__builtin_assume)
110  
#  if __has_builtin(__builtin_assume)
110  
#   undef BOOST_JSON_ASSUME
111  
#   undef BOOST_JSON_ASSUME
111  
#   define BOOST_JSON_ASSUME(x) __builtin_assume(!!(x))
112  
#   define BOOST_JSON_ASSUME(x) __builtin_assume(!!(x))
112  
#  endif
113  
#  endif
113  
# endif
114  
# endif
114  
#endif
115  
#endif
115  

116  

116  
// older versions of msvc and clang don't always
117  
// older versions of msvc and clang don't always
117  
// constant initialize when they are supposed to
118  
// constant initialize when they are supposed to
118  
#ifndef BOOST_JSON_WEAK_CONSTINIT
119  
#ifndef BOOST_JSON_WEAK_CONSTINIT
119  
# if defined(_MSC_VER) && ! defined(__clang__) && _MSC_VER < 1920
120  
# if defined(_MSC_VER) && ! defined(__clang__) && _MSC_VER < 1920
120  
#  define BOOST_JSON_WEAK_CONSTINIT
121  
#  define BOOST_JSON_WEAK_CONSTINIT
121  
# elif defined(__clang__) && __clang_major__ < 4
122  
# elif defined(__clang__) && __clang_major__ < 4
122  
#  define BOOST_JSON_WEAK_CONSTINIT
123  
#  define BOOST_JSON_WEAK_CONSTINIT
123  
# endif
124  
# endif
124  
#endif
125  
#endif
125  

126  

126  
// These macros are private, for tests, do not change
127  
// These macros are private, for tests, do not change
127  
// them or else previously built libraries won't match.
128  
// them or else previously built libraries won't match.
128  
#ifndef  BOOST_JSON_MAX_STRING_SIZE
129  
#ifndef  BOOST_JSON_MAX_STRING_SIZE
129  
# define BOOST_JSON_NO_MAX_STRING_SIZE
130  
# define BOOST_JSON_NO_MAX_STRING_SIZE
130  
# define BOOST_JSON_MAX_STRING_SIZE  0x7ffffffe
131  
# define BOOST_JSON_MAX_STRING_SIZE  0x7ffffffe
131  
#endif
132  
#endif
132  
#ifndef  BOOST_JSON_MAX_STRUCTURED_SIZE
133  
#ifndef  BOOST_JSON_MAX_STRUCTURED_SIZE
133  
# define BOOST_JSON_NO_MAX_STRUCTURED_SIZE
134  
# define BOOST_JSON_NO_MAX_STRUCTURED_SIZE
134  
# define BOOST_JSON_MAX_STRUCTURED_SIZE  0x7ffffffe
135  
# define BOOST_JSON_MAX_STRUCTURED_SIZE  0x7ffffffe
135  
#endif
136  
#endif
136  
#ifndef  BOOST_JSON_STACK_BUFFER_SIZE
137  
#ifndef  BOOST_JSON_STACK_BUFFER_SIZE
137  
# define BOOST_JSON_NO_STACK_BUFFER_SIZE
138  
# define BOOST_JSON_NO_STACK_BUFFER_SIZE
138  
# if defined(__i386__) || defined(__x86_64__) || \
139  
# if defined(__i386__) || defined(__x86_64__) || \
139  
     defined(_M_IX86)  || defined(_M_X64)
140  
     defined(_M_IX86)  || defined(_M_X64)
140  
#  define BOOST_JSON_STACK_BUFFER_SIZE 4096
141  
#  define BOOST_JSON_STACK_BUFFER_SIZE 4096
141  
# else
142  
# else
142  
// If we are not on Intel, then assume we are on
143  
// If we are not on Intel, then assume we are on
143  
// embedded and use a smaller stack size. If this
144  
// embedded and use a smaller stack size. If this
144  
// is not suitable, the user can define the macro
145  
// is not suitable, the user can define the macro
145  
// themselves when building the library or including
146  
// themselves when building the library or including
146  
// src.hpp.
147  
// src.hpp.
147  
#  define BOOST_JSON_STACK_BUFFER_SIZE 256
148  
#  define BOOST_JSON_STACK_BUFFER_SIZE 256
148  
# endif
149  
# endif
149  
#endif
150  
#endif
150  

151  

151  
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
152  
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
152  
# define BOOST_JSON_CONSTINIT constinit
153  
# define BOOST_JSON_CONSTINIT constinit
153  
#elif defined(__has_cpp_attribute) && defined(__clang__)
154  
#elif defined(__has_cpp_attribute) && defined(__clang__)
154  
# if __has_cpp_attribute(clang::require_constant_initialization)
155  
# if __has_cpp_attribute(clang::require_constant_initialization)
155  
#  define BOOST_JSON_CONSTINIT [[clang::require_constant_initialization]]
156  
#  define BOOST_JSON_CONSTINIT [[clang::require_constant_initialization]]
156  
# endif
157  
# endif
157  
#elif defined(__GNUC__) && (__GNUC__ >= 10)
158  
#elif defined(__GNUC__) && (__GNUC__ >= 10)
158  
# define BOOST_JSON_CONSTINIT __constinit
159  
# define BOOST_JSON_CONSTINIT __constinit
159  
#endif
160  
#endif
160  
#ifndef BOOST_JSON_CONSTINIT
161  
#ifndef BOOST_JSON_CONSTINIT
161  
# define BOOST_JSON_CONSTINIT
162  
# define BOOST_JSON_CONSTINIT
162  
#endif
163  
#endif
163  

164  

164  
namespace boost {
165  
namespace boost {
165  
namespace json {
166  
namespace json {
166  
namespace detail {
167  
namespace detail {
167  

168  

168  
template<class...>
169  
template<class...>
169  
struct make_void
170  
struct make_void
170  
{
171  
{
171  
    using type =void;
172  
    using type =void;
172  
};
173  
};
173  

174  

174  
template<class... Ts>
175  
template<class... Ts>
175  
using void_t = typename
176  
using void_t = typename
176  
    make_void<Ts...>::type;
177  
    make_void<Ts...>::type;
177  

178  

178  
template<class T>
179  
template<class T>
179  
using remove_cvref = typename
180  
using remove_cvref = typename
180  
    std::remove_cv<typename
181  
    std::remove_cv<typename
181  
        std::remove_reference<T>::type>::type;
182  
        std::remove_reference<T>::type>::type;
182  

183  

183  
template<class T, class U>
184  
template<class T, class U>
184  
T exchange(T& t, U u) noexcept
185  
T exchange(T& t, U u) noexcept
185  
{
186  
{
186  
    T v = std::move(t);
187  
    T v = std::move(t);
187  
    t = std::move(u);
188  
    t = std::move(u);
188  
    return v;
189  
    return v;
189  
}
190  
}
190  

191  

191  
/*  This is a derivative work, original copyright:
192  
/*  This is a derivative work, original copyright:
192  

193  

193  
    Copyright Eric Niebler 2013-present
194  
    Copyright Eric Niebler 2013-present
194  

195  

195  
    Use, modification and distribution is subject to the
196  
    Use, modification and distribution is subject to the
196  
    Boost Software License, Version 1.0. (See accompanying
197  
    Boost Software License, Version 1.0. (See accompanying
197  
    file LICENSE_1_0.txt or copy at
198  
    file LICENSE_1_0.txt or copy at
198  
    http://www.boost.org/LICENSE_1_0.txt)
199  
    http://www.boost.org/LICENSE_1_0.txt)
199  

200  

200  
    Project home: https://github.com/ericniebler/range-v3
201  
    Project home: https://github.com/ericniebler/range-v3
201  
*/
202  
*/
202  
template<typename T>
203  
template<typename T>
203  
struct static_const
204  
struct static_const
204  
{
205  
{
205  
    static constexpr T value {};
206  
    static constexpr T value {};
206  
};
207  
};
207  
template<typename T>
208  
template<typename T>
208  
constexpr T static_const<T>::value;
209  
constexpr T static_const<T>::value;
209  

210  

210  
#define BOOST_JSON_INLINE_VARIABLE(name, type) \
211  
#define BOOST_JSON_INLINE_VARIABLE(name, type) \
211  
    namespace { constexpr auto& name = \
212  
    namespace { constexpr auto& name = \
212  
        ::boost::json::detail::static_const<type>::value; \
213  
        ::boost::json::detail::static_const<type>::value; \
213  
    } struct _unused_ ## name ## _semicolon_bait_
214  
    } struct _unused_ ## name ## _semicolon_bait_
214  

215  

215  
} // detail
216  
} // detail
216  
} // namespace json
217  
} // namespace json
217  
} // namespace boost
218  
} // namespace boost
218  

219  

219  
#ifndef BOOST_JSON_ALLOW_DEPRECATED
220  
#ifndef BOOST_JSON_ALLOW_DEPRECATED
220  
# ifdef BOOST_ALLOW_DEPRECATED
221  
# ifdef BOOST_ALLOW_DEPRECATED
221  
#  define BOOST_JSON_ALLOW_DEPRECATED
222  
#  define BOOST_JSON_ALLOW_DEPRECATED
222  
# endif
223  
# endif
223  
#endif
224  
#endif
224  

225  

225  
#if defined(BOOST_GCC) && BOOST_GCC < 50000 && !defined(BOOST_JSON_ALLOW_DEPRECATED)
226  
#if defined(BOOST_GCC) && BOOST_GCC < 50000 && !defined(BOOST_JSON_ALLOW_DEPRECATED)
226  
# pragma GCC warning "Support for GCC versions below 5.0 is deprecated and will stop in Boost 1.88.0. To suppress this message define macro BOOST_JSON_ALLOW_DEPRECATED."
227  
# pragma GCC warning "Support for GCC versions below 5.0 is deprecated and will stop in Boost 1.88.0. To suppress this message define macro BOOST_JSON_ALLOW_DEPRECATED."
227  
#endif
228  
#endif
228  

229  

229  
#ifndef BOOST_JSON_ALLOW_DEPRECATED
230  
#ifndef BOOST_JSON_ALLOW_DEPRECATED
230  
# define BOOST_JSON_DEPRECATED(x) BOOST_DEPRECATED(x)
231  
# define BOOST_JSON_DEPRECATED(x) BOOST_DEPRECATED(x)
231  
#else
232  
#else
232  
# define BOOST_JSON_DEPRECATED(x)
233  
# define BOOST_JSON_DEPRECATED(x)
233  
#endif
234  
#endif
234  

235  

235  
#ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS
236  
#ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS
236  
#include <boost/json/detail/gdb_printers.hpp>
237  
#include <boost/json/detail/gdb_printers.hpp>
237  
#endif
238  
#endif
238  

239  

239  
#endif
240  
#endif