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_IMPL_VALUE_REF_IPP
11 : #define BOOST_JSON_IMPL_VALUE_REF_IPP
12 :
13 : #include <boost/json/value_ref.hpp>
14 : #include <boost/json/array.hpp>
15 : #include <boost/json/value.hpp>
16 :
17 : namespace boost {
18 : namespace json {
19 :
20 HIT 3241 : value_ref::
21 : operator
22 : value() const
23 : {
24 3241 : return make_value({});
25 : }
26 :
27 : bool
28 860 : value_ref::
29 : is_key_value_pair() const noexcept
30 : {
31 860 : if(what_ != what::ini)
32 351 : return false;
33 509 : if(arg_.init_list_.size() != 2)
34 6 : return false;
35 : auto const& e =
36 503 : *arg_.init_list_.begin();
37 503 : if( e.what_ != what::str &&
38 25 : e.what_ != what::strfunc)
39 23 : return false;
40 480 : return true;
41 : }
42 :
43 : bool
44 513 : value_ref::
45 : maybe_object(
46 : std::initializer_list<
47 : value_ref> init) noexcept
48 : {
49 993 : for(auto const& e : init)
50 860 : if(! e.is_key_value_pair())
51 380 : return false;
52 133 : return true;
53 : }
54 :
55 : string_view
56 475 : value_ref::
57 : get_string() const noexcept
58 : {
59 475 : BOOST_ASSERT(
60 : what_ == what::str ||
61 : what_ == what::strfunc);
62 475 : if (what_ == what::strfunc)
63 2 : return *static_cast<const string*>(f_.p);
64 473 : return arg_.str_;
65 : }
66 :
67 : value
68 9159 : value_ref::
69 : make_value(
70 : storage_ptr sp) const
71 : {
72 9159 : switch(what_)
73 : {
74 417 : default:
75 : case what::str:
76 834 : return string(
77 : arg_.str_,
78 817 : std::move(sp));
79 :
80 172 : case what::ini:
81 : return make_value(
82 : arg_.init_list_,
83 175 : std::move(sp));
84 :
85 61 : case what::func:
86 122 : return f_.f(f_.p,
87 61 : std::move(sp));
88 :
89 5 : case what::strfunc:
90 10 : return f_.f(f_.p,
91 5 : std::move(sp));
92 :
93 8504 : case what::cfunc:
94 17008 : return cf_.f(cf_.p,
95 8504 : std::move(sp));
96 : }
97 : }
98 :
99 : value
100 174 : value_ref::
101 : make_value(
102 : std::initializer_list<
103 : value_ref> init,
104 : storage_ptr sp)
105 : {
106 174 : if(maybe_object(init))
107 60 : return make_object(
108 60 : init, std::move(sp));
109 288 : return make_array(
110 285 : init, std::move(sp));
111 : }
112 :
113 : object
114 133 : value_ref::
115 : make_object(
116 : std::initializer_list<value_ref> init,
117 : storage_ptr sp)
118 : {
119 133 : object obj(std::move(sp));
120 133 : obj.reserve(init.size());
121 608 : for(auto const& e : init)
122 475 : obj.emplace(
123 : e.arg_.init_list_.begin()[0].get_string(),
124 950 : e.arg_.init_list_.begin()[1].make_value(
125 : obj.storage()));
126 133 : return obj;
127 MIS 0 : }
128 :
129 : array
130 HIT 366 : value_ref::
131 : make_array(
132 : std::initializer_list<
133 : value_ref> init,
134 : storage_ptr sp)
135 : {
136 366 : array arr(std::move(sp));
137 366 : arr.reserve(init.size());
138 1382 : for(auto const& e : init)
139 1019 : arr.emplace_back(
140 2038 : e.make_value(
141 : arr.storage()));
142 363 : return arr;
143 3 : }
144 :
145 : void
146 241 : value_ref::
147 : write_array(
148 : value* dest,
149 : std::initializer_list<
150 : value_ref> init,
151 : storage_ptr const& sp)
152 : {
153 : struct undo
154 : {
155 : value* const base;
156 : value* pos;
157 241 : ~undo()
158 : {
159 241 : if(pos)
160 40 : while(pos > base)
161 22 : (--pos)->~value();
162 241 : }
163 : };
164 241 : undo u{dest, dest};
165 817 : for(auto const& e : init)
166 : {
167 18 : ::new(u.pos) value(
168 630 : e.make_value(sp));
169 576 : ++u.pos;
170 : }
171 223 : u.pos = nullptr;
172 241 : }
173 :
174 : } // namespace json
175 : } // namespace boost
176 :
177 : #endif
|