Coverage Report

Created: 2025-08-28 06:51

/src/boost/boost/json/impl/string.hpp
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_HPP
11
#define BOOST_JSON_IMPL_STRING_HPP
12
13
#include <utility>
14
15
namespace boost {
16
namespace json {
17
18
string::
19
string(
20
    detail::key_t const&,
21
    string_view s,
22
    storage_ptr sp)
23
1.88M
    : sp_(std::move(sp))
24
1.88M
    , impl_(detail::key_t{},
25
1.88M
        s, sp_)
26
1.88M
{
27
1.88M
}
28
29
string::
30
string(
31
    detail::key_t const&,
32
    string_view s1,
33
    string_view s2,
34
    storage_ptr sp)
35
3.26k
    : sp_(std::move(sp))
36
3.26k
    , impl_(detail::key_t{},
37
3.26k
        s1, s2, sp_)
38
3.26k
{
39
3.26k
}
40
41
template<class InputIt, class>
42
string::
43
string(
44
    InputIt first,
45
    InputIt last,
46
    storage_ptr sp)
47
0
    : sp_(std::move(sp))
48
0
    , impl_(first, last, sp_,
49
0
        iter_cat<InputIt>{})
50
0
{
51
0
}
52
53
template<class InputIt, class>
54
string&
55
string::
56
assign(
57
    InputIt first,
58
    InputIt last)
59
{
60
    assign(first, last,
61
        iter_cat<InputIt>{});
62
    return *this;
63
}
64
65
template<class InputIt, class>
66
string&
67
string::
68
append(InputIt first, InputIt last)
69
{
70
    append(first, last,
71
        iter_cat<InputIt>{});
72
    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
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
        ~cleanup()
93
        {
94
            s.destroy(sp);
95
        }
96
    };
97
98
    // We use the default storage because
99
    // the allocation is immediately freed.
100
    storage_ptr dsp;
101
    detail::string_impl tmp(
102
        first, last, dsp,
103
        iter_cat<InputIt>{});
104
    cleanup c{tmp, dsp};
105
    std::memcpy(
106
        impl_.insert_unchecked(pos, tmp.size(), sp_),
107
        tmp.data(),
108
        tmp.size());
109
    return *this;
110
}
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
string::
159
assign(
160
    InputIt first,
161
    InputIt last,
162
    std::random_access_iterator_tag)
163
{
164
    auto dest = impl_.assign(static_cast<
165
        size_type>(last - first), sp_);
166
    while(first != last)
167
        *dest++ = *first++;
168
}
169
170
template<class InputIt>
171
void
172
string::
173
assign(
174
    InputIt first,
175
    InputIt last,
176
    std::input_iterator_tag)
177
{
178
    if(first == last)
179
    {
180
        impl_.term(0);
181
        return;
182
    }
183
    detail::string_impl tmp(
184
        first, last, sp_,
185
        std::input_iterator_tag{});
186
    impl_.destroy(sp_);
187
    impl_ = tmp;
188
}
189
190
template<class InputIt>
191
void
192
string::
193
append(
194
    InputIt first,
195
    InputIt last,
196
    std::random_access_iterator_tag)
197
{
198
199
    auto const n = static_cast<
200
        size_type>(last - first);
201
    char* out = impl_.append(n, sp_);
202
#if defined(_MSC_VER) && _MSC_VER <= 1900
203
    while( first != last )
204
        *out++ = *first++;
205
#else
206
    std::copy(first, last, out);
207
#endif
208
}
209
210
template<class InputIt>
211
void
212
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
        ~cleanup()
224
        {
225
            s.destroy(sp);
226
        }
227
    };
228
229
    // We use the default storage because
230
    // the allocation is immediately freed.
231
    storage_ptr dsp;
232
    detail::string_impl tmp(
233
        first, last, dsp,
234
        std::input_iterator_tag{});
235
    cleanup c{tmp, dsp};
236
    std::memcpy(
237
        impl_.append(tmp.size(), sp_),
238
        tmp.data(), tmp.size());
239
}
240
241
char&
242
string::at(std::size_t pos, source_location const& loc)
243
0
{
244
0
245
0
    auto const& self = *this;
246
0
    return const_cast< char& >( self.at(pos, loc) );
247
0
}
248
249
} // namespace json
250
} // namespace boost
251
252
#endif