1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/json
7  
// Official repository: https://github.com/boostorg/json
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_JSON_DETAIL_VALUE_HPP
10  
#ifndef BOOST_JSON_DETAIL_VALUE_HPP
11  
#define BOOST_JSON_DETAIL_VALUE_HPP
11  
#define BOOST_JSON_DETAIL_VALUE_HPP
12  

12  

13  
#include <boost/json/fwd.hpp>
13  
#include <boost/json/fwd.hpp>
14  
#include <boost/json/kind.hpp>
14  
#include <boost/json/kind.hpp>
15  
#include <boost/json/storage_ptr.hpp>
15  
#include <boost/json/storage_ptr.hpp>
16  
#include <cstdint>
16  
#include <cstdint>
17  
#include <limits>
17  
#include <limits>
18  
#include <new>
18  
#include <new>
19  
#include <utility>
19  
#include <utility>
20  

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace json {
22  
namespace json {
23  
namespace detail {
23  
namespace detail {
24  

24  

25  
struct key_t
25  
struct key_t
26  
{
26  
{
27  
};
27  
};
28  

28  

29  
#if 0
29  
#if 0
30  
template<class T>
30  
template<class T>
31  
struct to_number_limit
31  
struct to_number_limit
32  
    : std::numeric_limits<T>
32  
    : std::numeric_limits<T>
33  
{
33  
{
34  
};
34  
};
35  

35  

36  
template<class T>
36  
template<class T>
37  
struct to_number_limit<T const>
37  
struct to_number_limit<T const>
38  
    : to_number_limit<T>
38  
    : to_number_limit<T>
39  
{
39  
{
40  
};
40  
};
41  

41  

42  
template<>
42  
template<>
43  
struct to_number_limit<long long>
43  
struct to_number_limit<long long>
44  
{
44  
{
45  
    static constexpr long long (min)() noexcept
45  
    static constexpr long long (min)() noexcept
46  
    {
46  
    {
47  
        return -9223372036854774784;
47  
        return -9223372036854774784;
48  
    }
48  
    }
49  

49  

50  
    static constexpr long long (max)() noexcept
50  
    static constexpr long long (max)() noexcept
51  
    {
51  
    {
52  
        return 9223372036854774784;
52  
        return 9223372036854774784;
53  
    }
53  
    }
54  
};
54  
};
55  

55  

56  
template<>
56  
template<>
57  
struct to_number_limit<unsigned long long>
57  
struct to_number_limit<unsigned long long>
58  
{
58  
{
59  
    static constexpr
59  
    static constexpr
60  
    unsigned long long (min)() noexcept
60  
    unsigned long long (min)() noexcept
61  
    {
61  
    {
62  
        return 0;
62  
        return 0;
63  
    }
63  
    }
64  

64  

65  
    static constexpr
65  
    static constexpr
66  
    unsigned long long (max)() noexcept
66  
    unsigned long long (max)() noexcept
67  
    {
67  
    {
68  
        return 18446744073709549568ULL;
68  
        return 18446744073709549568ULL;
69  
    }
69  
    }
70  
};
70  
};
71  
#else
71  
#else
72  

72  

73  
template<class T>
73  
template<class T>
74  
class to_number_limit
74  
class to_number_limit
75  
{
75  
{
76  
    // unsigned
76  
    // unsigned
77  

77  

78  
    static constexpr
78  
    static constexpr
79  
    double min1(std::false_type)
79  
    double min1(std::false_type)
80  
    {
80  
    {
81  
        return 0.0;
81  
        return 0.0;
82  
    }
82  
    }
83  

83  

84  
    static constexpr
84  
    static constexpr
85  
    double max1(std::false_type)
85  
    double max1(std::false_type)
86  
    {
86  
    {
87  
        return max2u(std::integral_constant<
87  
        return max2u(std::integral_constant<
88  
            bool, (std::numeric_limits<T>::max)() ==
88  
            bool, (std::numeric_limits<T>::max)() ==
89  
            UINT64_MAX>{});
89  
            UINT64_MAX>{});
90  
    }
90  
    }
91  

91  

92  
    static constexpr
92  
    static constexpr
93  
    double max2u(std::false_type)
93  
    double max2u(std::false_type)
94  
    {
94  
    {
95  
        return static_cast<double>(
95  
        return static_cast<double>(
96  
            (std::numeric_limits<T>::max)());
96  
            (std::numeric_limits<T>::max)());
97  
    }
97  
    }
98  

98  

99  
    static constexpr
99  
    static constexpr
100  
    double max2u(std::true_type)
100  
    double max2u(std::true_type)
101  
    {
101  
    {
102  
        return 18446744073709549568.0;
102  
        return 18446744073709549568.0;
103  
    }
103  
    }
104  

104  

105  
    // signed
105  
    // signed
106  

106  

107  
    static constexpr
107  
    static constexpr
108  
    double min1(std::true_type)
108  
    double min1(std::true_type)
109  
    {
109  
    {
110  
        return min2s(std::integral_constant<
110  
        return min2s(std::integral_constant<
111  
            bool, (std::numeric_limits<T>::max)() ==
111  
            bool, (std::numeric_limits<T>::max)() ==
112  
            INT64_MAX>{});
112  
            INT64_MAX>{});
113  
    }
113  
    }
114  

114  

115  
    static constexpr
115  
    static constexpr
116  
    double min2s(std::false_type)
116  
    double min2s(std::false_type)
117  
    {
117  
    {
118  
        return static_cast<double>(
118  
        return static_cast<double>(
119  
            (std::numeric_limits<T>::min)());
119  
            (std::numeric_limits<T>::min)());
120  
    }
120  
    }
121  

121  

122  
    static constexpr
122  
    static constexpr
123  
    double min2s(std::true_type)
123  
    double min2s(std::true_type)
124  
    {
124  
    {
125  
        return -9223372036854774784.0;
125  
        return -9223372036854774784.0;
126  
    }
126  
    }
127  

127  

128  
    static constexpr
128  
    static constexpr
129  
    double max1(std::true_type)
129  
    double max1(std::true_type)
130  
    {
130  
    {
131  
        return max2s(std::integral_constant<
131  
        return max2s(std::integral_constant<
132  
            bool, (std::numeric_limits<T>::max)() ==
132  
            bool, (std::numeric_limits<T>::max)() ==
133  
            INT64_MAX>{});
133  
            INT64_MAX>{});
134  
    }
134  
    }
135  

135  

136  
    static constexpr
136  
    static constexpr
137  
    double max2s(std::false_type)
137  
    double max2s(std::false_type)
138  
    {
138  
    {
139  
        return static_cast<double>(
139  
        return static_cast<double>(
140  
            (std::numeric_limits<T>::max)());
140  
            (std::numeric_limits<T>::max)());
141  
    }
141  
    }
142  

142  

143  
    static constexpr
143  
    static constexpr
144  
    double max2s(std::true_type)
144  
    double max2s(std::true_type)
145  
    {
145  
    {
146  
        return 9223372036854774784.0;
146  
        return 9223372036854774784.0;
147  
    }
147  
    }
148  

148  

149  
public:
149  
public:
150  
    static constexpr
150  
    static constexpr
151  
    double (min)() noexcept
151  
    double (min)() noexcept
152  
    {
152  
    {
153  
        return min1(std::is_signed<T>{});
153  
        return min1(std::is_signed<T>{});
154  
    }
154  
    }
155  

155  

156  
    static constexpr
156  
    static constexpr
157  
    double (max)() noexcept
157  
    double (max)() noexcept
158  
    {
158  
    {
159  
        return max1(std::is_signed<T>{});
159  
        return max1(std::is_signed<T>{});
160  
    }
160  
    }
161  
};
161  
};
162  

162  

163  
#endif
163  
#endif
164  

164  

165  
struct scalar
165  
struct scalar
166  
{
166  
{
167  
    storage_ptr sp; // must come first
167  
    storage_ptr sp; // must come first
168  
    kind k;         // must come second
168  
    kind k;         // must come second
169  
    union
169  
    union
170  
    {
170  
    {
171  
        bool b;
171  
        bool b;
172  
        std::int64_t i;
172  
        std::int64_t i;
173  
        std::uint64_t u;
173  
        std::uint64_t u;
174  
        double d;
174  
        double d;
175  
    };
175  
    };
176  

176  

177  
    explicit
177  
    explicit
178  
    scalar(storage_ptr sp_ = {}) noexcept
178  
    scalar(storage_ptr sp_ = {}) noexcept
179  
        : sp(std::move(sp_))
179  
        : sp(std::move(sp_))
180  
        , k(json::kind::null)
180  
        , k(json::kind::null)
181  
    {
181  
    {
182  
    }
182  
    }
183  

183  

184  
    explicit
184  
    explicit
185  
    scalar(bool b_,
185  
    scalar(bool b_,
186  
        storage_ptr sp_ = {}) noexcept
186  
        storage_ptr sp_ = {}) noexcept
187  
        : sp(std::move(sp_))
187  
        : sp(std::move(sp_))
188  
        , k(json::kind::bool_)
188  
        , k(json::kind::bool_)
189  
        , b(b_)
189  
        , b(b_)
190  
    {
190  
    {
191  
    }
191  
    }
192  

192  

193  
    explicit
193  
    explicit
194  
    scalar(std::int64_t i_,
194  
    scalar(std::int64_t i_,
195  
        storage_ptr sp_ = {}) noexcept
195  
        storage_ptr sp_ = {}) noexcept
196  
        : sp(std::move(sp_))
196  
        : sp(std::move(sp_))
197  
        , k(json::kind::int64)
197  
        , k(json::kind::int64)
198  
        , i(i_)
198  
        , i(i_)
199  
    {
199  
    {
200  
    }
200  
    }
201  

201  

202  
    explicit
202  
    explicit
203  
    scalar(std::uint64_t u_,
203  
    scalar(std::uint64_t u_,
204  
        storage_ptr sp_ = {}) noexcept
204  
        storage_ptr sp_ = {}) noexcept
205  
        : sp(std::move(sp_))
205  
        : sp(std::move(sp_))
206  
        , k(json::kind::uint64)
206  
        , k(json::kind::uint64)
207  
        , u(u_)
207  
        , u(u_)
208  
    {
208  
    {
209  
    }
209  
    }
210  

210  

211  
    explicit
211  
    explicit
212  
    scalar(double d_,
212  
    scalar(double d_,
213  
        storage_ptr sp_ = {}) noexcept
213  
        storage_ptr sp_ = {}) noexcept
214  
        : sp(std::move(sp_))
214  
        : sp(std::move(sp_))
215  
        , k(json::kind::double_)
215  
        , k(json::kind::double_)
216  
        , d(d_)
216  
        , d(d_)
217  
    {
217  
    {
218  
    }
218  
    }
219  
};
219  
};
220  

220  

221  
struct access
221  
struct access
222  
{
222  
{
223  
    template<class Value, class... Args>
223  
    template<class Value, class... Args>
224  
    static
224  
    static
225  
    Value&
225  
    Value&
226  
    construct_value(Value* p, Args&&... args)
226  
    construct_value(Value* p, Args&&... args)
227  
    {
227  
    {
228  
        return *reinterpret_cast<
228  
        return *reinterpret_cast<
229  
            Value*>(::new(p) Value(
229  
            Value*>(::new(p) Value(
230  
            std::forward<Args>(args)...));
230  
            std::forward<Args>(args)...));
231  
    }
231  
    }
232  

232  

233  
    template<class KeyValuePair, class... Args>
233  
    template<class KeyValuePair, class... Args>
234  
    static
234  
    static
235  
    KeyValuePair&
235  
    KeyValuePair&
236  
    construct_key_value_pair(
236  
    construct_key_value_pair(
237  
        KeyValuePair* p, Args&&... args)
237  
        KeyValuePair* p, Args&&... args)
238  
    {
238  
    {
239  
        return *reinterpret_cast<
239  
        return *reinterpret_cast<
240  
            KeyValuePair*>(::new(p)
240  
            KeyValuePair*>(::new(p)
241  
                KeyValuePair(
241  
                KeyValuePair(
242  
                    std::forward<Args>(args)...));
242  
                    std::forward<Args>(args)...));
243  
    }
243  
    }
244  

244  

245  
    template<class Value>
245  
    template<class Value>
246  
    static
246  
    static
247  
    char const*
247  
    char const*
248  
    release_key(
248  
    release_key(
249  
        Value& jv,
249  
        Value& jv,
250  
        std::size_t& len) noexcept
250  
        std::size_t& len) noexcept
251  
    {
251  
    {
252  
        BOOST_ASSERT(jv.is_string());
252  
        BOOST_ASSERT(jv.is_string());
253  
        jv.str_.sp_.~storage_ptr();
253  
        jv.str_.sp_.~storage_ptr();
254  
        return jv.str_.impl_.release_key(len);
254  
        return jv.str_.impl_.release_key(len);
255  
    }
255  
    }
256  

256  

257  
    using index_t = std::uint32_t;
257  
    using index_t = std::uint32_t;
258  

258  

259  
    template<class KeyValuePair>
259  
    template<class KeyValuePair>
260  
    static
260  
    static
261  
    index_t&
261  
    index_t&
262  
    next(KeyValuePair& e) noexcept
262  
    next(KeyValuePair& e) noexcept
263  
    {
263  
    {
264  
        return e.next_;
264  
        return e.next_;
265  
    }
265  
    }
266  

266  

267  
    template<class KeyValuePair>
267  
    template<class KeyValuePair>
268  
    static
268  
    static
269  
    index_t const&
269  
    index_t const&
270  
    next(KeyValuePair const& e) noexcept
270  
    next(KeyValuePair const& e) noexcept
271  
    {
271  
    {
272  
        return e.next_;
272  
        return e.next_;
273  
    }
273  
    }
274  
};
274  
};
275  

275  

276  
BOOST_JSON_DECL
276  
BOOST_JSON_DECL
277  
std::size_t
277  
std::size_t
278  
hash_value_impl( value const& jv ) noexcept;
278  
hash_value_impl( value const& jv ) noexcept;
279  

279  

280  
} // detail
280  
} // detail
281  
} // namespace json
281  
} // namespace json
282  
} // namespace boost
282  
} // namespace boost
283  

283  

284  
#endif
284  
#endif