/src/boost/boost/json/impl/value_stack.ipp
Line | Count | Source |
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_STACK_IPP |
11 | | #define BOOST_JSON_IMPL_VALUE_STACK_IPP |
12 | | |
13 | | #include <boost/json/value_stack.hpp> |
14 | | #include <cstring> |
15 | | #include <stdexcept> |
16 | | #include <utility> |
17 | | |
18 | | namespace boost { |
19 | | namespace json { |
20 | | |
21 | | //-------------------------------------- |
22 | | |
23 | | value_stack:: |
24 | | stack:: |
25 | | ~stack() |
26 | 22.1k | { |
27 | 22.1k | clear(); |
28 | 22.1k | if( begin_ != temp_ && |
29 | 8.70k | begin_ != nullptr) |
30 | 8.50k | sp_->deallocate( |
31 | 8.50k | begin_, |
32 | 8.50k | (end_ - begin_) * |
33 | 8.50k | sizeof(value)); |
34 | 22.1k | } |
35 | | |
36 | | value_stack:: |
37 | | stack:: |
38 | | stack( |
39 | | storage_ptr sp, |
40 | | void* temp, |
41 | | std::size_t size) noexcept |
42 | 22.1k | : sp_(std::move(sp)) |
43 | 22.1k | , temp_(temp) |
44 | 22.1k | { |
45 | 22.1k | if(size >= min_size_ * |
46 | 22.1k | sizeof(value)) |
47 | 13.2k | { |
48 | 13.2k | begin_ = reinterpret_cast< |
49 | 13.2k | value*>(temp); |
50 | 13.2k | top_ = begin_; |
51 | 13.2k | end_ = begin_ + |
52 | 13.2k | size / sizeof(value); |
53 | 13.2k | } |
54 | 8.94k | else |
55 | 8.94k | { |
56 | 8.94k | begin_ = nullptr; |
57 | 8.94k | top_ = nullptr; |
58 | 8.94k | end_ = nullptr; |
59 | 8.94k | } |
60 | 22.1k | } |
61 | | |
62 | | void |
63 | | value_stack:: |
64 | | stack:: |
65 | | run_dtors(bool b) noexcept |
66 | 35.9k | { |
67 | 35.9k | run_dtors_ = b; |
68 | 35.9k | } |
69 | | |
70 | | std::size_t |
71 | | value_stack:: |
72 | | stack:: |
73 | | size() const noexcept |
74 | 9.73k | { |
75 | 9.73k | return top_ - begin_; |
76 | 9.73k | } |
77 | | |
78 | | bool |
79 | | value_stack:: |
80 | | stack:: |
81 | | has_chars() |
82 | 1.82M | { |
83 | 1.82M | return chars_ != 0; |
84 | 1.82M | } |
85 | | |
86 | | //-------------------------------------- |
87 | | |
88 | | // destroy the values but |
89 | | // not the stack allocation. |
90 | | void |
91 | | value_stack:: |
92 | | stack:: |
93 | | clear() noexcept |
94 | 58.0k | { |
95 | 58.0k | if(top_ != begin_) |
96 | 8.28k | { |
97 | 8.28k | if(run_dtors_) |
98 | 5.63k | for(auto it = top_; |
99 | 1.16M | it-- != begin_;) |
100 | 1.16M | it->~value(); |
101 | 8.28k | top_ = begin_; |
102 | 8.28k | } |
103 | 58.0k | chars_ = 0; |
104 | 58.0k | } |
105 | | |
106 | | void |
107 | | value_stack:: |
108 | | stack:: |
109 | | maybe_grow() |
110 | 21.1k | { |
111 | 21.1k | if(top_ >= end_) |
112 | 148 | grow_one(); |
113 | 21.1k | } |
114 | | |
115 | | // make room for at least one more value |
116 | | void |
117 | | value_stack:: |
118 | | stack:: |
119 | | grow_one() |
120 | 14.2k | { |
121 | 14.2k | BOOST_ASSERT(chars_ == 0); |
122 | 14.2k | std::size_t const capacity = |
123 | 14.2k | end_ - begin_; |
124 | 14.2k | std::size_t new_cap = min_size_; |
125 | | // VFALCO check overflow here |
126 | 39.8k | while(new_cap < capacity + 1) |
127 | 25.6k | new_cap <<= 1; |
128 | 14.2k | auto const begin = |
129 | 14.2k | reinterpret_cast<value*>( |
130 | 14.2k | sp_->allocate( |
131 | 14.2k | new_cap * sizeof(value))); |
132 | 14.2k | std::size_t const cur_size = top_ - begin_; |
133 | 14.2k | if(begin_) |
134 | 6.57k | { |
135 | 6.57k | std::memcpy( |
136 | 6.57k | reinterpret_cast<char*>(begin), |
137 | 6.57k | reinterpret_cast<char*>(begin_), |
138 | 6.57k | size() * sizeof(value)); |
139 | 6.57k | if(begin_ != temp_) |
140 | 6.35k | sp_->deallocate(begin_, |
141 | 6.35k | capacity * sizeof(value)); |
142 | 6.57k | } |
143 | | // book-keeping |
144 | 14.2k | top_ = begin + cur_size; |
145 | 14.2k | end_ = begin + new_cap; |
146 | 14.2k | begin_ = begin; |
147 | 14.2k | } |
148 | | |
149 | | // make room for nchars additional characters. |
150 | | void |
151 | | value_stack:: |
152 | | stack:: |
153 | | grow(std::size_t nchars) |
154 | 1.79k | { |
155 | | // needed capacity in values |
156 | 1.79k | std::size_t const needed = |
157 | 1.79k | size() + |
158 | 1.79k | 1 + |
159 | 1.79k | ((chars_ + nchars + |
160 | 1.79k | sizeof(value) - 1) / |
161 | 1.79k | sizeof(value)); |
162 | 1.79k | std::size_t const capacity = |
163 | 1.79k | end_ - begin_; |
164 | 1.79k | BOOST_ASSERT( |
165 | 1.79k | needed > capacity); |
166 | 1.79k | std::size_t new_cap = min_size_; |
167 | | // VFALCO check overflow here |
168 | 9.78k | while(new_cap < needed) |
169 | 7.99k | new_cap <<= 1; |
170 | 1.79k | auto const begin = |
171 | 1.79k | reinterpret_cast<value*>( |
172 | 1.79k | sp_->allocate( |
173 | 1.79k | new_cap * sizeof(value))); |
174 | 1.79k | std::size_t const cur_size = top_ - begin_; |
175 | 1.79k | if(begin_) |
176 | 1.37k | { |
177 | 1.37k | std::size_t amount = |
178 | 1.37k | size() * sizeof(value); |
179 | 1.37k | if(chars_ > 0) |
180 | 1.00k | amount += sizeof(value) + chars_; |
181 | 1.37k | std::memcpy( |
182 | 1.37k | reinterpret_cast<char*>(begin), |
183 | 1.37k | reinterpret_cast<char*>(begin_), |
184 | 1.37k | amount); |
185 | 1.37k | if(begin_ != temp_) |
186 | 1.00k | sp_->deallocate(begin_, |
187 | 1.00k | capacity * sizeof(value)); |
188 | 1.37k | } |
189 | | // book-keeping |
190 | 1.79k | top_ = begin + cur_size; |
191 | 1.79k | end_ = begin + new_cap; |
192 | 1.79k | begin_ = begin; |
193 | 1.79k | } |
194 | | |
195 | | //-------------------------------------- |
196 | | |
197 | | void |
198 | | value_stack:: |
199 | | stack:: |
200 | | append(string_view s) |
201 | 155k | { |
202 | 155k | std::size_t const bytes_avail = |
203 | 155k | reinterpret_cast< |
204 | 155k | char const*>(end_) - |
205 | 155k | reinterpret_cast< |
206 | 155k | char const*>(top_); |
207 | | // make sure there is room for |
208 | | // pushing one more value without |
209 | | // clobbering the string. |
210 | 155k | if(sizeof(value) + chars_ + |
211 | 155k | s.size() > bytes_avail) |
212 | 1.79k | grow(s.size()); |
213 | | |
214 | | // copy the new piece |
215 | 155k | std::memcpy( |
216 | 155k | reinterpret_cast<char*>( |
217 | 155k | top_ + 1) + chars_, |
218 | 155k | s.data(), s.size()); |
219 | 155k | chars_ += s.size(); |
220 | | |
221 | | // ensure a pushed value cannot |
222 | | // clobber the released string. |
223 | 155k | BOOST_ASSERT( |
224 | 155k | reinterpret_cast<char*>( |
225 | 155k | top_ + 1) + chars_ <= |
226 | 155k | reinterpret_cast<char*>( |
227 | 155k | end_)); |
228 | 155k | } |
229 | | |
230 | | string_view |
231 | | value_stack:: |
232 | | stack:: |
233 | | release_string() noexcept |
234 | 17.5k | { |
235 | | // ensure a pushed value cannot |
236 | | // clobber the released string. |
237 | 17.5k | BOOST_ASSERT( |
238 | 17.5k | reinterpret_cast<char*>( |
239 | 17.5k | top_ + 1) + chars_ <= |
240 | 17.5k | reinterpret_cast<char*>( |
241 | 17.5k | end_)); |
242 | 17.5k | auto const n = chars_; |
243 | 17.5k | chars_ = 0; |
244 | 17.5k | return { reinterpret_cast< |
245 | 17.5k | char const*>(top_ + 1), n }; |
246 | 17.5k | } |
247 | | |
248 | | // transfer ownership of the top n |
249 | | // elements of the stack to the caller |
250 | | value* |
251 | | value_stack:: |
252 | | stack:: |
253 | | release(std::size_t n) noexcept |
254 | 60.0k | { |
255 | 60.0k | BOOST_ASSERT(n <= size()); |
256 | 60.0k | BOOST_ASSERT(chars_ == 0); |
257 | 60.0k | top_ -= n; |
258 | 60.0k | return top_; |
259 | 60.0k | } |
260 | | |
261 | | template<class... Args> |
262 | | value& |
263 | | value_stack:: |
264 | | stack:: |
265 | | push(Args&&... args) |
266 | 14.4M | { |
267 | 14.4M | BOOST_ASSERT(chars_ == 0); |
268 | 14.4M | if(top_ >= end_) |
269 | 14.0k | grow_one(); |
270 | 14.4M | value& jv = detail::access:: |
271 | 14.4M | construct_value(top_, |
272 | 14.4M | std::forward<Args>(args)...); |
273 | 14.4M | ++top_; |
274 | 14.4M | return jv; |
275 | 14.4M | } boost::json::value& boost::json::value_stack::stack::push<boost::json::detail::key_t, boost::core::basic_string_view<char>&, boost::json::storage_ptr&>(boost::json::detail::key_t&&, boost::core::basic_string_view<char>&, boost::json::storage_ptr&) Line | Count | Source | 266 | 1.76M | { | 267 | 1.76M | BOOST_ASSERT(chars_ == 0); | 268 | 1.76M | if(top_ >= end_) | 269 | 1.48k | grow_one(); | 270 | 1.76M | value& jv = detail::access:: | 271 | 1.76M | construct_value(top_, | 272 | 1.76M | std::forward<Args>(args)...); | 273 | 1.76M | ++top_; | 274 | 1.76M | return jv; | 275 | 1.76M | } |
boost::json::value& boost::json::value_stack::stack::push<boost::json::detail::key_t, boost::core::basic_string_view<char>&, boost::core::basic_string_view<char>&, boost::json::storage_ptr&>(boost::json::detail::key_t&&, boost::core::basic_string_view<char>&, boost::core::basic_string_view<char>&, boost::json::storage_ptr&) Line | Count | Source | 266 | 8.26k | { | 267 | 8.26k | BOOST_ASSERT(chars_ == 0); | 268 | 8.26k | if(top_ >= end_) | 269 | 0 | grow_one(); | 270 | 8.26k | value& jv = detail::access:: | 271 | 8.26k | construct_value(top_, | 272 | 8.26k | std::forward<Args>(args)...); | 273 | 8.26k | ++top_; | 274 | 8.26k | return jv; | 275 | 8.26k | } |
boost::json::value& boost::json::value_stack::stack::push<boost::core::basic_string_view<char>&, boost::json::storage_ptr&>(boost::core::basic_string_view<char>&, boost::json::storage_ptr&) Line | Count | Source | 266 | 36.4k | { | 267 | 36.4k | BOOST_ASSERT(chars_ == 0); | 268 | 36.4k | if(top_ >= end_) | 269 | 290 | grow_one(); | 270 | 36.4k | value& jv = detail::access:: | 271 | 36.4k | construct_value(top_, | 272 | 36.4k | std::forward<Args>(args)...); | 273 | 36.4k | ++top_; | 274 | 36.4k | return jv; | 275 | 36.4k | } |
boost::json::value& boost::json::value_stack::stack::push<boost::json::string_kind_t const&, boost::json::storage_ptr&>(boost::json::string_kind_t const&, boost::json::storage_ptr&) Line | Count | Source | 266 | 9.28k | { | 267 | 9.28k | BOOST_ASSERT(chars_ == 0); | 268 | 9.28k | if(top_ >= end_) | 269 | 0 | grow_one(); | 270 | 9.28k | value& jv = detail::access:: | 271 | 9.28k | construct_value(top_, | 272 | 9.28k | std::forward<Args>(args)...); | 273 | 9.28k | ++top_; | 274 | 9.28k | return jv; | 275 | 9.28k | } |
boost::json::value& boost::json::value_stack::stack::push<long&, boost::json::storage_ptr&>(long&, boost::json::storage_ptr&) Line | Count | Source | 266 | 7.09M | { | 267 | 7.09M | BOOST_ASSERT(chars_ == 0); | 268 | 7.09M | if(top_ >= end_) | 269 | 2.97k | grow_one(); | 270 | 7.09M | value& jv = detail::access:: | 271 | 7.09M | construct_value(top_, | 272 | 7.09M | std::forward<Args>(args)...); | 273 | 7.09M | ++top_; | 274 | 7.09M | return jv; | 275 | 7.09M | } |
boost::json::value& boost::json::value_stack::stack::push<unsigned long&, boost::json::storage_ptr&>(unsigned long&, boost::json::storage_ptr&) Line | Count | Source | 266 | 28.3k | { | 267 | 28.3k | BOOST_ASSERT(chars_ == 0); | 268 | 28.3k | if(top_ >= end_) | 269 | 309 | grow_one(); | 270 | 28.3k | value& jv = detail::access:: | 271 | 28.3k | construct_value(top_, | 272 | 28.3k | std::forward<Args>(args)...); | 273 | 28.3k | ++top_; | 274 | 28.3k | return jv; | 275 | 28.3k | } |
boost::json::value& boost::json::value_stack::stack::push<double&, boost::json::storage_ptr&>(double&, boost::json::storage_ptr&) Line | Count | Source | 266 | 5.40M | { | 267 | 5.40M | BOOST_ASSERT(chars_ == 0); | 268 | 5.40M | if(top_ >= end_) | 269 | 8.74k | grow_one(); | 270 | 5.40M | value& jv = detail::access:: | 271 | 5.40M | construct_value(top_, | 272 | 5.40M | std::forward<Args>(args)...); | 273 | 5.40M | ++top_; | 274 | 5.40M | return jv; | 275 | 5.40M | } |
boost::json::value& boost::json::value_stack::stack::push<bool&, boost::json::storage_ptr&>(bool&, boost::json::storage_ptr&) Line | Count | Source | 266 | 48.6k | { | 267 | 48.6k | BOOST_ASSERT(chars_ == 0); | 268 | 48.6k | if(top_ >= end_) | 269 | 145 | grow_one(); | 270 | 48.6k | value& jv = detail::access:: | 271 | 48.6k | construct_value(top_, | 272 | 48.6k | std::forward<Args>(args)...); | 273 | 48.6k | ++top_; | 274 | 48.6k | return jv; | 275 | 48.6k | } |
boost::json::value& boost::json::value_stack::stack::push<decltype(nullptr), boost::json::storage_ptr&>(decltype(nullptr)&&, boost::json::storage_ptr&) Line | Count | Source | 266 | 15.6k | { | 267 | 15.6k | BOOST_ASSERT(chars_ == 0); | 268 | 15.6k | if(top_ >= end_) | 269 | 109 | grow_one(); | 270 | 15.6k | value& jv = detail::access:: | 271 | 15.6k | construct_value(top_, | 272 | 15.6k | std::forward<Args>(args)...); | 273 | 15.6k | ++top_; | 274 | 15.6k | return jv; | 275 | 15.6k | } |
|
276 | | |
277 | | template<class Unchecked> |
278 | | void |
279 | | value_stack:: |
280 | | stack:: |
281 | | exchange(Unchecked&& u) |
282 | 50.9k | { |
283 | 50.9k | BOOST_ASSERT(chars_ == 0); |
284 | 50.9k | union U |
285 | 50.9k | { |
286 | 50.9k | value v; |
287 | 50.9k | U() {}boost::json::value_stack::stack::exchange<boost::json::detail::unchecked_array>(boost::json::detail::unchecked_array&&)::U::U() Line | Count | Source | 287 | 27.5k | U() {} |
boost::json::value_stack::stack::exchange<boost::json::detail::unchecked_object>(boost::json::detail::unchecked_object&&)::U::U() Line | Count | Source | 287 | 23.4k | U() {} |
|
288 | 50.9k | ~U() {}boost::json::value_stack::stack::exchange<boost::json::detail::unchecked_array>(boost::json::detail::unchecked_array&&)::U::~U() Line | Count | Source | 288 | 27.5k | ~U() {} |
boost::json::value_stack::stack::exchange<boost::json::detail::unchecked_object>(boost::json::detail::unchecked_object&&)::U::~U() Line | Count | Source | 288 | 23.4k | ~U() {} |
|
289 | 50.9k | } jv; |
290 | | // construct value on the stack |
291 | | // to avoid clobbering top_[0], |
292 | | // which belongs to `u`. |
293 | 50.9k | detail::access:: |
294 | 50.9k | construct_value( |
295 | 50.9k | &jv.v, std::move(u)); |
296 | 50.9k | std::memcpy( |
297 | 50.9k | reinterpret_cast< |
298 | 50.9k | char*>(top_), |
299 | 50.9k | &jv.v, sizeof(value)); |
300 | 50.9k | ++top_; |
301 | 50.9k | } void boost::json::value_stack::stack::exchange<boost::json::detail::unchecked_array>(boost::json::detail::unchecked_array&&) Line | Count | Source | 282 | 27.5k | { | 283 | 27.5k | BOOST_ASSERT(chars_ == 0); | 284 | 27.5k | union U | 285 | 27.5k | { | 286 | 27.5k | value v; | 287 | 27.5k | U() {} | 288 | 27.5k | ~U() {} | 289 | 27.5k | } jv; | 290 | | // construct value on the stack | 291 | | // to avoid clobbering top_[0], | 292 | | // which belongs to `u`. | 293 | 27.5k | detail::access:: | 294 | 27.5k | construct_value( | 295 | 27.5k | &jv.v, std::move(u)); | 296 | 27.5k | std::memcpy( | 297 | 27.5k | reinterpret_cast< | 298 | 27.5k | char*>(top_), | 299 | 27.5k | &jv.v, sizeof(value)); | 300 | 27.5k | ++top_; | 301 | 27.5k | } |
void boost::json::value_stack::stack::exchange<boost::json::detail::unchecked_object>(boost::json::detail::unchecked_object&&) Line | Count | Source | 282 | 23.4k | { | 283 | 23.4k | BOOST_ASSERT(chars_ == 0); | 284 | 23.4k | union U | 285 | 23.4k | { | 286 | 23.4k | value v; | 287 | 23.4k | U() {} | 288 | 23.4k | ~U() {} | 289 | 23.4k | } jv; | 290 | | // construct value on the stack | 291 | | // to avoid clobbering top_[0], | 292 | | // which belongs to `u`. | 293 | 23.4k | detail::access:: | 294 | 23.4k | construct_value( | 295 | 23.4k | &jv.v, std::move(u)); | 296 | 23.4k | std::memcpy( | 297 | 23.4k | reinterpret_cast< | 298 | 23.4k | char*>(top_), | 299 | 23.4k | &jv.v, sizeof(value)); | 300 | 23.4k | ++top_; | 301 | 23.4k | } |
|
302 | | |
303 | | //---------------------------------------------------------- |
304 | | |
305 | | value_stack:: |
306 | | ~value_stack() |
307 | 22.1k | { |
308 | | // default dtor is here so the |
309 | | // definition goes in the library |
310 | | // instead of the caller's TU. |
311 | 22.1k | } |
312 | | |
313 | | value_stack:: |
314 | | value_stack( |
315 | | storage_ptr sp, |
316 | | unsigned char* temp_buffer, |
317 | | std::size_t temp_size) noexcept |
318 | 22.1k | : st_( |
319 | 22.1k | std::move(sp), |
320 | 22.1k | temp_buffer, |
321 | 22.1k | temp_size) |
322 | 22.1k | { |
323 | 22.1k | } |
324 | | |
325 | | void |
326 | | value_stack:: |
327 | | reset(storage_ptr sp) noexcept |
328 | 35.9k | { |
329 | 35.9k | st_.clear(); |
330 | | |
331 | 35.9k | sp_.~storage_ptr(); |
332 | 35.9k | ::new(&sp_) storage_ptr( |
333 | 35.9k | pilfer(sp)); |
334 | | |
335 | | // `stack` needs this |
336 | | // to clean up correctly |
337 | 35.9k | st_.run_dtors( |
338 | 35.9k | ! sp_.is_not_shared_and_deallocate_is_trivial()); |
339 | 35.9k | } |
340 | | |
341 | | value |
342 | | value_stack:: |
343 | | release() noexcept |
344 | 9.14k | { |
345 | | // This means the caller did not |
346 | | // cause a single top level element |
347 | | // to be produced. |
348 | 9.14k | BOOST_ASSERT(st_.size() == 1); |
349 | | |
350 | | // give up shared ownership |
351 | 9.14k | sp_ = {}; |
352 | | |
353 | 9.14k | return pilfer(*st_.release(1)); |
354 | 9.14k | } |
355 | | |
356 | | //---------------------------------------------------------- |
357 | | |
358 | | void |
359 | | value_stack:: |
360 | | push_array(std::size_t n) |
361 | 27.5k | { |
362 | | // we already have room if n > 0 |
363 | 27.5k | if(BOOST_JSON_UNLIKELY(n == 0)) |
364 | 6.77k | st_.maybe_grow(); |
365 | 27.5k | detail::unchecked_array ua( |
366 | 27.5k | st_.release(n), n, sp_); |
367 | 27.5k | st_.exchange(std::move(ua)); |
368 | 27.5k | } |
369 | | |
370 | | void |
371 | | value_stack:: |
372 | | push_object(std::size_t n) |
373 | 23.4k | { |
374 | | // we already have room if n > 0 |
375 | 23.4k | if(BOOST_JSON_UNLIKELY(n == 0)) |
376 | 14.4k | st_.maybe_grow(); |
377 | 23.4k | detail::unchecked_object uo( |
378 | 23.4k | st_.release(n * 2), n, sp_); |
379 | 23.4k | st_.exchange(std::move(uo)); |
380 | 23.4k | } |
381 | | |
382 | | void |
383 | | value_stack:: |
384 | | push_chars( |
385 | | string_view s) |
386 | 155k | { |
387 | 155k | st_.append(s); |
388 | 155k | } |
389 | | |
390 | | void |
391 | | value_stack:: |
392 | | push_key( |
393 | | string_view s) |
394 | 1.77M | { |
395 | 1.77M | if(! st_.has_chars()) |
396 | 1.76M | { |
397 | 1.76M | st_.push(detail::key_t{}, s, sp_); |
398 | 1.76M | return; |
399 | 1.76M | } |
400 | 8.26k | auto part = st_.release_string(); |
401 | 8.26k | st_.push(detail::key_t{}, part, s, sp_); |
402 | 8.26k | } |
403 | | |
404 | | void |
405 | | value_stack:: |
406 | | push_string( |
407 | | string_view s) |
408 | 45.7k | { |
409 | 45.7k | if(! st_.has_chars()) |
410 | 36.4k | { |
411 | | // fast path |
412 | 36.4k | st_.push(s, sp_); |
413 | 36.4k | return; |
414 | 36.4k | } |
415 | | |
416 | | // VFALCO We could add a special |
417 | | // private ctor to string that just |
418 | | // creates uninitialized space, |
419 | | // to reduce member function calls. |
420 | 9.28k | auto part = st_.release_string(); |
421 | 9.28k | auto& str = st_.push( |
422 | 9.28k | string_kind, sp_).get_string(); |
423 | 9.28k | str.reserve( |
424 | 9.28k | part.size() + s.size()); |
425 | 9.28k | std::memcpy( |
426 | 9.28k | str.data(), |
427 | 9.28k | part.data(), part.size()); |
428 | 9.28k | std::memcpy( |
429 | 9.28k | str.data() + part.size(), |
430 | 9.28k | s.data(), s.size()); |
431 | 9.28k | str.grow(part.size() + s.size()); |
432 | 9.28k | } |
433 | | |
434 | | void |
435 | | value_stack:: |
436 | | push_int64( |
437 | | int64_t i) |
438 | 7.09M | { |
439 | 7.09M | st_.push(i, sp_); |
440 | 7.09M | } |
441 | | |
442 | | void |
443 | | value_stack:: |
444 | | push_uint64( |
445 | | uint64_t u) |
446 | 28.3k | { |
447 | 28.3k | st_.push(u, sp_); |
448 | 28.3k | } |
449 | | |
450 | | void |
451 | | value_stack:: |
452 | | push_double( |
453 | | double d) |
454 | 5.40M | { |
455 | 5.40M | st_.push(d, sp_); |
456 | 5.40M | } |
457 | | |
458 | | void |
459 | | value_stack:: |
460 | | push_bool( |
461 | | bool b) |
462 | 48.6k | { |
463 | 48.6k | st_.push(b, sp_); |
464 | 48.6k | } |
465 | | |
466 | | void |
467 | | value_stack:: |
468 | | push_null() |
469 | 15.6k | { |
470 | 15.6k | st_.push(nullptr, sp_); |
471 | 15.6k | } |
472 | | |
473 | | } // namespace json |
474 | | } // namespace boost |
475 | | |
476 | | #endif |