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 : bool b;
172 : std::int64_t i;
173 : std::uint64_t u;
174 : double d;
175 : };
176 :
177 : explicit
178 2152021 : scalar(storage_ptr sp_ = {}) noexcept
179 2152021 : : sp(std::move(sp_))
180 2152021 : , k(json::kind::null)
181 : {
182 2152021 : }
183 :
184 : explicit
185 1085 : scalar(bool b_,
186 : storage_ptr sp_ = {}) noexcept
187 1085 : : sp(std::move(sp_))
188 1085 : , k(json::kind::bool_)
189 1085 : , b(b_)
190 : {
191 1085 : }
192 :
193 : explicit
194 34607 : scalar(std::int64_t i_,
195 : storage_ptr sp_ = {}) noexcept
196 34607 : : sp(std::move(sp_))
197 34607 : , k(json::kind::int64)
198 34607 : , i(i_)
199 : {
200 34607 : }
201 :
202 : explicit
203 406 : scalar(std::uint64_t u_,
204 : storage_ptr sp_ = {}) noexcept
205 406 : : sp(std::move(sp_))
206 406 : , k(json::kind::uint64)
207 406 : , u(u_)
208 : {
209 406 : }
210 :
211 : explicit
212 2040002 : scalar(double d_,
213 : storage_ptr sp_ = {}) noexcept
214 2040002 : : sp(std::move(sp_))
215 2040002 : , k(json::kind::double_)
216 2040002 : , d(d_)
217 : {
218 2040002 : }
219 : };
220 :
221 : struct access
222 : {
223 : template<class Value, class... Args>
224 : static
225 : Value&
226 2156934 : construct_value(Value* p, Args&&... args)
227 : {
228 : return *reinterpret_cast<
229 6396945 : Value*>(::new(p) Value(
230 6489244 : std::forward<Args>(args)...));
231 : }
232 :
233 : template<class KeyValuePair, class... Args>
234 : static
235 : KeyValuePair&
236 38150 : construct_key_value_pair(
237 : KeyValuePair* p, Args&&... args)
238 : {
239 : return *reinterpret_cast<
240 38150 : KeyValuePair*>(::new(p)
241 : KeyValuePair(
242 76300 : std::forward<Args>(args)...));
243 : }
244 :
245 : template<class Value>
246 : static
247 : char const*
248 38150 : release_key(
249 : Value& jv,
250 : std::size_t& len) noexcept
251 : {
252 38150 : BOOST_ASSERT(jv.is_string());
253 38150 : jv.str_.sp_.~storage_ptr();
254 38150 : return jv.str_.impl_.release_key(len);
255 : }
256 :
257 : using index_t = std::uint32_t;
258 :
259 : template<class KeyValuePair>
260 : static
261 : index_t&
262 9717 : next(KeyValuePair& e) noexcept
263 : {
264 9717 : return e.next_;
265 : }
266 :
267 : template<class KeyValuePair>
268 : static
269 : index_t const&
270 : next(KeyValuePair const& e) noexcept
271 : {
272 : return e.next_;
273 : }
274 : };
275 :
276 : BOOST_JSON_DECL
277 : std::size_t
278 : hash_value_impl( value const& jv ) noexcept;
279 :
280 : } // detail
281 : } // namespace json
282 : } // namespace boost
283 :
284 : #endif
|