impl/value_ref.ipp

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