value_ref.hpp

98.1% Lines (202/206) 98.2% List of functions (56/57)
f(x) Functions (57)
Function Calls Lines Branches Blocks
boost::json::value_ref::arg_type::arg_type() :127 101x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(boost::core::basic_string_view<char>) :128 917x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(std::initializer_list<boost::json::value_ref>) :129 659x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(signed char) :130 1x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(short) :131 3x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(int) :132 2722x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(long) :133 3x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(long long) :134 3x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(unsigned char) :135 21x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(unsigned short) :136 3x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(unsigned int) :137 45x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(unsigned long) :138 3x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(unsigned long long) :139 3x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(float) :140 18x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(double) :141 34x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(bool) :142 288x 100.0% 100.0% boost::json::value_ref::arg_type::arg_type(decltype(nullptr)) :143 88x 100.0% 100.0% boost::json::value_ref::value_ref<boost::core::basic_string_view<char>, void>(boost::core::basic_string_view<char> const&) :210 140x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::string, void>(boost::json::string const&) :210 7x 100.0% 100.0% boost::json::value_ref::value_ref<char [11], void>(char const (&) [11]) :210 0 0.0% 0.0% boost::json::value_ref::value_ref<char [12], void>(char const (&) [12]) :210 1x 100.0% 100.0% boost::json::value_ref::value_ref<char [14], void>(char const (&) [14]) :210 2x 100.0% 100.0% boost::json::value_ref::value_ref<char [17], void>(char const (&) [17]) :210 1x 100.0% 100.0% boost::json::value_ref::value_ref<char [1], void>(char const (&) [1]) :210 16x 100.0% 100.0% boost::json::value_ref::value_ref<char [20], void>(char const (&) [20]) :210 1x 100.0% 100.0% boost::json::value_ref::value_ref<char [2], void>(char const (&) [2]) :210 347x 100.0% 100.0% boost::json::value_ref::value_ref<char [3], void>(char const (&) [3]) :210 189x 100.0% 100.0% boost::json::value_ref::value_ref<char [4], void>(char const (&) [4]) :210 101x 100.0% 100.0% boost::json::value_ref::value_ref<char [5], void>(char const (&) [5]) :210 9x 100.0% 100.0% boost::json::value_ref::value_ref<char [6], void>(char const (&) [6]) :210 80x 100.0% 100.0% boost::json::value_ref::value_ref<char [7], void>(char const (&) [7]) :210 15x 100.0% 100.0% boost::json::value_ref::value_ref<char [8], void>(char const (&) [8]) :210 4x 100.0% 100.0% boost::json::value_ref::value_ref<char [9], void>(char const (&) [9]) :210 2x 100.0% 100.0% boost::json::value_ref::value_ref<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, void>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) :210 2x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::array>(boost::json::array const&, std::enable_if<(!std::is_constructible<boost::core::basic_string_view<char>, boost::json::array>::value)&&(!std::is_same<bool, boost::json::array>::value), void>::type*) :220 7x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::object>(boost::json::object const&, std::enable_if<(!std::is_constructible<boost::core::basic_string_view<char>, boost::json::object>::value)&&(!std::is_same<bool, boost::json::object>::value), void>::type*) :220 7x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::value>(boost::json::value const&, std::enable_if<(!std::is_constructible<boost::core::basic_string_view<char>, boost::json::value>::value)&&(!std::is_same<bool, boost::json::value>::value), void>::type*) :220 8x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::array>(boost::json::array&&, std::enable_if<(((!std::is_constructible<boost::core::basic_string_view<char>, boost::json::array>::value)||std::is_same<boost::json::string, boost::json::array>::value)&&(!std::is_same<bool, std::remove_cv<std::remove_reference<boost::json::array>::type>::type>::value))&&std::is_same<boost::json::array, std::remove_cv<std::remove_reference<boost::json::array>::type>::type>::value, void>::type*) :237 16x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::object>(boost::json::object&&, std::enable_if<(((!std::is_constructible<boost::core::basic_string_view<char>, boost::json::object>::value)||std::is_same<boost::json::string, boost::json::object>::value)&&(!std::is_same<bool, std::remove_cv<std::remove_reference<boost::json::object>::type>::type>::value))&&std::is_same<boost::json::object, std::remove_cv<std::remove_reference<boost::json::object>::type>::type>::value, void>::type*) :237 39x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::string>(boost::json::string&&, std::enable_if<(((!std::is_constructible<boost::core::basic_string_view<char>, boost::json::string>::value)||std::is_same<boost::json::string, boost::json::string>::value)&&(!std::is_same<bool, std::remove_cv<std::remove_reference<boost::json::string>::type>::type>::value))&&std::is_same<boost::json::string, std::remove_cv<std::remove_reference<boost::json::string>::type>::type>::value, void>::type*) :237 9x 100.0% 100.0% boost::json::value_ref::value_ref<boost::json::value>(boost::json::value&&, std::enable_if<(((!std::is_constructible<boost::core::basic_string_view<char>, boost::json::value>::value)||std::is_same<boost::json::string, boost::json::value>::value)&&(!std::is_same<bool, std::remove_cv<std::remove_reference<boost::json::value>::type>::type>::value))&&std::is_same<boost::json::value, std::remove_cv<std::remove_reference<boost::json::value>::type>::type>::value, void>::type*) :237 12x 100.0% 100.0% boost::json::value_ref::value_ref<std::vector<int, std::allocator<int> > >(std::vector<int, std::allocator<int> >&&, std::enable_if<(((!std::is_constructible<boost::core::basic_string_view<char>, std::vector<int, std::allocator<int> > >::value)||std::is_same<boost::json::string, std::vector<int, std::allocator<int> > >::value)&&(!std::is_same<bool, std::remove_cv<std::remove_reference<std::vector<int, std::allocator<int> > >::type>::type>::value))&&std::is_same<std::vector<int, std::allocator<int> >, std::remove_cv<std::remove_reference<std::vector<int, std::allocator<int> > >::type>::type>::value, void>::type*) :237 3x 100.0% 100.0% boost::json::value_ref::value_ref<bool, void>(bool) :266 288x 100.0% 100.0% boost::json::value_ref::value_ref(signed char) :276 1x 100.0% 100.0% boost::json::value_ref::value_ref(short) :284 3x 100.0% 100.0% boost::json::value_ref::value_ref(int) :292 2722x 100.0% 100.0% boost::json::value_ref::value_ref(long) :300 3x 100.0% 100.0% boost::json::value_ref::value_ref(long long) :309 3x 100.0% 100.0% boost::json::value_ref::value_ref(unsigned char) :318 21x 100.0% 100.0% boost::json::value_ref::value_ref(unsigned short) :327 3x 100.0% 100.0% boost::json::value_ref::value_ref(unsigned int) :336 45x 100.0% 100.0% boost::json::value_ref::value_ref(unsigned long) :345 3x 100.0% 100.0% boost::json::value_ref::value_ref(unsigned long long) :354 3x 100.0% 100.0% boost::json::value_ref::value_ref(float) :363 18x 100.0% 100.0% boost::json::value_ref::value_ref(double) :372 34x 100.0% 100.0% boost::json::value_ref::value_ref(decltype(nullptr)) :381 88x 100.0% 100.0% boost::json::value_ref::value_ref(std::initializer_list<boost::json::value_ref>) :390 659x 100.0% 100.0%
Line TLA 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_VALUE_REF_HPP
11 #define BOOST_JSON_VALUE_REF_HPP
12
13 #include <boost/json/detail/config.hpp>
14 #include <boost/json/storage_ptr.hpp>
15 #include <boost/json/string.hpp>
16 #include <initializer_list>
17 #include <type_traits>
18 #include <utility>
19
20 namespace boost {
21 namespace json {
22
23 #ifndef BOOST_JSON_DOCS
24 class value;
25 class object;
26 class array;
27 class string;
28 #endif
29
30 //----------------------------------------------------------
31
32 /** The type used in initializer lists.
33
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.
36 The two types of initializer lists used are:
37
38 @li `std::initializer_list< value_ref >` for constructing or assigning
39 a @ref value or @ref array, and
40 @li `std::initializer_list< std::pair< string_view, value_ref > >` for
41 constructing or assigning an @ref object.
42
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
45 means that the @ref boost::container::pmr::memory_resource used to
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
48 constructing a @ref value until it's necessary.
49
50 @par Example
51 This example demonstrates how a user-defined type containing a JSON value
52 can be constructed from an initializer list:
53
54 @code
55 class my_type
56 {
57 value jv_;
58
59 public:
60 my_type( std::initializer_list<value_ref> init )
61 : jv_(init)
62 {
63 }
64 };
65 @endcode
66
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`
69 object is used, you will get undefined behavior. Because of this it is
70 advised against declaring a variable of type
71 `std::initializer_list<value_ref>` except in function parameter lists.
72
73 @see @ref value, @ref array, @ref object, @ref value::set_at_pointer.
74 */
75 class value_ref
76 {
77 friend class value;
78 friend class object;
79 friend class array;
80
81 friend class value_ref_test;
82
83 enum class what
84 {
85 str,
86 ini,
87 func,
88 cfunc,
89 strfunc,
90 };
91
92 using init_list =
93 std::initializer_list<value_ref>;
94
95 struct func_type
96 {
97 value(*f)(void*, storage_ptr);
98 void* p;
99 };
100
101 struct cfunc_type
102 {
103 value(*f)(void const*, storage_ptr);
104 void const* p;
105 };
106
107 union arg_type
108 {
109 string_view str_;
110 init_list init_list_;
111
112 signed char schar_;
113 short short_;
114 int int_;
115 long long_;
116 long long long_long_;
117 unsigned char uchar_;
118 unsigned short ushort_;
119 unsigned int uint_;
120 unsigned long ulong_;
121 unsigned long long ulong_long_;
122 float float_;
123 double double_;
124 bool bool_;
125 std::nullptr_t nullptr_;
126
127 101x arg_type() {}
128 917x explicit arg_type(string_view t) noexcept : str_(t) {}
129 659x explicit arg_type(init_list t) noexcept : init_list_(t) {}
130 1x explicit arg_type(signed char t) noexcept : schar_(t) {}
131 3x explicit arg_type(short t) noexcept : short_(t) {}
132 2722x explicit arg_type(int t) noexcept : int_(t) {}
133 3x explicit arg_type(long t) noexcept : long_(t) {}
134 3x explicit arg_type(long long t) noexcept : long_long_(t) {}
135 21x explicit arg_type(unsigned char t) noexcept : uchar_(t) {}
136 3x explicit arg_type(unsigned short t) noexcept : ushort_(t) {}
137 45x explicit arg_type(unsigned int t) noexcept : uint_(t) {}
138 3x explicit arg_type(unsigned long t) noexcept : ulong_(t) {}
139 3x explicit arg_type(unsigned long long t) noexcept : ulong_long_(t) {}
140 18x explicit arg_type(float t) noexcept : float_(t) {}
141 34x explicit arg_type(double t) noexcept : double_(t) {}
142 288x explicit arg_type(bool t) noexcept : bool_(t) {}
143 88x explicit arg_type(std::nullptr_t) noexcept : nullptr_() {}
144 };
145
146 arg_type arg_;
147 #ifndef BOOST_JSON_DOCS
148 // VFALCO doc toolchain erroneously
149 // displays private, anonymous unions as public
150 union
151 {
152 func_type f_;
153 cfunc_type cf_;
154 };
155 #endif
156 what what_;
157
158 public:
159 /** Constructors.
160
161 @li **(1)** copy constructor.
162 @li **(2)** move constructor.
163 @li **(3)** the constructed value stores a reference to `t`'s character
164 array.
165 @li **(4)** the constructed value stores a `const` 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`.
168 @li **(7)**--**(18)** the constructed value stores a copy of `t`.
169 @li **(19)** the constrcuted value stores `nullptr`.
170 @li **(20)** the constrcuted value stores a copy of `init`.
171
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
174 the stored data.
175
176 @warning The overloads that accept references do not take ownership of
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.
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
181 not invoke undefeined behavior.
182
183 @par Complexity
184 @li **(1)**--**(19)** constant.
185 @li **(20)** linear in `init.size()`.
186
187 @par Exception Safety
188 No-throw guarantee.
189
190 @{
191 */
192 value_ref(
193 value_ref const&) = default;
194
195 /// Overload
196 value_ref(
197 value_ref&&) = default;
198
199 /// Overload
200 #ifdef BOOST_JSON_DOCS
201 value_ref(string_view s) noexcept;
202 #else
203 template<
204 class T
205 ,class = typename
206 std::enable_if<
207 std::is_constructible<
208 string_view, T>::value>::type
209 >
210 917x value_ref(
211 T const& t) noexcept
212 917x : arg_(string_view(t))
213 917x , what_(what::str)
214 {
215 917x }
216 #endif
217
218 /// Overload
219 template<class T>
220 22x value_ref(
221 T const& t
222 #ifndef BOOST_JSON_DOCS
223 ,typename std::enable_if<
224 ! std::is_constructible<
225 string_view, T>::value &&
226 ! std::is_same<bool, T>::value
227 >::type* = 0
228 #endif
229 ) noexcept
230 22x : cf_{&from_const<T>, &t}
231 22x , what_(what::cfunc)
232 {
233 22x }
234
235 /// Overload
236 template<class T>
237 79x value_ref(
238 T&& t
239 #ifndef BOOST_JSON_DOCS
240 ,typename std::enable_if<
241 (! std::is_constructible<
242 string_view, T>::value ||
243 std::is_same<string, T>::value) &&
244 ! std::is_same<bool,
245 detail::remove_cvref<T>>::value &&
246 std::is_same<T, detail::remove_cvref<T>>
247 ::value>::type* = 0
248 #endif
249 ) noexcept
250 79x : f_{&from_rvalue<
251 detail::remove_cvref<T>>, &t}
252 79x , what_(std::is_same<string, T>::value ?
253 79x what::strfunc : what::func)
254 {
255 79x }
256
257 /// Overload
258 #ifdef BOOST_JSON_DOCS
259 value_ref(bool b) noexcept;
260 #else
261 template<
262 class T
263 ,class = typename std::enable_if<
264 std::is_same<T, bool>::value>::type
265 >
266 288x value_ref(
267 T b) noexcept
268 288x : arg_(b)
269 288x , cf_{&from_builtin<bool>, &arg_.bool_}
270 288x , what_(what::cfunc)
271 {
272 288x }
273 #endif
274
275 /// Overload
276 1x value_ref(signed char t) noexcept
277 1x : arg_(t)
278 1x , cf_{&from_builtin<signed char>, &arg_.schar_}
279 1x , what_(what::cfunc)
280 {
281 1x }
282
283 /// Overload
284 3x value_ref(short t) noexcept
285 3x : arg_(t)
286 3x , cf_{&from_builtin<short>, &arg_.short_}
287 3x , what_(what::cfunc)
288 {
289 3x }
290
291 /// Overload
292 2722x value_ref(int t) noexcept
293 2722x : arg_(t)
294 2722x , cf_{&from_builtin<int>, &arg_.int_}
295 2722x , what_(what::cfunc)
296 {
297 2722x }
298
299 /// Overload
300 3x value_ref(long t) noexcept
301 3x : arg_(t)
302 3x , cf_{&from_builtin<
303 3x long>, &arg_.long_}
304 3x , what_(what::cfunc)
305 {
306 3x }
307
308 /// Overload
309 3x value_ref(long long t) noexcept
310 3x : arg_(t)
311 3x , cf_{&from_builtin<
312 3x long long>, &arg_.long_long_}
313 3x , what_(what::cfunc)
314 {
315 3x }
316
317 /// Overload
318 21x value_ref(unsigned char t) noexcept
319 21x : arg_(t)
320 21x , cf_{&from_builtin<
321 21x unsigned char>, &arg_.uchar_}
322 21x , what_(what::cfunc)
323 {
324 21x }
325
326 /// Overload
327 3x value_ref(unsigned short t) noexcept
328 3x : arg_(t)
329 3x , cf_{&from_builtin<
330 3x unsigned short>, &arg_.ushort_}
331 3x , what_(what::cfunc)
332 {
333 3x }
334
335 /// Overload
336 45x value_ref(unsigned int t) noexcept
337 45x : arg_(t)
338 45x , cf_{&from_builtin<
339 45x unsigned int>, &arg_.uint_}
340 45x , what_(what::cfunc)
341 {
342 45x }
343
344 /// Overload
345 3x value_ref(unsigned long t) noexcept
346 3x : arg_(t)
347 3x , cf_{&from_builtin<
348 3x unsigned long>, &arg_.ulong_}
349 3x , what_(what::cfunc)
350 {
351 3x }
352
353 /// Overload
354 3x value_ref(unsigned long long t) noexcept
355 3x : arg_(t)
356 3x , cf_{&from_builtin<
357 3x unsigned long long>, &arg_.ulong_long_}
358 3x , what_(what::cfunc)
359 {
360 3x }
361
362 /// Overload
363 18x value_ref(float t) noexcept
364 18x : arg_(t)
365 18x , cf_{&from_builtin<
366 18x float>, &arg_.float_}
367 18x , what_(what::cfunc)
368 {
369 18x }
370
371 /// Overload
372 34x value_ref(double t) noexcept
373 34x : arg_(t)
374 34x , cf_{&from_builtin<
375 34x double>, &arg_.double_}
376 34x , what_(what::cfunc)
377 {
378 34x }
379
380 /// Overload
381 88x value_ref(std::nullptr_t) noexcept
382 88x : arg_(nullptr)
383 88x , cf_{&from_builtin<
384 88x std::nullptr_t>, &arg_.nullptr_}
385 88x , what_(what::cfunc)
386 {
387 88x }
388
389 /// Overload
390 659x value_ref(
391 std::initializer_list<value_ref> init) noexcept
392 659x : arg_(init)
393 659x , what_(what::ini)
394 {
395 659x }
396
397 /// @}
398
399 #ifndef BOOST_JSON_DOCS
400 // Not public
401 //private:
402 // VFALCO Why is this needed?
403 /** Operator conversion to @ref value
404
405 This allows creation of a @ref value from
406 an initializer list element.
407 */
408 BOOST_JSON_DECL
409 operator value() const;
410 #endif
411
412 private:
413 template<class T>
414 static
415 value
416 from_builtin(
417 void const* p,
418 storage_ptr sp) noexcept;
419
420 template<class T>
421 static
422 value
423 from_const(
424 void const* p,
425 storage_ptr sp);
426
427 template<class T>
428 static
429 value
430 from_rvalue(
431 void* p,
432 storage_ptr sp);
433
434 static
435 BOOST_JSON_DECL
436 value
437 from_init_list(
438 void const* p,
439 storage_ptr sp);
440
441 inline
442 bool
443 is_key_value_pair() const noexcept;
444
445 static
446 inline
447 bool
448 maybe_object(
449 std::initializer_list<
450 value_ref> init) noexcept;
451
452 inline
453 string_view
454 get_string() const noexcept;
455
456 BOOST_JSON_DECL
457 value
458 make_value(
459 storage_ptr sp) const;
460
461 BOOST_JSON_DECL
462 static
463 value
464 make_value(
465 std::initializer_list<
466 value_ref> init,
467 storage_ptr sp);
468
469 BOOST_JSON_DECL
470 static
471 object
472 make_object(
473 std::initializer_list<value_ref> init,
474 storage_ptr sp);
475
476 BOOST_JSON_DECL
477 static
478 array
479 make_array(
480 std::initializer_list<
481 value_ref> init,
482 storage_ptr sp);
483
484 BOOST_JSON_DECL
485 static
486 void
487 write_array(
488 value* dest,
489 std::initializer_list<
490 value_ref> init,
491 storage_ptr const& sp);
492 };
493
494 } // namespace json
495 } // namespace boost
496
497 // Must be included here for this file to stand alone
498 #include <boost/json/value.hpp>
499
500 // includes are at the bottom of <boost/json/value.hpp>
501 //#include <boost/json/impl/value.hpp>
502 //#include <boost/json/impl/value.ipp>
503
504 #endif
505