Line data Source code
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_VALUE_HPP
11 : #define BOOST_JSON_DETAIL_VALUE_HPP
12 :
13 : #include <boost/json/fwd.hpp>
14 : #include <boost/json/kind.hpp>
15 : #include <boost/json/storage_ptr.hpp>
16 : #include <cstdint>
17 : #include <limits>
18 : #include <new>
19 : #include <utility>
20 :
21 : namespace boost {
22 : namespace json {
23 : namespace detail {
24 :
25 : struct key_t
26 : {
27 : };
28 :
29 : #if 0
30 : template<class T>
31 : struct to_number_limit
32 : : std::numeric_limits<T>
33 : {
34 : };
35 :
36 : template<class T>
37 : struct to_number_limit<T const>
38 : : to_number_limit<T>
39 : {
40 : };
41 :
42 : template<>
43 : struct to_number_limit<long long>
44 : {
45 : static constexpr long long (min)() noexcept
46 : {
47 : return -9223372036854774784;
48 : }
49 :
50 : static constexpr long long (max)() noexcept
51 : {
52 : return 9223372036854774784;
53 : }
54 : };
55 :
56 : template<>
57 : struct to_number_limit<unsigned long long>
58 : {
59 : static constexpr
60 : unsigned long long (min)() noexcept
61 : {
62 : return 0;
63 : }
64 :
65 : static constexpr
66 : unsigned long long (max)() noexcept
67 : {
68 : return 18446744073709549568ULL;
69 : }
70 : };
71 : #else
72 :
73 : template<class T>
74 : class to_number_limit
75 : {
76 : // unsigned
77 :
78 : static constexpr
79 : double min1(std::false_type)
80 : {
81 : return 0.0;
82 : }
83 :
84 : static constexpr
85 8 : double max1(std::false_type)
86 : {
87 8 : return max2u(std::integral_constant<
88 : bool, (std::numeric_limits<T>::max)() ==
89 8 : UINT64_MAX>{});
90 : }
91 :
92 : static constexpr
93 6 : double max2u(std::false_type)
94 : {
95 : return static_cast<double>(
96 6 : (std::numeric_limits<T>::max)());
97 : }
98 :
99 : static constexpr
100 2 : double max2u(std::true_type)
101 : {
102 2 : return 18446744073709549568.0;
103 : }
104 :
105 : // signed
106 :
107 : static constexpr
108 20 : double min1(std::true_type)
109 : {
110 20 : return min2s(std::integral_constant<
111 : bool, (std::numeric_limits<T>::max)() ==
112 20 : INT64_MAX>{});
113 : }
114 :
115 : static constexpr
116 17 : double min2s(std::false_type)
117 : {
118 : return static_cast<double>(
119 17 : (std::numeric_limits<T>::min)());
120 : }
121 :
122 : static constexpr
123 3 : double min2s(std::true_type)
124 : {
125 3 : return -9223372036854774784.0;
126 : }
127 :
128 : static constexpr
129 20 : double max1(std::true_type)
130 : {
131 20 : return max2s(std::integral_constant<
132 : bool, (std::numeric_limits<T>::max)() ==
133 20 : INT64_MAX>{});
134 : }
135 :
136 : static constexpr
137 17 : double max2s(std::false_type)
138 : {
139 : return static_cast<double>(
140 17 : (std::numeric_limits<T>::max)());
141 : }
142 :
143 : static constexpr
144 3 : double max2s(std::true_type)
145 : {
146 3 : return 9223372036854774784.0;
147 : }
148 :
149 : public:
150 : static constexpr
151 20 : double (min)() noexcept
152 : {
153 20 : return min1(std::is_signed<T>{});
154 : }
155 :
156 : static constexpr
157 28 : double (max)() noexcept
158 : {
159 28 : return max1(std::is_signed<T>{});
160 : }
161 : };
162 :
163 : #endif
164 :
165 : struct scalar
166 : {
167 : storage_ptr sp; // must come first
168 : kind k; // must come second
169 : union
170 : {
171 : std::nullptr_t n;
172 : bool b;
173 : std::int64_t i;
174 : std::uint64_t u;
175 : double d;
176 : };
177 :
178 : explicit
179 2151977 : scalar(storage_ptr sp_ = {}) noexcept
180 2151977 : : sp(std::move(sp_))
181 2151977 : , k(json::kind::null)
182 2151977 : , n()
183 : {
184 2151977 : }
185 :
186 : explicit
187 1085 : scalar(bool b_,
188 : storage_ptr sp_ = {}) noexcept
189 1085 : : sp(std::move(sp_))
190 1085 : , k(json::kind::bool_)
191 1085 : , b(b_)
192 : {
193 1085 : }
194 :
195 : explicit
196 34532 : scalar(std::int64_t i_,
197 : storage_ptr sp_ = {}) noexcept
198 34532 : : sp(std::move(sp_))
199 34532 : , k(json::kind::int64)
200 34532 : , i(i_)
201 : {
202 34532 : }
203 :
204 : explicit
205 406 : scalar(std::uint64_t u_,
206 : storage_ptr sp_ = {}) noexcept
207 406 : : sp(std::move(sp_))
208 406 : , k(json::kind::uint64)
209 406 : , u(u_)
210 : {
211 406 : }
212 :
213 : explicit
214 2040002 : scalar(double d_,
215 : storage_ptr sp_ = {}) noexcept
216 2040002 : : sp(std::move(sp_))
217 2040002 : , k(json::kind::double_)
218 2040002 : , d(d_)
219 : {
220 2040002 : }
221 : };
222 :
223 : struct access
224 : {
225 : template<class Value, class... Args>
226 : static
227 : Value&
228 2156934 : construct_value(Value* p, Args&&... args)
229 : {
230 : return *reinterpret_cast<
231 6396945 : Value*>(::new(p) Value(
232 6489244 : std::forward<Args>(args)...));
233 : }
234 :
235 : template<class KeyValuePair, class... Args>
236 : static
237 : KeyValuePair&
238 38150 : construct_key_value_pair(
239 : KeyValuePair* p, Args&&... args)
240 : {
241 : return *reinterpret_cast<
242 38150 : KeyValuePair*>(::new(p)
243 : KeyValuePair(
244 76300 : std::forward<Args>(args)...));
245 : }
246 :
247 : template<class Value>
248 : static
249 : char const*
250 38150 : release_key(
251 : Value& jv,
252 : std::size_t& len) noexcept
253 : {
254 38150 : BOOST_ASSERT(jv.is_string());
255 38150 : jv.str_.sp_.~storage_ptr();
256 38150 : return jv.str_.impl_.release_key(len);
257 : }
258 :
259 : using index_t = std::uint32_t;
260 :
261 : template<class KeyValuePair>
262 : static
263 : index_t&
264 10983 : next(KeyValuePair& e) noexcept
265 : {
266 10983 : return e.next_;
267 : }
268 :
269 : template<class KeyValuePair>
270 : static
271 : index_t const&
272 : next(KeyValuePair const& e) noexcept
273 : {
274 : return e.next_;
275 : }
276 :
277 : template<class Value>
278 : static
279 : auto
280 26 : get_scalar(Value& jv) -> scalar&
281 : {
282 26 : return jv.sca_;
283 : }
284 :
285 : template<class Value>
286 : static
287 : auto
288 257 : get_scalar(Value const& jv) -> scalar const&
289 : {
290 257 : return jv.sca_;
291 : }
292 : };
293 :
294 : BOOST_JSON_DECL
295 : std::size_t
296 : hash_value_impl( value const& jv ) noexcept;
297 :
298 : } // detail
299 : } // namespace json
300 : } // namespace boost
301 :
302 : #endif
|