GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: impl/string.hpp
Date: 2025-12-23 17:20:53
Exec Total Coverage
Lines: 69 69 100.0%
Functions: 17 19 89.5%
Branches: 13 13 100.0%

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_HPP
11 #define BOOST_JSON_IMPL_STRING_HPP
12
13 #include <utility>
14
15 namespace boost {
16 namespace json {
17
18 30296 string::
19 string(
20 detail::key_t const&,
21 string_view s,
22 30296 storage_ptr sp)
23 30296 : sp_(std::move(sp))
24 30296 , impl_(detail::key_t{},
25
1/1
✓ Branch 1 taken 30236 times.
30296 s, sp_)
26 {
27 30296 }
28
29 8060 string::
30 string(
31 detail::key_t const&,
32 string_view s1,
33 string_view s2,
34 8060 storage_ptr sp)
35 8060 : sp_(std::move(sp))
36 8060 , impl_(detail::key_t{},
37
1/1
✓ Branch 1 taken 8060 times.
8060 s1, s2, sp_)
38 {
39 8060 }
40
41 template<class InputIt, class>
42 41 string::
43 string(
44 InputIt first,
45 InputIt last,
46 storage_ptr sp)
47 41 : sp_(std::move(sp))
48
1/1
✓ Branch 1 taken 8 times.
41 , impl_(first, last, sp_,
49
1/1
✓ Branch 1 taken 21 times.
21 iter_cat<InputIt>{})
50 {
51 41 }
52
53 template<class InputIt, class>
54 string&
55 26 string::
56 assign(
57 InputIt first,
58 InputIt last)
59 {
60 26 assign(first, last,
61 iter_cat<InputIt>{});
62 20 return *this;
63 }
64
65 template<class InputIt, class>
66 string&
67 12 string::
68 append(InputIt first, InputIt last)
69 {
70 12 append(first, last,
71 iter_cat<InputIt>{});
72 8 return *this;
73 }
74
75 // KRYSTIAN TODO: this can be done without copies when
76 // reallocation is not needed, when the iterator is a
77 // FowardIterator or better, as we can use std::distance
78 template<class InputIt, class>
79 auto
80 12 string::
81 insert(
82 size_type pos,
83 InputIt first,
84 InputIt last) ->
85 string&
86 {
87 struct cleanup
88 {
89 detail::string_impl& s;
90 storage_ptr const& sp;
91
92 6 ~cleanup()
93 {
94 6 s.destroy(sp);
95 6 }
96 };
97
98 // We use the default storage because
99 // the allocation is immediately freed.
100 12 storage_ptr dsp;
101
1/1
✓ Branch 1 taken 6 times.
12 detail::string_impl tmp(
102 first, last, dsp,
103 iter_cat<InputIt>{});
104 12 cleanup c{tmp, dsp};
105 12 std::memcpy(
106
1/1
✓ Branch 2 taken 4 times.
12 impl_.insert_unchecked(pos, tmp.size(), sp_),
107 12 tmp.data(),
108 tmp.size());
109 8 return *this;
110 16 }
111
112 // KRYSTIAN TODO: this can be done without copies when
113 // reallocation is not needed, when the iterator is a
114 // FowardIterator or better, as we can use std::distance
115 template<class InputIt, class>
116 auto
117 string::
118 replace(
119 const_iterator first,
120 const_iterator last,
121 InputIt first2,
122 InputIt last2) ->
123 string&
124 {
125 struct cleanup
126 {
127 detail::string_impl& s;
128 storage_ptr const& sp;
129
130 ~cleanup()
131 {
132 s.destroy(sp);
133 }
134 };
135
136 // We use the default storage because
137 // the allocation is immediately freed.
138 storage_ptr dsp;
139 detail::string_impl tmp(
140 first2, last2, dsp,
141 iter_cat<InputIt>{});
142 cleanup c{tmp, dsp};
143 std::memcpy(
144 impl_.replace_unchecked(
145 first - begin(),
146 last - first,
147 tmp.size(),
148 sp_),
149 tmp.data(),
150 tmp.size());
151 return *this;
152 }
153
154 //----------------------------------------------------------
155
156 template<class InputIt>
157 void
158 6 string::
159 assign(
160 InputIt first,
161 InputIt last,
162 std::random_access_iterator_tag)
163 {
164 6 auto dest = impl_.assign(static_cast<
165 6 size_type>(last - first), sp_);
166
2/2
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 5 times.
63 while(first != last)
167 58 *dest++ = *first++;
168 5 }
169
170 template<class InputIt>
171 void
172 7 string::
173 assign(
174 InputIt first,
175 InputIt last,
176 std::input_iterator_tag)
177 {
178
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
7 if(first == last)
179 {
180 1 impl_.term(0);
181 1 return;
182 }
183 6 detail::string_impl tmp(
184
1/1
✓ Branch 1 taken 4 times.
6 first, last, sp_,
185 std::input_iterator_tag{});
186 4 impl_.destroy(sp_);
187 4 impl_ = tmp;
188 }
189
190 template<class InputIt>
191 void
192 3 string::
193 append(
194 InputIt first,
195 InputIt last,
196 std::random_access_iterator_tag)
197 {
198
199 3 auto const n = static_cast<
200 3 size_type>(last - first);
201 3 char* out = impl_.append(n, sp_);
202 #if defined(_MSC_VER) && _MSC_VER <= 1900
203 while( first != last )
204 *out++ = *first++;
205 #else
206 2 std::copy(first, last, out);
207 #endif
208 2 }
209
210 template<class InputIt>
211 void
212 3 string::
213 append(
214 InputIt first,
215 InputIt last,
216 std::input_iterator_tag)
217 {
218 struct cleanup
219 {
220 detail::string_impl& s;
221 storage_ptr const& sp;
222
223 3 ~cleanup()
224 {
225 3 s.destroy(sp);
226 3 }
227 };
228
229 // We use the default storage because
230 // the allocation is immediately freed.
231 3 storage_ptr dsp;
232
1/1
✓ Branch 1 taken 3 times.
3 detail::string_impl tmp(
233 first, last, dsp,
234 std::input_iterator_tag{});
235 3 cleanup c{tmp, dsp};
236 3 std::memcpy(
237
1/1
✓ Branch 2 taken 2 times.
3 impl_.append(tmp.size(), sp_),
238 3 tmp.data(), tmp.size());
239 4 }
240
241 char&
242 15 string::at(std::size_t pos, source_location const& loc)
243 {
244
245 15 auto const& self = *this;
246 15 return const_cast< char& >( self.at(pos, loc) );
247 }
248
249 } // namespace json
250 } // namespace boost
251
252 #endif
253