/src/boost/boost/json/detail/value.hpp
Line | Count | Source |
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 | | double max1(std::false_type) |
86 | | { |
87 | | return max2u(std::integral_constant< |
88 | | bool, (std::numeric_limits<T>::max)() == |
89 | | UINT64_MAX>{}); |
90 | | } |
91 | | |
92 | | static constexpr |
93 | | double max2u(std::false_type) |
94 | | { |
95 | | return static_cast<double>( |
96 | | (std::numeric_limits<T>::max)()); |
97 | | } |
98 | | |
99 | | static constexpr |
100 | | double max2u(std::true_type) |
101 | | { |
102 | | return 18446744073709549568.0; |
103 | | } |
104 | | |
105 | | // signed |
106 | | |
107 | | static constexpr |
108 | | double min1(std::true_type) |
109 | | { |
110 | | return min2s(std::integral_constant< |
111 | | bool, (std::numeric_limits<T>::max)() == |
112 | | INT64_MAX>{}); |
113 | | } |
114 | | |
115 | | static constexpr |
116 | | double min2s(std::false_type) |
117 | | { |
118 | | return static_cast<double>( |
119 | | (std::numeric_limits<T>::min)()); |
120 | | } |
121 | | |
122 | | static constexpr |
123 | | double min2s(std::true_type) |
124 | | { |
125 | | return -9223372036854774784.0; |
126 | | } |
127 | | |
128 | | static constexpr |
129 | | double max1(std::true_type) |
130 | | { |
131 | | return max2s(std::integral_constant< |
132 | | bool, (std::numeric_limits<T>::max)() == |
133 | | INT64_MAX>{}); |
134 | | } |
135 | | |
136 | | static constexpr |
137 | | double max2s(std::false_type) |
138 | | { |
139 | | return static_cast<double>( |
140 | | (std::numeric_limits<T>::max)()); |
141 | | } |
142 | | |
143 | | static constexpr |
144 | | double max2s(std::true_type) |
145 | | { |
146 | | return 9223372036854774784.0; |
147 | | } |
148 | | |
149 | | public: |
150 | | static constexpr |
151 | | double (min)() noexcept |
152 | | { |
153 | | return min1(std::is_signed<T>{}); |
154 | | } |
155 | | |
156 | | static constexpr |
157 | | double (max)() noexcept |
158 | | { |
159 | | 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 | | scalar(storage_ptr sp_ = {}) noexcept |
179 | 1.70M | : sp(std::move(sp_)) |
180 | 1.70M | , k(json::kind::null) |
181 | 1.70M | { |
182 | 1.70M | } |
183 | | |
184 | | explicit |
185 | | scalar(bool b_, |
186 | | storage_ptr sp_ = {}) noexcept |
187 | 50.9k | : sp(std::move(sp_)) |
188 | 50.9k | , k(json::kind::bool_) |
189 | 50.9k | , b(b_) |
190 | 50.9k | { |
191 | 50.9k | } |
192 | | |
193 | | explicit |
194 | | scalar(std::int64_t i_, |
195 | | storage_ptr sp_ = {}) noexcept |
196 | 6.87M | : sp(std::move(sp_)) |
197 | 6.87M | , k(json::kind::int64) |
198 | 6.87M | , i(i_) |
199 | 6.87M | { |
200 | 6.87M | } |
201 | | |
202 | | explicit |
203 | | scalar(std::uint64_t u_, |
204 | | storage_ptr sp_ = {}) noexcept |
205 | 72.2k | : sp(std::move(sp_)) |
206 | 72.2k | , k(json::kind::uint64) |
207 | 72.2k | , u(u_) |
208 | 72.2k | { |
209 | 72.2k | } |
210 | | |
211 | | explicit |
212 | | scalar(double d_, |
213 | | storage_ptr sp_ = {}) noexcept |
214 | 5.63M | : sp(std::move(sp_)) |
215 | 5.63M | , k(json::kind::double_) |
216 | 5.63M | , d(d_) |
217 | 5.63M | { |
218 | 5.63M | } |
219 | | }; |
220 | | |
221 | | struct access |
222 | | { |
223 | | template<class Value, class... Args> |
224 | | static |
225 | | Value& |
226 | | construct_value(Value* p, Args&&... args) |
227 | 14.6M | { |
228 | 14.6M | return *reinterpret_cast< |
229 | 14.6M | Value*>(::new(p) Value( |
230 | 14.6M | std::forward<Args>(args)...)); |
231 | 14.6M | } boost::json::value& boost::json::detail::access::construct_value<boost::json::value, boost::json::detail::unchecked_array>(boost::json::value*, boost::json::detail::unchecked_array&&) Line | Count | Source | 227 | 27.7k | { | 228 | 27.7k | return *reinterpret_cast< | 229 | 27.7k | Value*>(::new(p) Value( | 230 | 27.7k | std::forward<Args>(args)...)); | 231 | 27.7k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, boost::json::detail::unchecked_object>(boost::json::value*, boost::json::detail::unchecked_object&&) Line | Count | Source | 227 | 22.8k | { | 228 | 22.8k | return *reinterpret_cast< | 229 | 22.8k | Value*>(::new(p) Value( | 230 | 22.8k | std::forward<Args>(args)...)); | 231 | 22.8k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, boost::json::detail::key_t, boost::core::basic_string_view<char>&, boost::json::storage_ptr&>(boost::json::value*, boost::json::detail::key_t&&, boost::core::basic_string_view<char>&, boost::json::storage_ptr&) Line | Count | Source | 227 | 1.88M | { | 228 | 1.88M | return *reinterpret_cast< | 229 | 1.88M | Value*>(::new(p) Value( | 230 | 1.88M | std::forward<Args>(args)...)); | 231 | 1.88M | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, boost::json::detail::key_t, boost::core::basic_string_view<char>&, boost::core::basic_string_view<char>&, boost::json::storage_ptr&>(boost::json::value*, boost::json::detail::key_t&&, boost::core::basic_string_view<char>&, boost::core::basic_string_view<char>&, boost::json::storage_ptr&) Line | Count | Source | 227 | 3.26k | { | 228 | 3.26k | return *reinterpret_cast< | 229 | 3.26k | Value*>(::new(p) Value( | 230 | 3.26k | std::forward<Args>(args)...)); | 231 | 3.26k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, boost::core::basic_string_view<char>&, boost::json::storage_ptr&>(boost::json::value*, boost::core::basic_string_view<char>&, boost::json::storage_ptr&) Line | Count | Source | 227 | 48.9k | { | 228 | 48.9k | return *reinterpret_cast< | 229 | 48.9k | Value*>(::new(p) Value( | 230 | 48.9k | std::forward<Args>(args)...)); | 231 | 48.9k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, boost::json::string_kind_t const&, boost::json::storage_ptr&>(boost::json::value*, boost::json::string_kind_t const&, boost::json::storage_ptr&) Line | Count | Source | 227 | 17.3k | { | 228 | 17.3k | return *reinterpret_cast< | 229 | 17.3k | Value*>(::new(p) Value( | 230 | 17.3k | std::forward<Args>(args)...)); | 231 | 17.3k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, long&, boost::json::storage_ptr&>(boost::json::value*, long&, boost::json::storage_ptr&) Line | Count | Source | 227 | 6.87M | { | 228 | 6.87M | return *reinterpret_cast< | 229 | 6.87M | Value*>(::new(p) Value( | 230 | 6.87M | std::forward<Args>(args)...)); | 231 | 6.87M | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, unsigned long&, boost::json::storage_ptr&>(boost::json::value*, unsigned long&, boost::json::storage_ptr&) Line | Count | Source | 227 | 72.2k | { | 228 | 72.2k | return *reinterpret_cast< | 229 | 72.2k | Value*>(::new(p) Value( | 230 | 72.2k | std::forward<Args>(args)...)); | 231 | 72.2k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, double&, boost::json::storage_ptr&>(boost::json::value*, double&, boost::json::storage_ptr&) Line | Count | Source | 227 | 5.63M | { | 228 | 5.63M | return *reinterpret_cast< | 229 | 5.63M | Value*>(::new(p) Value( | 230 | 5.63M | std::forward<Args>(args)...)); | 231 | 5.63M | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, bool&, boost::json::storage_ptr&>(boost::json::value*, bool&, boost::json::storage_ptr&) Line | Count | Source | 227 | 50.9k | { | 228 | 50.9k | return *reinterpret_cast< | 229 | 50.9k | Value*>(::new(p) Value( | 230 | 50.9k | std::forward<Args>(args)...)); | 231 | 50.9k | } |
boost::json::value& boost::json::detail::access::construct_value<boost::json::value, decltype(nullptr), boost::json::storage_ptr&>(boost::json::value*, decltype(nullptr)&&, boost::json::storage_ptr&) Line | Count | Source | 227 | 18.6k | { | 228 | 18.6k | return *reinterpret_cast< | 229 | 18.6k | Value*>(::new(p) Value( | 230 | 18.6k | std::forward<Args>(args)...)); | 231 | 18.6k | } |
|
232 | | |
233 | | template<class KeyValuePair, class... Args> |
234 | | static |
235 | | KeyValuePair& |
236 | | construct_key_value_pair( |
237 | | KeyValuePair* p, Args&&... args) |
238 | 1.67M | { |
239 | 1.67M | return *reinterpret_cast< |
240 | 1.67M | KeyValuePair*>(::new(p) |
241 | 1.67M | KeyValuePair( |
242 | 1.67M | std::forward<Args>(args)...)); |
243 | 1.67M | } |
244 | | |
245 | | template<class Value> |
246 | | static |
247 | | char const* |
248 | | release_key( |
249 | | Value& jv, |
250 | | std::size_t& len) noexcept |
251 | 1.67M | { |
252 | 1.67M | BOOST_ASSERT(jv.is_string()); |
253 | 1.67M | jv.str_.sp_.~storage_ptr(); |
254 | 1.67M | return jv.str_.impl_.release_key(len); |
255 | 1.67M | } |
256 | | |
257 | | using index_t = std::uint32_t; |
258 | | |
259 | | template<class KeyValuePair> |
260 | | static |
261 | | index_t& |
262 | | next(KeyValuePair& e) noexcept |
263 | 3.32M | { |
264 | 3.32M | return e.next_; |
265 | 3.32M | } |
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 |