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 3236 : value_ref::
21 : operator
22 : value() const
23 : {
24 3236 : return make_value({});
25 : }
26 :
27 : value
28 0 : 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 0 : std::move(sp));
37 : }
38 :
39 : bool
40 886 : value_ref::
41 : is_key_value_pair() const noexcept
42 : {
43 886 : if(what_ != what::ini)
44 363 : return false;
45 523 : if(arg_.init_list_.size() != 2)
46 5 : return false;
47 : auto const& e =
48 518 : *arg_.init_list_.begin();
49 518 : if( e.what_ != what::str &&
50 25 : e.what_ != what::strfunc)
51 23 : return false;
52 495 : return true;
53 : }
54 :
55 : bool
56 530 : value_ref::
57 : maybe_object(
58 : std::initializer_list<
59 : value_ref> init) noexcept
60 : {
61 1025 : for(auto const& e : init)
62 886 : if(! e.is_key_value_pair())
63 391 : return false;
64 139 : return true;
65 : }
66 :
67 : string_view
68 490 : value_ref::
69 : get_string() const noexcept
70 : {
71 490 : BOOST_ASSERT(
72 : what_ == what::str ||
73 : what_ == what::strfunc);
74 490 : if (what_ == what::strfunc)
75 2 : return *static_cast<const string*>(f_.p);
76 488 : return arg_.str_;
77 : }
78 :
79 : value
80 9160 : value_ref::
81 : make_value(
82 : storage_ptr sp) const
83 : {
84 9160 : switch(what_)
85 : {
86 473 : default:
87 : case what::str:
88 946 : return string(
89 : arg_.str_,
90 930 : std::move(sp));
91 :
92 170 : case what::ini:
93 : return make_value(
94 : arg_.init_list_,
95 173 : std::move(sp));
96 :
97 58 : case what::func:
98 116 : return f_.f(f_.p,
99 58 : std::move(sp));
100 :
101 5 : case what::strfunc:
102 10 : return f_.f(f_.p,
103 5 : std::move(sp));
104 :
105 8454 : case what::cfunc:
106 16908 : return cf_.f(cf_.p,
107 8454 : 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 139 : value_ref::
127 : make_object(
128 : std::initializer_list<value_ref> init,
129 : storage_ptr sp)
130 : {
131 139 : object obj(std::move(sp));
132 139 : obj.reserve(init.size());
133 629 : for(auto const& e : init)
134 490 : obj.emplace(
135 : e.arg_.init_list_.begin()[0].get_string(),
136 980 : e.arg_.init_list_.begin()[1].make_value(
137 : obj.storage()));
138 139 : return obj;
139 0 : }
140 :
141 : array
142 379 : value_ref::
143 : make_array(
144 : std::initializer_list<
145 : value_ref> init,
146 : storage_ptr sp)
147 : {
148 379 : array arr(std::move(sp));
149 379 : arr.reserve(init.size());
150 1434 : for(auto const& e : init)
151 1058 : arr.emplace_back(
152 2116 : e.make_value(
153 : arr.storage()));
154 376 : return arr;
155 3 : }
156 :
157 : void
158 214 : 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 214 : ~undo()
170 : {
171 214 : if(pos)
172 36 : while(pos > base)
173 20 : (--pos)->~value();
174 214 : }
175 : };
176 214 : undo u{dest, dest};
177 730 : for(auto const& e : init)
178 : {
179 16 : ::new(u.pos) value(
180 564 : e.make_value(sp));
181 516 : ++u.pos;
182 : }
183 198 : u.pos = nullptr;
184 214 : }
185 :
186 : } // namespace json
187 : } // namespace boost
188 :
189 : #endif
|