impl/string.ipp

100.0% Lines (177/177) 100.0% List of functions (36/36)
string.ipp
f(x) Functions (36)
Function Calls Lines Blocks
boost::json::string::string(unsigned long, char, boost::json::storage_ptr) :30 78x 100.0% 100.0% boost::json::string::string(char const*, boost::json::storage_ptr) :40 178x 100.0% 100.0% boost::json::string::string(char const*, unsigned long, boost::json::storage_ptr) :49 4x 100.0% 86.0% boost::json::string::string(boost::json::string const&) :59 8x 100.0% 83.0% boost::json::string::string(boost::json::string const&, boost::json::storage_ptr) :66 158x 100.0% 100.0% boost::json::string::string(boost::json::string&&, boost::json::storage_ptr) :75 355x 100.0% 100.0% boost::json::string::string(boost::core::basic_string_view<char>, boost::json::storage_ptr) :84 17893x 100.0% 100.0% boost::json::string::operator=(boost::json::string const&) :100 6x 100.0% 100.0% boost::json::string::operator=(boost::json::string&&) :107 10x 100.0% 100.0% boost::json::string::operator=(char const*) :114 9x 100.0% 100.0% boost::json::string::operator=(boost::core::basic_string_view<char>) :121 8x 100.0% 100.0% boost::json::string::assign(unsigned long, char) :130 83x 100.0% 100.0% boost::json::string::assign(boost::json::string const&) :143 210x 100.0% 100.0% boost::json::string::assign(boost::json::string&&) :155 379x 100.0% 100.0% boost::json::string::assign(char const*, unsigned long) :174 18393x 100.0% 100.0% boost::json::string::assign(char const*) :195 192x 100.0% 100.0% boost::json::string::shrink_to_fit() :210 7x 100.0% 100.0% boost::json::string::try_at(unsigned long) :223 12x 100.0% 100.0% boost::json::string::try_at(unsigned long) const :234 20x 100.0% 100.0% boost::json::string::at(unsigned long, boost::source_location const&) const :245 18x 100.0% 100.0% boost::json::string::clear() :257 2x 100.0% 100.0% boost::json::string::push_back(char) :266 148x 100.0% 100.0% boost::json::string::pop_back() :273 29x 100.0% 100.0% boost::json::string::append(unsigned long, char) :283 4x 100.0% 100.0% boost::json::string::append(boost::core::basic_string_view<char>) :293 55x 100.0% 100.0% boost::json::string::insert(unsigned long, boost::core::basic_string_view<char>) :318 27x 100.0% 100.0% boost::json::string::insert(unsigned long, unsigned long, char) :328 11x 100.0% 100.0% boost::json::string::replace(unsigned long, unsigned long, boost::core::basic_string_view<char>) :343 19x 100.0% 100.0% boost::json::string::replace(unsigned long, unsigned long, unsigned long, char) :354 11x 100.0% 100.0% boost::json::string::erase(unsigned long, unsigned long) :370 10x 100.0% 100.0% boost::json::string::erase(char const*) :391 2x 100.0% 100.0% boost::json::string::erase(char const*, char const*) :399 3x 100.0% 100.0% boost::json::string::resize(unsigned long, char) :414 66x 100.0% 100.0% boost::json::string::swap(boost::json::string&) :434 4x 100.0% 77.0% boost::json::string::reserve_impl(unsigned long) :455 9686x 100.0% 94.0% std::hash<boost::json::string>::operator()(boost::json::string const&) const :481 3x 100.0% 100.0%
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_STRING_IPP
11 #define BOOST_JSON_IMPL_STRING_IPP
12
13 #include <boost/json/detail/except.hpp>
14 #include <algorithm>
15 #include <new>
16 #include <ostream>
17 #include <stdexcept>
18 #include <string>
19 #include <utility>
20
21 namespace boost {
22 namespace json {
23
24 //----------------------------------------------------------
25 //
26 // Construction
27 //
28 //----------------------------------------------------------
29
30 78x string::
31 string(
32 std::size_t count,
33 char ch,
34 78x storage_ptr sp)
35 78x : sp_(std::move(sp))
36 {
37 78x assign(count, ch);
38 78x }
39
40 178x string::
41 string(
42 char const* s,
43 178x storage_ptr sp)
44 178x : sp_(std::move(sp))
45 {
46 178x assign(s);
47 178x }
48
49 4x string::
50 string(
51 char const* s,
52 std::size_t count,
53 4x storage_ptr sp)
54 4x : sp_(std::move(sp))
55 {
56 4x assign(s, count);
57 4x }
58
59 8x string::
60 8x string(string const& other)
61 8x : sp_(other.sp_)
62 {
63 8x assign(other);
64 8x }
65
66 158x string::
67 string(
68 string const& other,
69 158x storage_ptr sp)
70 158x : sp_(std::move(sp))
71 {
72 158x assign(other);
73 158x }
74
75 355x string::
76 string(
77 string&& other,
78 355x storage_ptr sp)
79 355x : sp_(std::move(sp))
80 {
81 355x assign(std::move(other));
82 355x }
83
84 17893x string::
85 string(
86 string_view s,
87 17893x storage_ptr sp)
88 17893x : sp_(std::move(sp))
89 {
90 17893x assign(s);
91 17893x }
92
93 //----------------------------------------------------------
94 //
95 // Assignment
96 //
97 //----------------------------------------------------------
98
99 string&
100 6x string::
101 operator=(string const& other)
102 {
103 6x return assign(other);
104 }
105
106 string&
107 10x string::
108 operator=(string&& other)
109 {
110 10x return assign(std::move(other));
111 }
112
113 string&
114 9x string::
115 operator=(char const* s)
116 {
117 9x return assign(s);
118 }
119
120 string&
121 8x string::
122 operator=(string_view s)
123 {
124 8x return assign(s);
125 }
126
127
128
129 string&
130 83x string::
131 assign(
132 size_type count,
133 char ch)
134 {
135 64x std::char_traits<char>::assign(
136 83x impl_.assign(count, sp_),
137 count,
138 ch);
139 64x return *this;
140 }
141
142 string&
143 210x string::
144 assign(
145 string const& other)
146 {
147 210x if(this == &other)
148 1x return *this;
149 209x return assign(
150 other.data(),
151 179x other.size());
152 }
153
154 string&
155 379x string::
156 assign(string&& other)
157 {
158 379x if( &other == this )
159 1x return *this;
160
161 378x if(*sp_ == *other.sp_)
162 {
163 340x impl_.destroy(sp_);
164 340x impl_ = other.impl_;
165 340x ::new(&other.impl_) detail::string_impl();
166 340x return *this;
167 }
168
169 // copy
170 38x return assign(other);
171 }
172
173 string&
174 18393x string::
175 assign(
176 char const* s,
177 size_type count)
178 {
179 18393x auto const p = impl_.data();
180 18393x if(detail::ptr_in_range(p, p + impl_.size(), s))
181 {
182 3x std::char_traits<char>::move(p, s, count);
183 3x impl_.term(count);
184 }
185 else
186 {
187 18264x std::char_traits<char>::copy(
188 18390x impl_.assign(count, sp_),
189 s, count);
190 }
191 18267x return *this;
192 }
193
194 string&
195 192x string::
196 assign(
197 char const* s)
198 {
199 192x return assign(s, std::char_traits<
200 189x char>::length(s));
201 }
202
203 //----------------------------------------------------------
204 //
205 // Capacity
206 //
207 //----------------------------------------------------------
208
209 void
210 7x string::
211 shrink_to_fit()
212 {
213 7x impl_.shrink_to_fit(sp_);
214 7x }
215
216 //----------------------------------------------------------
217 //
218 // Access
219 //
220 //----------------------------------------------------------
221
222 system::result<char&>
223 12x string::try_at(std::size_t pos) noexcept
224 {
225 12x if( pos < size() )
226 10x return impl_.data()[pos];
227
228 2x system::error_code ec;
229 2x BOOST_JSON_FAIL(ec, error::out_of_range);
230 2x return ec;
231 }
232
233 system::result<char const&>
234 20x string::try_at(std::size_t pos) const noexcept
235 {
236 20x if( pos < size() )
237 18x return impl_.data()[pos];
238
239 2x system::error_code ec;
240 2x BOOST_JSON_FAIL(ec, error::out_of_range);
241 2x return ec;
242 }
243
244 char const&
245 18x string::at(std::size_t pos, source_location const& loc) const
246 {
247 18x return try_at(pos).value(loc);
248 }
249
250 //----------------------------------------------------------
251 //
252 // Operations
253 //
254 //----------------------------------------------------------
255
256 void
257 2x string::
258 clear() noexcept
259 {
260 2x impl_.term(0);
261 2x }
262
263 //----------------------------------------------------------
264
265 void
266 148x string::
267 push_back(char ch)
268 {
269 148x *impl_.append(1, sp_) = ch;
270 146x }
271
272 void
273 29x string::
274 pop_back()
275 {
276 29x back() = 0;
277 29x impl_.size(impl_.size() - 1);
278 29x }
279
280 //----------------------------------------------------------
281
282 string&
283 4x string::
284 append(size_type count, char ch)
285 {
286 2x std::char_traits<char>::assign(
287 4x impl_.append(count, sp_),
288 count, ch);
289 2x return *this;
290 }
291
292 string&
293 55x string::
294 append(string_view sv)
295 {
296 55x auto const p = impl_.data();
297 55x if(detail::ptr_in_range(p, p + impl_.size(), sv.data()))
298 {
299 // sv aliases our own storage; appending may reallocate and free the
300 // buffer sv points into, so copy from the relocated offset afterwards
301 10x auto const offset = sv.data() - p;
302 10x auto const dest = impl_.append(sv.size(), sp_);
303 8x std::char_traits<char>::copy(
304 8x dest, impl_.data() + offset, sv.size());
305 }
306 else
307 {
308 90x std::char_traits<char>::copy(
309 45x impl_.append(sv.size(), sp_),
310 sv.data(), sv.size());
311 }
312 40x return *this;
313 }
314
315 //----------------------------------------------------------
316
317 string&
318 27x string::
319 insert(
320 size_type pos,
321 string_view sv)
322 {
323 27x impl_.insert(pos, sv.data(), sv.size(), sp_);
324 17x return *this;
325 }
326
327 string&
328 11x string::
329 insert(
330 std::size_t pos,
331 std::size_t count,
332 char ch)
333 {
334 6x std::char_traits<char>::assign(
335 11x impl_.insert_unchecked(pos, count, sp_),
336 count, ch);
337 6x return *this;
338 }
339
340 //----------------------------------------------------------
341
342 string&
343 19x string::
344 replace(
345 std::size_t pos,
346 std::size_t count,
347 string_view sv)
348 {
349 19x impl_.replace(pos, count, sv.data(), sv.size(), sp_);
350 15x return *this;
351 }
352
353 string&
354 11x string::
355 replace(
356 std::size_t pos,
357 std::size_t count,
358 std::size_t count2,
359 char ch)
360 {
361 7x std::char_traits<char>::assign(
362 11x impl_.replace_unchecked(pos, count, count2, sp_),
363 count2, ch);
364 7x return *this;
365 }
366
367 //----------------------------------------------------------
368
369 string&
370 10x string::
371 erase(
372 size_type pos,
373 size_type count)
374 {
375 10x if(pos > impl_.size())
376 {
377 BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
378 1x detail::throw_system_error( error::out_of_range, &loc );
379 }
380 9x if( count > impl_.size() - pos)
381 4x count = impl_.size() - pos;
382 9x std::char_traits<char>::move(
383 9x impl_.data() + pos,
384 9x impl_.data() + pos + count,
385 9x impl_.size() - pos - count + 1);
386 9x impl_.term(impl_.size() - count);
387 9x return *this;
388 }
389
390 auto
391 2x string::
392 erase(const_iterator pos) ->
393 iterator
394 {
395 2x return erase(pos, pos+1);
396 }
397
398 auto
399 3x string::
400 erase(
401 const_iterator first,
402 const_iterator last) ->
403 iterator
404 {
405 3x auto const pos = first - begin();
406 3x auto const count = last - first;
407 3x erase(pos, count);
408 3x return data() + pos;
409 }
410
411 //----------------------------------------------------------
412
413 void
414 66x string::
415 resize(size_type count, char ch)
416 {
417 66x if(count <= impl_.size())
418 {
419 25x impl_.term(count);
420 25x return;
421 }
422
423 41x reserve(count);
424 35x std::char_traits<char>::assign(
425 impl_.end(),
426 35x count - impl_.size(),
427 ch);
428 35x grow(count - size());
429 }
430
431 //----------------------------------------------------------
432
433 void
434 4x string::
435 swap(string& other)
436 {
437 4x if(*sp_ == *other.sp_)
438 {
439 3x std::swap(impl_, other.impl_);
440 3x return;
441 }
442 string temp1(
443 1x std::move(*this), other.sp_);
444 string temp2(
445 1x std::move(other), sp_);
446 1x this->~string();
447 1x ::new(this) string(pilfer(temp2));
448 1x other.~string();
449 1x ::new(&other) string(pilfer(temp1));
450 1x }
451
452 //----------------------------------------------------------
453
454 void
455 9686x string::
456 reserve_impl(size_type new_cap)
457 {
458 9686x BOOST_ASSERT(
459 new_cap >= impl_.capacity());
460 9686x if(new_cap > impl_.capacity())
461 {
462 // grow
463 9686x new_cap = detail::string_impl::growth(
464 new_cap, impl_.capacity());
465 9685x detail::string_impl tmp(new_cap, sp_);
466 9675x std::char_traits<char>::copy(tmp.data(),
467 9675x impl_.data(), impl_.size() + 1);
468 9675x tmp.size(impl_.size());
469 9675x impl_.destroy(sp_);
470 9675x impl_ = tmp;
471 9675x return;
472 }
473 }
474
475 } // namespace json
476 } // namespace boost
477
478 //----------------------------------------------------------
479
480 std::size_t
481 3x std::hash< ::boost::json::string >::operator()(
482 ::boost::json::string const& js ) const noexcept
483 {
484 3x return ::boost::hash< ::boost::json::string >()( js );
485 }
486
487 #endif
488