TLA 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 : template<class T>
30 : class to_number_limit
31 : {
32 : // unsigned
33 :
34 : static constexpr
35 HIT 16 : double max1(std::false_type)
36 : {
37 16 : return max2u(std::integral_constant<
38 : bool, (std::numeric_limits<T>::max)() ==
39 16 : UINT64_MAX>{});
40 : }
41 :
42 : static constexpr
43 12 : double max2u(std::false_type)
44 : {
45 : return static_cast<double>(
46 12 : (std::numeric_limits<T>::max)());
47 : }
48 :
49 : static constexpr
50 4 : double max2u(std::true_type)
51 : {
52 : // largest uint64_t value exactly representable as double
53 4 : return 18446744073709549568.0;
54 : }
55 :
56 : // signed
57 :
58 : static constexpr
59 29 : double max1(std::true_type)
60 : {
61 29 : return max2s(std::integral_constant<
62 : bool, (std::numeric_limits<T>::max)() ==
63 29 : INT64_MAX>{});
64 : }
65 :
66 : static constexpr
67 23 : double max2s(std::false_type)
68 : {
69 : return static_cast<double>(
70 23 : (std::numeric_limits<T>::max)());
71 : }
72 :
73 : static constexpr
74 6 : double max2s(std::true_type)
75 : {
76 : // largest int64_t value exactly representable as double
77 6 : return 9223372036854774784.0;
78 : }
79 :
80 : public:
81 : static constexpr
82 32 : double (min)() noexcept
83 : {
84 32 : return static_cast<double>( (std::numeric_limits<T>::min)() );
85 : }
86 :
87 : static constexpr
88 45 : double (max)() noexcept
89 : {
90 45 : return max1(std::is_signed<T>{});
91 : }
92 : };
93 :
94 : struct scalar
95 : {
96 : storage_ptr sp; // must come first
97 : kind k; // must come second
98 : union
99 : {
100 : bool b;
101 : std::int64_t i;
102 : std::uint64_t u;
103 : double d;
104 : };
105 :
106 : explicit
107 2152210 : scalar(storage_ptr sp_ = {}) noexcept
108 2152210 : : sp(std::move(sp_))
109 2152210 : , k(json::kind::null)
110 : {
111 2152210 : }
112 :
113 : explicit
114 1107 : scalar(bool b_,
115 : storage_ptr sp_ = {}) noexcept
116 1107 : : sp(std::move(sp_))
117 1107 : , k(json::kind::bool_)
118 1107 : , b(b_)
119 : {
120 1107 : }
121 :
122 : explicit
123 34780 : scalar(std::int64_t i_,
124 : storage_ptr sp_ = {}) noexcept
125 34780 : : sp(std::move(sp_))
126 34780 : , k(json::kind::int64)
127 34780 : , i(i_)
128 : {
129 34780 : }
130 :
131 : explicit
132 406 : scalar(std::uint64_t u_,
133 : storage_ptr sp_ = {}) noexcept
134 406 : : sp(std::move(sp_))
135 406 : , k(json::kind::uint64)
136 406 : , u(u_)
137 : {
138 406 : }
139 :
140 : explicit
141 2039974 : scalar(double d_,
142 : storage_ptr sp_ = {}) noexcept
143 2039974 : : sp(std::move(sp_))
144 2039974 : , k(json::kind::double_)
145 2039974 : , d(d_)
146 : {
147 2039974 : }
148 : };
149 :
150 : struct access
151 : {
152 : template<class Value, class... Args>
153 : static
154 : Value&
155 2156952 : construct_value(Value* p, Args&&... args)
156 : {
157 : return *reinterpret_cast<
158 6396997 : Value*>(::new(p) Value(
159 6489299 : std::forward<Args>(args)...));
160 : }
161 :
162 : template<class KeyValuePair, class... Args>
163 : static
164 : KeyValuePair&
165 38151 : construct_key_value_pair(
166 : KeyValuePair* p, Args&&... args)
167 : {
168 : return *reinterpret_cast<
169 38151 : KeyValuePair*>(::new(p)
170 : KeyValuePair(
171 76302 : std::forward<Args>(args)...));
172 : }
173 :
174 : template<class Value>
175 : static
176 : char const*
177 38151 : release_key(
178 : Value& jv,
179 : std::size_t& len) noexcept
180 : {
181 38151 : BOOST_ASSERT(jv.is_string());
182 38151 : jv.str_.sp_.~storage_ptr();
183 38151 : return jv.str_.impl_.release_key(len);
184 : }
185 :
186 : using index_t = std::uint32_t;
187 :
188 : template<class KeyValuePair>
189 : static
190 : index_t&
191 11464 : next(KeyValuePair& e) noexcept
192 : {
193 11464 : return e.next_;
194 : }
195 :
196 : template<class KeyValuePair>
197 : static
198 : index_t const&
199 : next(KeyValuePair const& e) noexcept
200 : {
201 : return e.next_;
202 : }
203 :
204 : template<class Value>
205 : static
206 : auto
207 12 : get_scalar(Value& jv) -> scalar&
208 : {
209 12 : return jv.sca_;
210 : }
211 :
212 : template<class Value>
213 : static
214 : auto
215 264 : get_scalar(Value const& jv) -> scalar const&
216 : {
217 264 : return jv.sca_;
218 : }
219 : };
220 :
221 : BOOST_JSON_DECL
222 : std::size_t
223 : hash_value_impl( value const& jv ) noexcept;
224 :
225 : } // detail
226 : } // namespace json
227 : } // namespace boost
228 :
229 : #endif
|