detail/value.hpp

100.0% Lines (66/66) 79.5% Functions (58/73) 63.6% Branches (7/11)
detail/value.hpp
Line Branch Hits 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
3/3
✓ Branch 1 taken 36922 times.
✓ Branch 2 taken 55440 times.
✓ Branch 2 taken 1 time.
6396945 Value*>(::new(p) Value(
232
3/6
✓ Branch 2 taken 77 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 60 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 38150 times.
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
303