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/throw_exception.hpp>
16  
#include <boost/throw_exception.hpp>
17  
#include <cstdint>
17  
#include <cstdint>
18  
#include <type_traits>
18  
#include <type_traits>
19  
#include <utility>
19  
#include <utility>
20  

20  

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

29  

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

42  

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

50  

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

58  

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

80  

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

84  

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

88  

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

102  

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

115  

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

125  

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

150  

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

163  

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

167  

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

173  

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

177  

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

182  

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

190  

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

192  

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

194  

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

199  

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

209  

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

214  

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

218  

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

224  

225  
#if defined(BOOST_GCC) && BOOST_GCC < 50000 && !defined(BOOST_JSON_ALLOW_DEPRECATED)
225  
#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."
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  
#endif
227  
#endif
228  

228  

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

234  

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

238  

239  
#endif
239  
#endif