• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

boostorg / url / #611

20 Feb 2026 02:42AM UTC coverage: 99.123% (-0.09%) from 99.217%
#611

push

travis-ci

alandefreitas
feat: constexpr URL parsing for C++20

fix #890

9949 of 10037 relevant lines covered (99.12%)

2919.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.06
include/boost/url/impl/params_encoded_ref.hpp
1
//
2
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4
//
5
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// Official repository: https://github.com/boostorg/url
9
//
10

11
#ifndef BOOST_URL_IMPL_PARAMS_ENCODED_REF_HPP
12
#define BOOST_URL_IMPL_PARAMS_ENCODED_REF_HPP
13

14
#include <boost/url/params_encoded_view.hpp>
15
#include <boost/url/url_base.hpp>
16
#include <boost/url/detail/except.hpp>
17
#include <boost/url/grammar/ci_string.hpp>
18
#include <boost/assert.hpp>
19
#include <utility>
20

21
namespace boost {
22
namespace urls {
23

24
//------------------------------------------------
25
//
26
// Special Members
27
//
28
//------------------------------------------------
29

30
inline
31
params_encoded_ref::
155✔
32
params_encoded_ref(
33
    url_base& u) noexcept
155✔
34
    : params_encoded_base(u.impl_)
155✔
35
    , u_(&u)
155✔
36
{
37
}
155✔
38

39
inline
40
params_encoded_ref&
41
params_encoded_ref::
2✔
42
operator=(
43
    params_encoded_ref const& other)
44
{
45
    if (!ref_.alias_of( other.ref_ ))
2✔
46
        assign(other.begin(), other.end());
2✔
47
    return *this;
2✔
48
}
49

50
inline
51
params_encoded_ref&
52
params_encoded_ref::
4✔
53
operator=(std::initializer_list<
54
    param_pct_view> init)
55
{
56
    assign(init.begin(), init.end());
4✔
57
    return *this;
4✔
58
}
59

60
inline
61
params_encoded_ref::
116✔
62
operator
63
params_encoded_view() const noexcept
64
{
65
    return {ref_};
116✔
66
}
67

68
//------------------------------------------------
69
//
70
// Modifiers
71
//
72
//------------------------------------------------
73

74
inline
75
void
76
params_encoded_ref::
6✔
77
assign(
78
    std::initializer_list<
79
        param_pct_view> init)
80
{
81
    assign(init.begin(), init.end());
6✔
82
}
6✔
83

84
inline
85
void
86
params_encoded_ref::
6✔
87
clear() noexcept
88
{
89
    u_->remove_query();
6✔
90
}
6✔
91

92
template<class FwdIt>
93
void
94
params_encoded_ref::
14✔
95
assign(FwdIt first, FwdIt last)
96
{
97
/*  If you get a compile error here, it
98
    means that the iterators you passed
99
    do not meet the requirements stated
100
    in the documentation.
101
*/
102
    static_assert(
103
        std::is_convertible<
104
            typename std::iterator_traits<
105
                FwdIt>::reference,
106
            param_view>::value,
107
        "Type requirements not met");
108

109
    assign(first, last,
14✔
110
        typename std::iterator_traits<
111
            FwdIt>::iterator_category{});
112
}
14✔
113

114
inline
115
auto
116
params_encoded_ref::
8✔
117
append(
118
    param_pct_view const& p) ->
119
        iterator
120
{
121
    return insert(end(), p);
8✔
122
}
123

124
inline
125
auto
126
params_encoded_ref::
8✔
127
append(
128
    std::initializer_list<
129
        param_pct_view> init) ->
130
    iterator
131
{
132
    return insert(end(), init);
8✔
133
}
134

135
template<class FwdIt>
136
auto
137
params_encoded_ref::
12✔
138
append(
139
    FwdIt first, FwdIt last) ->
140
    iterator
141
{
142
/*  If you get a compile error here, it
143
    means that the iterators you passed
144
    do not meet the requirements stated
145
    in the documentation.
146
*/
147
    static_assert(
148
        std::is_convertible<
149
            typename std::iterator_traits<
150
                FwdIt>::reference,
151
            param_view>::value,
152
        "Type requirements not met");
153

154
    return insert(
12✔
155
        end(), first, last);
6✔
156
}
157

158
template<class FwdIt>
159
auto
160
params_encoded_ref::
38✔
161
insert(
162
    iterator before,
163
    FwdIt first,
164
    FwdIt last) ->
165
        iterator
166
{
167
/*  If you get a compile error here, it
168
    means that the iterators you passed
169
    do not meet the requirements stated
170
    in the documentation.
171
*/
172
    static_assert(
173
        std::is_convertible<
174
            typename std::iterator_traits<
175
                FwdIt>::reference,
176
            param_view>::value,
177
        "Type requirements not met");
178

179
    return insert(
68✔
180
        before,
181
        first,
182
        last,
183
        typename std::iterator_traits<
184
            FwdIt>::iterator_category{});
60✔
185
}
186

187
template<class FwdIt>
188
auto
189
params_encoded_ref::
6✔
190
replace(
191
    iterator from,
192
    iterator to,
193
    FwdIt first,
194
    FwdIt last) ->
195
        iterator
196
{
197
/*  If you get a compile error here, it
198
    means that the iterators you passed
199
    do not meet the requirements stated
200
    in the documentation.
201
*/
202
    static_assert(
203
        std::is_convertible<
204
            typename std::iterator_traits<
205
                FwdIt>::reference,
206
            param_view>::value,
207
        "Type requirements not met");
208

209
    return u_->edit_params(
12✔
210
        from.it_, to.it_,
211
        detail::make_params_encoded_iter(
212
            first, last));
8✔
213
}
214

215
//------------------------------------------------
216
//
217
// implementation
218
//
219
//------------------------------------------------
220

221
template<class FwdIt>
222
void
223
params_encoded_ref::
14✔
224
assign(FwdIt first, FwdIt last,
225
    std::forward_iterator_tag)
226
{
227
    u_->edit_params(
28✔
228
        begin().it_,
14✔
229
        end().it_,
28✔
230
        detail::make_params_encoded_iter(
231
            first, last));
232
}
14✔
233

234
template<class FwdIt>
235
auto
236
params_encoded_ref::
38✔
237
insert(
238
    iterator before,
239
    FwdIt first,
240
    FwdIt last,
241
    std::forward_iterator_tag) ->
242
        iterator
243
{
244
    return u_->edit_params(
76✔
245
        before.it_,
246
        before.it_,
247
        detail::make_params_encoded_iter(
248
            first, last));
60✔
249
}
250

251
inline
252
auto
253
params_encoded_ref::
14✔
254
insert(
255
    iterator before,
256
    param_pct_view const& p) ->
257
        iterator
258
{
259
    return u_->edit_params(
14✔
260
        before.it_,
261
        before.it_,
262
        detail::param_encoded_iter(p));
28✔
263
}
264

265
inline
266
auto
267
params_encoded_ref::
24✔
268
insert(
269
    iterator before,
270
    std::initializer_list<
271
        param_pct_view> init) ->
272
    iterator
273
{
274
    return insert(
24✔
275
        before,
276
        init.begin(),
277
        init.end());
24✔
278
}
279

280
inline
281
std::size_t
282
params_encoded_ref::
4✔
283
erase(
284
    pct_string_view key,
285
    ignore_case_param ic) noexcept
286
{
287
    // end() can't be fully cached,
288
    // since erase invalidates it.
289
    iterator it;
4✔
290
    {
291
        auto const end_ = end();
4✔
292
        it = find_last(end_, key, ic);
4✔
293
        if(it == end_)
4✔
294
            return 0;
×
295
    }
296
    std::size_t n = 0;
4✔
297
    for(;;)
298
    {
299
        ++n;
10✔
300
        // Use it->key instead of key,
301
        // to handle self-intersection
302
        auto prev = find_last(it, it->key, ic);
10✔
303
        if(prev == end())
10✔
304
            break;
4✔
305
        erase(it);
6✔
306
        it = prev;
6✔
307
    }
6✔
308
    erase(it);
4✔
309
    return n;
4✔
310
}
311

312
inline
313
auto
314
params_encoded_ref::
10✔
315
replace(
316
    iterator pos,
317
    param_pct_view const& p) ->
318
        iterator
319
{
320
    return u_->edit_params(
10✔
321
        pos.it_,
322
        std::next(pos).it_,
10✔
323
        detail::param_encoded_iter(p));
20✔
324
}
325

326
inline
327
auto
328
params_encoded_ref::
2✔
329
replace(
330
    iterator from,
331
    iterator to,
332
    std::initializer_list<
333
        param_pct_view> init) ->
334
    iterator
335
{
336
    return replace(
2✔
337
        from,
338
        to,
339
        init.begin(),
340
        init.end());
2✔
341
}
342

343
inline
344
auto
345
params_encoded_ref::
8✔
346
unset(
347
    iterator pos) noexcept ->
348
        iterator
349
{
350
    BOOST_ASSERT(pos.it_.nk > 0);
8✔
351
    pct_string_view s;
8✔
352
    return u_->edit_params(
8✔
353
        pos.it_, pos.it_.next(),
8✔
354
        detail::param_encoded_value_iter(
8✔
355
            pos.it_.nk - 1, s, false));
16✔
356
}
357

358
inline
359
auto
360
params_encoded_ref::
8✔
361
set(
362
    iterator pos,
363
    pct_string_view value) ->
364
        iterator
365
{
366
    BOOST_ASSERT(pos.it_.nk > 0);
8✔
367
    return u_->edit_params(
8✔
368
        pos.it_,
369
        pos.it_.next(),
8✔
370
        detail::param_encoded_value_iter(
8✔
371
            pos.it_.nk - 1, value, true));
24✔
372
}
373

374
inline
375
auto
376
params_encoded_ref::
2✔
377
set(
378
    pct_string_view key,
379
    pct_string_view value,
380
    ignore_case_param ic) ->
381
        iterator
382
{
383
    // VFALCO we can't cache end() here
384
    // because it is invalidated
385
    // every time we set or erase.
386
    auto it0 = find(key, ic);
2✔
387
    if(it0 == end())
2✔
388
        return append({key, value});
×
389
    it0 = set(it0, value);
2✔
390
    auto it = end();
2✔
391
    for(;;)
392
    {
393
        it = find_last(it, key, ic);
4✔
394
        if(it == it0)
4✔
395
            return it0;
2✔
396
        it = erase(it);
2✔
397
    }
398
}
399

400
inline
401
auto
402
params_encoded_ref::
18✔
403
erase(
404
    iterator pos) noexcept ->
405
        iterator
406
{
407
    return erase(
18✔
408
        pos,
409
        std::next(pos));
18✔
410
}
411

412
inline
413
auto
414
params_encoded_ref::
22✔
415
erase(
416
    iterator first,
417
    iterator last) noexcept ->
418
        iterator
419
{
420
    core::string_view s("", 0);
22✔
421
    return u_->edit_params(
22✔
422
        first.it_,
423
        last.it_,
424
        detail::query_string_iter(s));
44✔
425
}
426

427
} // urls
428
} // boost
429

430
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc