Coverage Report

Created: 2023-03-26 06:57

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