impl/value_ref.ipp

96.0% Lines (72/75) 90.9% Functions (10/11)
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_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 3236x value_ref::
21 operator
22 value() const
23 {
24 3236x return make_value({});
25 }
26
27 value
28 value_ref::
29 from_init_list(
30 void const* p,
31 storage_ptr sp)
32 {
33 return make_value(
34 *reinterpret_cast<
35 init_list const*>(p),
36 std::move(sp));
37 }
38
39 bool
40 855x value_ref::
41 is_key_value_pair() const noexcept
42 {
43 855x if(what_ != what::ini)
44 347x return false;
45 508x if(arg_.init_list_.size() != 2)
46 5x return false;
47 auto const& e =
48 503x *arg_.init_list_.begin();
49 503x if( e.what_ != what::str &&
50 25x e.what_ != what::strfunc)
51 23x return false;
52 480x return true;
53 }
54
55 bool
56 508x value_ref::
57 maybe_object(
58 std::initializer_list<
59 value_ref> init) noexcept
60 {
61 988x for(auto const& e : init)
62 855x if(! e.is_key_value_pair())
63 375x return false;
64 133x return true;
65 }
66
67 string_view
68 475x value_ref::
69 get_string() const noexcept
70 {
71 475x BOOST_ASSERT(
72 what_ == what::str ||
73 what_ == what::strfunc);
74 475x if (what_ == what::strfunc)
75 2x return *static_cast<const string*>(f_.p);
76 473x return arg_.str_;
77 }
78
79 value
80 9088x value_ref::
81 make_value(
82 storage_ptr sp) const
83 {
84 9088x switch(what_)
85 {
86 403x default:
87 case what::str:
88 806x return string(
89 arg_.str_,
90 790x std::move(sp));
91
92 170x case what::ini:
93 return make_value(
94 arg_.init_list_,
95 173x std::move(sp));
96
97 61x case what::func:
98 122x return f_.f(f_.p,
99 61x std::move(sp));
100
101 5x case what::strfunc:
102 10x return f_.f(f_.p,
103 5x std::move(sp));
104
105 8449x case what::cfunc:
106 16898x return cf_.f(cf_.p,
107 8449x std::move(sp));
108 }
109 }
110
111 value
112 172x value_ref::
113 make_value(
114 std::initializer_list<
115 value_ref> init,
116 storage_ptr sp)
117 {
118 172x if(maybe_object(init))
119 60x return make_object(
120 60x init, std::move(sp));
121 284x return make_array(
122 281x init, std::move(sp));
123 }
124
125 object
126 133x value_ref::
127 make_object(
128 std::initializer_list<value_ref> init,
129 storage_ptr sp)
130 {
131 133x object obj(std::move(sp));
132 133x obj.reserve(init.size());
133 608x for(auto const& e : init)
134 475x obj.emplace(
135 e.arg_.init_list_.begin()[0].get_string(),
136 950x e.arg_.init_list_.begin()[1].make_value(
137 obj.storage()));
138 133x return obj;
139 }
140
141 array
142 362x value_ref::
143 make_array(
144 std::initializer_list<
145 value_ref> init,
146 storage_ptr sp)
147 {
148 362x array arr(std::move(sp));
149 362x arr.reserve(init.size());
150 1366x for(auto const& e : init)
151 1007x arr.emplace_back(
152 2014x e.make_value(
153 arr.storage()));
154 359x return arr;
155 3x }
156
157 void
158 217x value_ref::
159 write_array(
160 value* dest,
161 std::initializer_list<
162 value_ref> init,
163 storage_ptr const& sp)
164 {
165 struct undo
166 {
167 value* const base;
168 value* pos;
169 217x ~undo()
170 {
171 217x if(pos)
172 36x while(pos > base)
173 20x (--pos)->~value();
174 217x }
175 };
176 217x undo u{dest, dest};
177 744x for(auto const& e : init)
178 {
179 16x ::new(u.pos) value(
180 575x e.make_value(sp));
181 527x ++u.pos;
182 }
183 201x u.pos = nullptr;
184 217x }
185
186 } // namespace json
187 } // namespace boost
188
189 #endif
190