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_VALUE_REF_HPP
10  
#ifndef BOOST_JSON_VALUE_REF_HPP
11  
#define BOOST_JSON_VALUE_REF_HPP
11  
#define BOOST_JSON_VALUE_REF_HPP
12  

12  

13  
#include <boost/json/detail/config.hpp>
13  
#include <boost/json/detail/config.hpp>
14  
#include <boost/json/storage_ptr.hpp>
14  
#include <boost/json/storage_ptr.hpp>
15  
#include <boost/json/string.hpp>
15  
#include <boost/json/string.hpp>
16  
#include <initializer_list>
16  
#include <initializer_list>
17  
#include <type_traits>
17  
#include <type_traits>
18  
#include <utility>
18  
#include <utility>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace json {
21  
namespace json {
22  

22  

23  
#ifndef BOOST_JSON_DOCS
23  
#ifndef BOOST_JSON_DOCS
24  
class value;
24  
class value;
25  
class object;
25  
class object;
26  
class array;
26  
class array;
27  
class string;
27  
class string;
28  
#endif
28  
#endif
29  

29  

30  
//----------------------------------------------------------
30  
//----------------------------------------------------------
31  

31  

32  
/** The type used in initializer lists.
32  
/** The type used in initializer lists.
33  

33  

34  
    This type is used in initializer lists for lazy construction of and
34  
    This type is used in initializer lists for lazy construction of and
35  
    assignment to the container types @ref value, @ref array, and @ref object.
35  
    assignment to the container types @ref value, @ref array, and @ref object.
36  
    The two types of initializer lists used are:
36  
    The two types of initializer lists used are:
37  

37  

38  
    @li `std::initializer_list< value_ref >` for constructing or assigning
38  
    @li `std::initializer_list< value_ref >` for constructing or assigning
39  
        a @ref value or @ref array, and
39  
        a @ref value or @ref array, and
40  
    @li `std::initializer_list< std::pair< string_view, value_ref > >` for
40  
    @li `std::initializer_list< std::pair< string_view, value_ref > >` for
41  
        constructing or assigning an @ref object.
41  
        constructing or assigning an @ref object.
42  

42  

43  
    A `value_ref` uses reference semantics. Creation of the actual container
43  
    A `value_ref` uses reference semantics. Creation of the actual container
44  
    from the initializer list is lazily deferred until the list is used. This
44  
    from the initializer list is lazily deferred until the list is used. This
45  
    means that the @ref boost::container::pmr::memory_resource used to
45  
    means that the @ref boost::container::pmr::memory_resource used to
46  
    construct a container can be specified after the point where the
46  
    construct a container can be specified after the point where the
47  
    initializer list is specified. Also, the usage of this type allows to avoid
47  
    initializer list is specified. Also, the usage of this type allows to avoid
48  
    constructing a @ref value until it's necessary.
48  
    constructing a @ref value until it's necessary.
49  

49  

50  
    @par Example
50  
    @par Example
51  
    This example demonstrates how a user-defined type containing a JSON value
51  
    This example demonstrates how a user-defined type containing a JSON value
52  
    can be constructed from an initializer list:
52  
    can be constructed from an initializer list:
53  

53  

54  
    @code
54  
    @code
55  
    class my_type
55  
    class my_type
56  
    {
56  
    {
57  
        value jv_;
57  
        value jv_;
58  

58  

59  
    public:
59  
    public:
60  
        my_type( std::initializer_list<value_ref> init )
60  
        my_type( std::initializer_list<value_ref> init )
61  
            : jv_(init)
61  
            : jv_(init)
62  
        {
62  
        {
63  
        }
63  
        }
64  
    };
64  
    };
65  
    @endcode
65  
    @endcode
66  

66  

67  
    @warning `value_ref` does not take ownership of the objects it was
67  
    @warning `value_ref` does not take ownership of the objects it was
68  
    constructed with. If those objects' lifetimes end before the `value_ref`
68  
    constructed with. If those objects' lifetimes end before the `value_ref`
69  
    object is used, you will get undefined behavior. Because of this it is
69  
    object is used, you will get undefined behavior. Because of this it is
70  
    advised against declaring a variable of type
70  
    advised against declaring a variable of type
71  
    `std::initializer_list<value_ref>` except in function parameter lists.
71  
    `std::initializer_list<value_ref>` except in function parameter lists.
72  

72  

73  
    @see @ref value, @ref array, @ref object, @ref value::set_at_pointer.
73  
    @see @ref value, @ref array, @ref object, @ref value::set_at_pointer.
74  
*/
74  
*/
75  
class value_ref
75  
class value_ref
76  
{
76  
{
77  
    friend class value;
77  
    friend class value;
78  
    friend class object;
78  
    friend class object;
79  
    friend class array;
79  
    friend class array;
80  

80  

81  
    friend class value_ref_test;
81  
    friend class value_ref_test;
82  

82  

83  
    enum class what
83  
    enum class what
84  
    {
84  
    {
85  
        str,
85  
        str,
86  
        ini,
86  
        ini,
87  
        func,
87  
        func,
88  
        cfunc,
88  
        cfunc,
89  
        strfunc,
89  
        strfunc,
90  
    };
90  
    };
91  

91  

92  
    using init_list =
92  
    using init_list =
93  
        std::initializer_list<value_ref>;
93  
        std::initializer_list<value_ref>;
94  

94  

95  
    struct func_type
95  
    struct func_type
96  
    {
96  
    {
97  
        value(*f)(void*, storage_ptr);
97  
        value(*f)(void*, storage_ptr);
98  
        void* p;
98  
        void* p;
99  
    };
99  
    };
100  

100  

101  
    struct cfunc_type
101  
    struct cfunc_type
102  
    {
102  
    {
103  
        value(*f)(void const*, storage_ptr);
103  
        value(*f)(void const*, storage_ptr);
104  
        void const* p;
104  
        void const* p;
105  
    };
105  
    };
106  

106  

107  
    union arg_type
107  
    union arg_type
108  
    {
108  
    {
109  
        string_view         str_;
109  
        string_view         str_;
110  
        init_list           init_list_;
110  
        init_list           init_list_;
111  

111  

112  
        signed char         schar_;
112  
        signed char         schar_;
113  
        short               short_;
113  
        short               short_;
114  
        int                 int_;
114  
        int                 int_;
115  
        long                long_;
115  
        long                long_;
116  
        long long           long_long_;
116  
        long long           long_long_;
117  
        unsigned char       uchar_;
117  
        unsigned char       uchar_;
118  
        unsigned short      ushort_;
118  
        unsigned short      ushort_;
119  
        unsigned int        uint_;
119  
        unsigned int        uint_;
120  
        unsigned long       ulong_;
120  
        unsigned long       ulong_;
121  
        unsigned long long  ulong_long_;
121  
        unsigned long long  ulong_long_;
122  
        float               float_;
122  
        float               float_;
123  
        double              double_;
123  
        double              double_;
124  
        bool                bool_;
124  
        bool                bool_;
125  
        std::nullptr_t      nullptr_;
125  
        std::nullptr_t      nullptr_;
126  

126  

127  
        arg_type() {}
127  
        arg_type() {}
128  
        explicit arg_type(string_view t) noexcept : str_(t) {}
128  
        explicit arg_type(string_view t) noexcept : str_(t) {}
129  
        explicit arg_type(init_list t) noexcept : init_list_(t) {}
129  
        explicit arg_type(init_list t) noexcept : init_list_(t) {}
130  
        explicit arg_type(signed char t) noexcept : schar_(t) {}
130  
        explicit arg_type(signed char t) noexcept : schar_(t) {}
131  
        explicit arg_type(short t) noexcept : short_(t) {}
131  
        explicit arg_type(short t) noexcept : short_(t) {}
132  
        explicit arg_type(int t) noexcept : int_(t) {}
132  
        explicit arg_type(int t) noexcept : int_(t) {}
133  
        explicit arg_type(long t) noexcept : long_(t) {}
133  
        explicit arg_type(long t) noexcept : long_(t) {}
134  
        explicit arg_type(long long t) noexcept : long_long_(t) {}
134  
        explicit arg_type(long long t) noexcept : long_long_(t) {}
135  
        explicit arg_type(unsigned char t) noexcept : uchar_(t) {}
135  
        explicit arg_type(unsigned char t) noexcept : uchar_(t) {}
136  
        explicit arg_type(unsigned short t) noexcept : ushort_(t) {}
136  
        explicit arg_type(unsigned short t) noexcept : ushort_(t) {}
137  
        explicit arg_type(unsigned int t) noexcept : uint_(t) {}
137  
        explicit arg_type(unsigned int t) noexcept : uint_(t) {}
138  
        explicit arg_type(unsigned long t) noexcept : ulong_(t) {}
138  
        explicit arg_type(unsigned long t) noexcept : ulong_(t) {}
139  
        explicit arg_type(unsigned long long t) noexcept : ulong_long_(t) {}
139  
        explicit arg_type(unsigned long long t) noexcept : ulong_long_(t) {}
140  
        explicit arg_type(float t) noexcept : float_(t) {}
140  
        explicit arg_type(float t) noexcept : float_(t) {}
141  
        explicit arg_type(double t) noexcept : double_(t) {}
141  
        explicit arg_type(double t) noexcept : double_(t) {}
142  
        explicit arg_type(bool t) noexcept : bool_(t) {}
142  
        explicit arg_type(bool t) noexcept : bool_(t) {}
143  
        explicit arg_type(std::nullptr_t) noexcept : nullptr_() {}
143  
        explicit arg_type(std::nullptr_t) noexcept : nullptr_() {}
144  
    };
144  
    };
145  

145  

146  
    arg_type arg_;
146  
    arg_type arg_;
147  
#ifndef BOOST_JSON_DOCS
147  
#ifndef BOOST_JSON_DOCS
148  
    // VFALCO doc toolchain erroneously
148  
    // VFALCO doc toolchain erroneously
149  
    // displays private, anonymous unions as public
149  
    // displays private, anonymous unions as public
150  
    union
150  
    union
151  
    {
151  
    {
152  
        func_type f_;
152  
        func_type f_;
153  
        cfunc_type cf_;
153  
        cfunc_type cf_;
154  
    };
154  
    };
155  
#endif
155  
#endif
156  
    what what_;
156  
    what what_;
157  

157  

158  
public:
158  
public:
159  
    /** Constructors.
159  
    /** Constructors.
160  

160  

161  
        @li **(1)** copy constructor.
161  
        @li **(1)** copy constructor.
162  
        @li **(2)** move constructor.
162  
        @li **(2)** move constructor.
163  
        @li **(3)** the constructed value stores a reference to `t`'s character
163  
        @li **(3)** the constructed value stores a reference to `t`'s character
164  
            array.
164  
            array.
165  
        @li **(4)** the constructed value stores a `const` reference to `t`.
165  
        @li **(4)** the constructed value stores a `const` reference to `t`.
166  
        @li **(5)** the constructed value stores an rvalue reference to `t`.
166  
        @li **(5)** the constructed value stores an rvalue reference to `t`.
167  
        @li **(6)** the constructed value stores a copy of `b`.
167  
        @li **(6)** the constructed value stores a copy of `b`.
168  
        @li **(7)**--**(18)** the constructed value stores a copy of `t`.
168  
        @li **(7)**--**(18)** the constructed value stores a copy of `t`.
169  
        @li **(19)** the constrcuted value stores `nullptr`.
169  
        @li **(19)** the constrcuted value stores `nullptr`.
170  
        @li **(20)** the constrcuted value stores a copy of `init`.
170  
        @li **(20)** the constrcuted value stores a copy of `init`.
171  

171  

172  
        In addition the constructed object stores a pointer to a function that
172  
        In addition the constructed object stores a pointer to a function that
173  
        captures the type information necessary to construct a @ref value from
173  
        captures the type information necessary to construct a @ref value from
174  
        the stored data.
174  
        the stored data.
175  

175  

176  
        @warning The overloads that accept references do not take ownership of
176  
        @warning The overloads that accept references do not take ownership of
177  
        referenced objects. The caller is responsible for making sure those
177  
        referenced objects. The caller is responsible for making sure those
178  
        objects do not go out of scope before the `value_ref` object is used.
178  
        objects do not go out of scope before the `value_ref` object is used.
179  
        It is advised you only use `value_ref` (or any type that contains a
179  
        It is advised you only use `value_ref` (or any type that contains a
180  
        `value_ref` subobject) as function parameters or take special care to
180  
        `value_ref` subobject) as function parameters or take special care to
181  
        not invoke undefeined behavior.
181  
        not invoke undefeined behavior.
182  

182  

183  
        @par Complexity
183  
        @par Complexity
184  
        @li **(1)**--**(19)** constant.
184  
        @li **(1)**--**(19)** constant.
185  
        @li **(20)** linear in `init.size()`.
185  
        @li **(20)** linear in `init.size()`.
186  

186  

187  
        @par Exception Safety
187  
        @par Exception Safety
188  
        No-throw guarantee.
188  
        No-throw guarantee.
189  

189  

190  
        @{
190  
        @{
191  
    */
191  
    */
192  
    value_ref(
192  
    value_ref(
193  
        value_ref const&) = default;
193  
        value_ref const&) = default;
194  

194  

195  
    /// Overload
195  
    /// Overload
196  
    value_ref(
196  
    value_ref(
197  
        value_ref&&) = default;
197  
        value_ref&&) = default;
198  

198  

199  
    /// Overload
199  
    /// Overload
200  
#ifdef BOOST_JSON_DOCS
200  
#ifdef BOOST_JSON_DOCS
201  
    value_ref(string_view s) noexcept;
201  
    value_ref(string_view s) noexcept;
202  
#else
202  
#else
203  
    template<
203  
    template<
204  
        class T
204  
        class T
205  
        ,class = typename
205  
        ,class = typename
206  
            std::enable_if<
206  
            std::enable_if<
207  
                std::is_constructible<
207  
                std::is_constructible<
208  
                    string_view, T>::value>::type
208  
                    string_view, T>::value>::type
209  
    >
209  
    >
210  
    value_ref(
210  
    value_ref(
211  
        T const& t) noexcept
211  
        T const& t) noexcept
212  
        : arg_(string_view(t))
212  
        : arg_(string_view(t))
213  
        , what_(what::str)
213  
        , what_(what::str)
214  
    {
214  
    {
215  
    }
215  
    }
216  
#endif
216  
#endif
217  

217  

218  
    /// Overload
218  
    /// Overload
219  
    template<class T>
219  
    template<class T>
220  
    value_ref(
220  
    value_ref(
221  
        T const& t
221  
        T const& t
222  
#ifndef BOOST_JSON_DOCS
222  
#ifndef BOOST_JSON_DOCS
223  
        ,typename std::enable_if<
223  
        ,typename std::enable_if<
224  
            ! std::is_constructible<
224  
            ! std::is_constructible<
225  
                string_view, T>::value &&
225  
                string_view, T>::value &&
226  
            ! std::is_same<bool, T>::value
226  
            ! std::is_same<bool, T>::value
227  
                >::type* = 0
227  
                >::type* = 0
228  
#endif
228  
#endif
229  
        ) noexcept
229  
        ) noexcept
230  
        : cf_{&from_const<T>, &t}
230  
        : cf_{&from_const<T>, &t}
231  
        , what_(what::cfunc)
231  
        , what_(what::cfunc)
232  
    {
232  
    {
233  
    }
233  
    }
234  

234  

235  
    /// Overload
235  
    /// Overload
236  
    template<class T>
236  
    template<class T>
237  
    value_ref(
237  
    value_ref(
238  
        T&& t
238  
        T&& t
239  
#ifndef BOOST_JSON_DOCS
239  
#ifndef BOOST_JSON_DOCS
240  
        ,typename std::enable_if<
240  
        ,typename std::enable_if<
241  
            (! std::is_constructible<
241  
            (! std::is_constructible<
242  
                string_view, T>::value ||
242  
                string_view, T>::value ||
243  
            std::is_same<string, T>::value) &&
243  
            std::is_same<string, T>::value) &&
244  
            ! std::is_same<bool,
244  
            ! std::is_same<bool,
245  
                detail::remove_cvref<T>>::value &&
245  
                detail::remove_cvref<T>>::value &&
246  
            std::is_same<T, detail::remove_cvref<T>>
246  
            std::is_same<T, detail::remove_cvref<T>>
247  
                ::value>::type* = 0
247  
                ::value>::type* = 0
248  
#endif
248  
#endif
249  
        ) noexcept
249  
        ) noexcept
250  
        : f_{&from_rvalue<
250  
        : f_{&from_rvalue<
251  
            detail::remove_cvref<T>>, &t}
251  
            detail::remove_cvref<T>>, &t}
252  
        , what_(std::is_same<string, T>::value ?
252  
        , what_(std::is_same<string, T>::value ?
253  
                what::strfunc : what::func)
253  
                what::strfunc : what::func)
254  
    {
254  
    {
255  
    }
255  
    }
256  

256  

257  
    /// Overload
257  
    /// Overload
258  
#ifdef BOOST_JSON_DOCS
258  
#ifdef BOOST_JSON_DOCS
259  
    value_ref(bool b) noexcept;
259  
    value_ref(bool b) noexcept;
260  
#else
260  
#else
261  
    template<
261  
    template<
262  
        class T
262  
        class T
263  
        ,class = typename std::enable_if<
263  
        ,class = typename std::enable_if<
264  
            std::is_same<T, bool>::value>::type
264  
            std::is_same<T, bool>::value>::type
265  
    >
265  
    >
266  
    value_ref(
266  
    value_ref(
267  
        T b) noexcept
267  
        T b) noexcept
268  
        : arg_(b)
268  
        : arg_(b)
269  
        , cf_{&from_builtin<bool>, &arg_.bool_}
269  
        , cf_{&from_builtin<bool>, &arg_.bool_}
270  
        , what_(what::cfunc)
270  
        , what_(what::cfunc)
271  
    {
271  
    {
272  
    }
272  
    }
273  
#endif
273  
#endif
274  

274  

275  
    /// Overload
275  
    /// Overload
276  
    value_ref(signed char t) noexcept
276  
    value_ref(signed char t) noexcept
277  
        : arg_(t)
277  
        : arg_(t)
278  
        , cf_{&from_builtin<signed char>, &arg_.schar_}
278  
        , cf_{&from_builtin<signed char>, &arg_.schar_}
279  
        , what_(what::cfunc)
279  
        , what_(what::cfunc)
280  
    {
280  
    {
281  
    }
281  
    }
282  

282  

283  
    /// Overload
283  
    /// Overload
284  
    value_ref(short t) noexcept
284  
    value_ref(short t) noexcept
285  
        : arg_(t)
285  
        : arg_(t)
286  
        , cf_{&from_builtin<short>, &arg_.short_}
286  
        , cf_{&from_builtin<short>, &arg_.short_}
287  
        , what_(what::cfunc)
287  
        , what_(what::cfunc)
288  
    {
288  
    {
289  
    }
289  
    }
290  

290  

291  
    /// Overload
291  
    /// Overload
292  
    value_ref(int t) noexcept
292  
    value_ref(int t) noexcept
293  
        : arg_(t)
293  
        : arg_(t)
294  
        , cf_{&from_builtin<int>, &arg_.int_}
294  
        , cf_{&from_builtin<int>, &arg_.int_}
295  
        , what_(what::cfunc)
295  
        , what_(what::cfunc)
296  
    {
296  
    {
297  
    }
297  
    }
298  

298  

299  
    /// Overload
299  
    /// Overload
300  
    value_ref(long t) noexcept
300  
    value_ref(long t) noexcept
301  
        : arg_(t)
301  
        : arg_(t)
302  
        , cf_{&from_builtin<
302  
        , cf_{&from_builtin<
303  
            long>, &arg_.long_}
303  
            long>, &arg_.long_}
304  
        , what_(what::cfunc)
304  
        , what_(what::cfunc)
305  
    {
305  
    {
306  
    }
306  
    }
307  

307  

308  
    /// Overload
308  
    /// Overload
309  
    value_ref(long long t) noexcept
309  
    value_ref(long long t) noexcept
310  
        : arg_(t)
310  
        : arg_(t)
311  
        , cf_{&from_builtin<
311  
        , cf_{&from_builtin<
312  
            long long>, &arg_.long_long_}
312  
            long long>, &arg_.long_long_}
313  
        , what_(what::cfunc)
313  
        , what_(what::cfunc)
314  
    {
314  
    {
315  
    }
315  
    }
316  

316  

317  
    /// Overload
317  
    /// Overload
318  
    value_ref(unsigned char t) noexcept
318  
    value_ref(unsigned char t) noexcept
319  
        : arg_(t)
319  
        : arg_(t)
320  
        , cf_{&from_builtin<
320  
        , cf_{&from_builtin<
321  
            unsigned char>, &arg_.uchar_}
321  
            unsigned char>, &arg_.uchar_}
322  
        , what_(what::cfunc)
322  
        , what_(what::cfunc)
323  
    {
323  
    {
324  
    }
324  
    }
325  

325  

326  
    /// Overload
326  
    /// Overload
327  
    value_ref(unsigned short t) noexcept
327  
    value_ref(unsigned short t) noexcept
328  
        : arg_(t)
328  
        : arg_(t)
329  
        , cf_{&from_builtin<
329  
        , cf_{&from_builtin<
330  
            unsigned short>, &arg_.ushort_}
330  
            unsigned short>, &arg_.ushort_}
331  
        , what_(what::cfunc)
331  
        , what_(what::cfunc)
332  
    {
332  
    {
333  
    }
333  
    }
334  

334  

335  
    /// Overload
335  
    /// Overload
336  
    value_ref(unsigned int t) noexcept
336  
    value_ref(unsigned int t) noexcept
337  
        : arg_(t)
337  
        : arg_(t)
338  
        , cf_{&from_builtin<
338  
        , cf_{&from_builtin<
339  
            unsigned int>, &arg_.uint_}
339  
            unsigned int>, &arg_.uint_}
340  
        , what_(what::cfunc)
340  
        , what_(what::cfunc)
341  
    {
341  
    {
342  
    }
342  
    }
343  

343  

344  
    /// Overload
344  
    /// Overload
345  
    value_ref(unsigned long t) noexcept
345  
    value_ref(unsigned long t) noexcept
346  
        : arg_(t)
346  
        : arg_(t)
347  
        , cf_{&from_builtin<
347  
        , cf_{&from_builtin<
348  
            unsigned long>, &arg_.ulong_}
348  
            unsigned long>, &arg_.ulong_}
349  
        , what_(what::cfunc)
349  
        , what_(what::cfunc)
350  
    {
350  
    {
351  
    }
351  
    }
352  

352  

353  
    /// Overload
353  
    /// Overload
354  
    value_ref(unsigned long long t) noexcept
354  
    value_ref(unsigned long long t) noexcept
355  
        : arg_(t)
355  
        : arg_(t)
356  
        , cf_{&from_builtin<
356  
        , cf_{&from_builtin<
357  
            unsigned long long>, &arg_.ulong_long_}
357  
            unsigned long long>, &arg_.ulong_long_}
358  
        , what_(what::cfunc)
358  
        , what_(what::cfunc)
359  
    {
359  
    {
360  
    }
360  
    }
361  

361  

362  
    /// Overload
362  
    /// Overload
363  
    value_ref(float t) noexcept
363  
    value_ref(float t) noexcept
364  
        : arg_(t)
364  
        : arg_(t)
365  
        , cf_{&from_builtin<
365  
        , cf_{&from_builtin<
366  
            float>, &arg_.float_}
366  
            float>, &arg_.float_}
367  
        , what_(what::cfunc)
367  
        , what_(what::cfunc)
368  
    {
368  
    {
369  
    }
369  
    }
370  

370  

371  
    /// Overload
371  
    /// Overload
372  
    value_ref(double t) noexcept
372  
    value_ref(double t) noexcept
373  
        : arg_(t)
373  
        : arg_(t)
374  
        , cf_{&from_builtin<
374  
        , cf_{&from_builtin<
375  
            double>, &arg_.double_}
375  
            double>, &arg_.double_}
376  
        , what_(what::cfunc)
376  
        , what_(what::cfunc)
377  
    {
377  
    {
378  
    }
378  
    }
379  

379  

380  
    /// Overload
380  
    /// Overload
381  
    value_ref(std::nullptr_t) noexcept
381  
    value_ref(std::nullptr_t) noexcept
382  
        : arg_(nullptr)
382  
        : arg_(nullptr)
383  
        , cf_{&from_builtin<
383  
        , cf_{&from_builtin<
384  
            std::nullptr_t>, &arg_.nullptr_}
384  
            std::nullptr_t>, &arg_.nullptr_}
385  
        , what_(what::cfunc)
385  
        , what_(what::cfunc)
386  
    {
386  
    {
387  
    }
387  
    }
388  

388  

389  
    /// Overload
389  
    /// Overload
390  
    value_ref(
390  
    value_ref(
391  
        std::initializer_list<value_ref> init) noexcept
391  
        std::initializer_list<value_ref> init) noexcept
392  
        : arg_(init)
392  
        : arg_(init)
393  
        , what_(what::ini)
393  
        , what_(what::ini)
394  
    {
394  
    {
395  
    }
395  
    }
396  

396  

397  
    /// @}
397  
    /// @}
398  

398  

399  
#ifndef BOOST_JSON_DOCS
399  
#ifndef BOOST_JSON_DOCS
400  
// Not public
400  
// Not public
401  
//private:
401  
//private:
402  
    // VFALCO Why is this needed?
402  
    // VFALCO Why is this needed?
403  
    /** Operator conversion to @ref value
403  
    /** Operator conversion to @ref value
404  

404  

405  
        This allows creation of a @ref value from
405  
        This allows creation of a @ref value from
406  
        an initializer list element.
406  
        an initializer list element.
407  
    */
407  
    */
408  
    BOOST_JSON_DECL
408  
    BOOST_JSON_DECL
409  
    operator value() const;
409  
    operator value() const;
410  
#endif
410  
#endif
411  

411  

412  
private:
412  
private:
413  
    template<class T>
413  
    template<class T>
414  
    static
414  
    static
415  
    value
415  
    value
416  
    from_builtin(
416  
    from_builtin(
417  
        void const* p,
417  
        void const* p,
418  
        storage_ptr sp) noexcept;
418  
        storage_ptr sp) noexcept;
419  

419  

420  
    template<class T>
420  
    template<class T>
421  
    static
421  
    static
422  
    value
422  
    value
423  
    from_const(
423  
    from_const(
424  
        void const* p,
424  
        void const* p,
425  
        storage_ptr sp);
425  
        storage_ptr sp);
426  

426  

427  
    template<class T>
427  
    template<class T>
428  
    static
428  
    static
429  
    value
429  
    value
430  
    from_rvalue(
430  
    from_rvalue(
431  
        void* p,
431  
        void* p,
432  
        storage_ptr sp);
432  
        storage_ptr sp);
433  

433  

434  
    static
434  
    static
435  
    BOOST_JSON_DECL
435  
    BOOST_JSON_DECL
436  
    value
436  
    value
437  
    from_init_list(
437  
    from_init_list(
438  
        void const* p,
438  
        void const* p,
439  
        storage_ptr sp);
439  
        storage_ptr sp);
440  

440  

441  
    inline
441  
    inline
442  
    bool
442  
    bool
443  
    is_key_value_pair() const noexcept;
443  
    is_key_value_pair() const noexcept;
444  

444  

445  
    static
445  
    static
446  
    inline
446  
    inline
447  
    bool
447  
    bool
448  
    maybe_object(
448  
    maybe_object(
449  
        std::initializer_list<
449  
        std::initializer_list<
450  
            value_ref> init) noexcept;
450  
            value_ref> init) noexcept;
451  

451  

452  
    inline
452  
    inline
453  
    string_view
453  
    string_view
454  
    get_string() const noexcept;
454  
    get_string() const noexcept;
455  

455  

456  
    BOOST_JSON_DECL
456  
    BOOST_JSON_DECL
457  
    value
457  
    value
458  
    make_value(
458  
    make_value(
459  
        storage_ptr sp) const;
459  
        storage_ptr sp) const;
460  

460  

461  
    BOOST_JSON_DECL
461  
    BOOST_JSON_DECL
462  
    static
462  
    static
463  
    value
463  
    value
464  
    make_value(
464  
    make_value(
465  
        std::initializer_list<
465  
        std::initializer_list<
466  
            value_ref> init,
466  
            value_ref> init,
467  
        storage_ptr sp);
467  
        storage_ptr sp);
468  

468  

469  
    BOOST_JSON_DECL
469  
    BOOST_JSON_DECL
470  
    static
470  
    static
471  
    object
471  
    object
472  
    make_object(
472  
    make_object(
473  
        std::initializer_list<value_ref> init,
473  
        std::initializer_list<value_ref> init,
474  
        storage_ptr sp);
474  
        storage_ptr sp);
475  

475  

476  
    BOOST_JSON_DECL
476  
    BOOST_JSON_DECL
477  
    static
477  
    static
478  
    array
478  
    array
479  
    make_array(
479  
    make_array(
480  
        std::initializer_list<
480  
        std::initializer_list<
481  
            value_ref> init,
481  
            value_ref> init,
482  
        storage_ptr sp);
482  
        storage_ptr sp);
483  

483  

484  
    BOOST_JSON_DECL
484  
    BOOST_JSON_DECL
485  
    static
485  
    static
486  
    void
486  
    void
487  
    write_array(
487  
    write_array(
488  
        value* dest,
488  
        value* dest,
489  
        std::initializer_list<
489  
        std::initializer_list<
490  
            value_ref> init,
490  
            value_ref> init,
491  
        storage_ptr const& sp);
491  
        storage_ptr const& sp);
492  
};
492  
};
493  

493  

494  
} // namespace json
494  
} // namespace json
495  
} // namespace boost
495  
} // namespace boost
496  

496  

497  
// Must be included here for this file to stand alone
497  
// Must be included here for this file to stand alone
498  
#include <boost/json/value.hpp>
498  
#include <boost/json/value.hpp>
499  

499  

500  
// includes are at the bottom of <boost/json/value.hpp>
500  
// includes are at the bottom of <boost/json/value.hpp>
501  
//#include <boost/json/impl/value.hpp>
501  
//#include <boost/json/impl/value.hpp>
502  
//#include <boost/json/impl/value.ipp>
502  
//#include <boost/json/impl/value.ipp>
503  

503  

504  
#endif
504  
#endif