GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: impl/string.ipp
Date: 2025-12-23 17:20:53
Exec Total Coverage
Lines: 167 167 100.0%
Functions: 36 36 100.0%
Branches: 32 34 94.1%

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