1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_URL_GRAMMAR_IMPL_RANGE_HPP
10  
#ifndef BOOST_URL_GRAMMAR_IMPL_RANGE_HPP
11  
#define BOOST_URL_GRAMMAR_IMPL_RANGE_HPP
11  
#define BOOST_URL_GRAMMAR_IMPL_RANGE_HPP
12  

12  

13  
#include <boost/url/detail/except.hpp>
13  
#include <boost/url/detail/except.hpp>
14  
#include <boost/url/grammar/error.hpp>
14  
#include <boost/url/grammar/error.hpp>
15  
#include <boost/url/grammar/recycled.hpp>
15  
#include <boost/url/grammar/recycled.hpp>
16  
#include <boost/core/empty_value.hpp>
16  
#include <boost/core/empty_value.hpp>
17  
#include <boost/assert.hpp>
17  
#include <boost/assert.hpp>
18  
#include <boost/core/detail/static_assert.hpp>
18  
#include <boost/core/detail/static_assert.hpp>
19  
#include <exception>
19  
#include <exception>
20  
#include <iterator>
20  
#include <iterator>
21  
#include <new>
21  
#include <new>
22  
#include <utility>
22  
#include <utility>
23  
#include <type_traits>
23  
#include <type_traits>
24  

24  

25  
#include <stddef.h> // ::max_align_t
25  
#include <stddef.h> // ::max_align_t
26  

26  

27  
namespace boost {
27  
namespace boost {
28  
namespace urls {
28  
namespace urls {
29  
namespace grammar {
29  
namespace grammar {
30  

30  

31  
//------------------------------------------------
31  
//------------------------------------------------
32  
//
32  
//
33  
// any_rule
33  
// any_rule
34  
//
34  
//
35  
//------------------------------------------------
35  
//------------------------------------------------
36  

36  

37  
template<class T>
37  
template<class T>
38  
struct any_rule<T>::impl_base
38  
struct any_rule<T>::impl_base
39  
{
39  
{
40  
    virtual
40  
    virtual
41  
    ~impl_base() = default;
41  
    ~impl_base() = default;
42  

42  

43  
    virtual
43  
    virtual
44  
    void
44  
    void
45  
    move(void* dest) noexcept
45  
    move(void* dest) noexcept
46  
    {
46  
    {
47  
        ::new(dest) impl_base(
47  
        ::new(dest) impl_base(
48  
            std::move(*this));
48  
            std::move(*this));
49  
    }
49  
    }
50  

50  

51  
    virtual
51  
    virtual
52  
    void
52  
    void
53  
    copy(void* dest) const noexcept
53  
    copy(void* dest) const noexcept
54  
    {
54  
    {
55  
        ::new(dest) impl_base(*this);
55  
        ::new(dest) impl_base(*this);
56  
    }
56  
    }
57  

57  

58  
    virtual
58  
    virtual
59  
    system::result<T>
59  
    system::result<T>
60  
    first(
60  
    first(
61  
        char const*&,
61  
        char const*&,
62  
        char const*) const noexcept
62  
        char const*) const noexcept
63  
    {
63  
    {
64  
        return system::error_code{};
64  
        return system::error_code{};
65  
    }
65  
    }
66  

66  

67  
    virtual
67  
    virtual
68  
    system::result<T>
68  
    system::result<T>
69  
    next(
69  
    next(
70  
        char const*&,
70  
        char const*&,
71  
        char const*) const noexcept
71  
        char const*) const noexcept
72  
    {
72  
    {
73  
        return system::error_code{};
73  
        return system::error_code{};
74  
    }
74  
    }
75  
};
75  
};
76  

76  

77  
//------------------------------------------------
77  
//------------------------------------------------
78  

78  

79  
// small
79  
// small
80  
template<class T>
80  
template<class T>
81  
template<class R, bool Small>
81  
template<class R, bool Small>
82  
struct any_rule<T>::impl1
82  
struct any_rule<T>::impl1
83  
    : impl_base
83  
    : impl_base
84  
    , private empty_value<R>
84  
    , private empty_value<R>
85  
{
85  
{
86  
    explicit
86  
    explicit
87  
    impl1(R const& next) noexcept
87  
    impl1(R const& next) noexcept
88  
        : empty_value<R>(
88  
        : empty_value<R>(
89  
            empty_init,
89  
            empty_init,
90  
            next)
90  
            next)
91  
    {
91  
    {
92  
    }
92  
    }
93  

93  

94  
private:
94  
private:
95  
    impl1(impl1&&) noexcept = default;
95  
    impl1(impl1&&) noexcept = default;
96  
    impl1(impl1 const&) noexcept = default;
96  
    impl1(impl1 const&) noexcept = default;
97  

97  

98  
    void
98  
    void
99  
    move(void* dest
99  
    move(void* dest
100  
        ) noexcept override
100  
        ) noexcept override
101  
    {
101  
    {
102  
        ::new(dest) impl1(
102  
        ::new(dest) impl1(
103  
            std::move(*this));
103  
            std::move(*this));
104  
    }
104  
    }
105  

105  

106  
    void
106  
    void
107  
    copy(void* dest
107  
    copy(void* dest
108  
        ) const noexcept override
108  
        ) const noexcept override
109  
    {
109  
    {
110  
        ::new(dest) impl1(*this);
110  
        ::new(dest) impl1(*this);
111  
    }
111  
    }
112  

112  

113  
    system::result<T>
113  
    system::result<T>
114  
    first(
114  
    first(
115  
        char const*& it,
115  
        char const*& it,
116  
        char const* end)
116  
        char const* end)
117  
            const noexcept override
117  
            const noexcept override
118  
    {
118  
    {
119  
        return grammar::parse(
119  
        return grammar::parse(
120  
            it, end, this->get());
120  
            it, end, this->get());
121  
    }
121  
    }
122  

122  

123  
    system::result<T>
123  
    system::result<T>
124  
    next(
124  
    next(
125  
        char const*& it,
125  
        char const*& it,
126  
        char const* end)
126  
        char const* end)
127  
            const noexcept override
127  
            const noexcept override
128  
    {
128  
    {
129  
        return grammar::parse(
129  
        return grammar::parse(
130  
            it, end, this->get());
130  
            it, end, this->get());
131  
    }
131  
    }
132  
};
132  
};
133  

133  

134  
//------------------------------------------------
134  
//------------------------------------------------
135  

135  

136  
// big
136  
// big
137  
template<class T>
137  
template<class T>
138  
template<class R>
138  
template<class R>
139  
struct any_rule<T>::impl1<R, false>
139  
struct any_rule<T>::impl1<R, false>
140  
    : impl_base
140  
    : impl_base
141  
{
141  
{
142  
    explicit
142  
    explicit
143  
    impl1(R const& next) noexcept
143  
    impl1(R const& next) noexcept
144  
    {
144  
    {
145  
        ::new(p_->addr()) impl{next};
145  
        ::new(p_->addr()) impl{next};
146  
    }
146  
    }
147  

147  

148  
private:
148  
private:
149  
    struct impl
149  
    struct impl
150  
    {
150  
    {
151  
        R r;
151  
        R r;
152  
    };
152  
    };
153  

153  

154  
    recycled_ptr<
154  
    recycled_ptr<
155  
        aligned_storage<impl>> p_;
155  
        aligned_storage<impl>> p_;
156  

156  

157  
    impl1(impl1&&) noexcept = default;
157  
    impl1(impl1&&) noexcept = default;
158  
    impl1(impl1 const&) noexcept = default;
158  
    impl1(impl1 const&) noexcept = default;
159  

159  

160  
    impl const&
160  
    impl const&
161  
    get() const noexcept
161  
    get() const noexcept
162  
    {
162  
    {
163  
        return *reinterpret_cast<
163  
        return *reinterpret_cast<
164  
            impl const*>(p_->addr());
164  
            impl const*>(p_->addr());
165  
    }
165  
    }
166  

166  

167  
    ~impl1()
167  
    ~impl1()
168  
    {
168  
    {
169  
        if(p_)
169  
        if(p_)
170  
            get().~impl();
170  
            get().~impl();
171  
    }
171  
    }
172  

172  

173  
    void
173  
    void
174  
    move(void* dest
174  
    move(void* dest
175  
        ) noexcept override
175  
        ) noexcept override
176  
    {
176  
    {
177  
        ::new(dest) impl1(
177  
        ::new(dest) impl1(
178  
            std::move(*this));
178  
            std::move(*this));
179  
    }
179  
    }
180  

180  

181  
    void
181  
    void
182  
    copy(void* dest
182  
    copy(void* dest
183  
        ) const noexcept override
183  
        ) const noexcept override
184  
    {
184  
    {
185  
        ::new(dest) impl1(*this);
185  
        ::new(dest) impl1(*this);
186  
    }
186  
    }
187  

187  

188  
    system::result<T>
188  
    system::result<T>
189  
    first(
189  
    first(
190  
        char const*& it,
190  
        char const*& it,
191  
        char const* end)
191  
        char const* end)
192  
            const noexcept override
192  
            const noexcept override
193  
    {
193  
    {
194  
        return grammar::parse(
194  
        return grammar::parse(
195  
            it, end, this->get().r);
195  
            it, end, this->get().r);
196  
    }
196  
    }
197  

197  

198  
    system::result<T>
198  
    system::result<T>
199  
    next(
199  
    next(
200  
        char const*& it,
200  
        char const*& it,
201  
        char const* end)
201  
        char const* end)
202  
            const noexcept override
202  
            const noexcept override
203  
    {
203  
    {
204  
        return grammar::parse(
204  
        return grammar::parse(
205  
            it, end, this->get().r);
205  
            it, end, this->get().r);
206  
    }
206  
    }
207  
};
207  
};
208  

208  

209  
//------------------------------------------------
209  
//------------------------------------------------
210  

210  

211  
// small
211  
// small
212  
template<class T>
212  
template<class T>
213  
template<
213  
template<
214  
    class R0, class R1, bool Small>
214  
    class R0, class R1, bool Small>
215  
struct any_rule<T>::impl2
215  
struct any_rule<T>::impl2
216  
    : impl_base
216  
    : impl_base
217  
    , private empty_value<R0, 0>
217  
    , private empty_value<R0, 0>
218  
    , private empty_value<R1, 1>
218  
    , private empty_value<R1, 1>
219  
{
219  
{
220  
    impl2(
220  
    impl2(
221  
        R0 const& first,
221  
        R0 const& first,
222  
        R1 const& next) noexcept
222  
        R1 const& next) noexcept
223  
        : empty_value<R0,0>(
223  
        : empty_value<R0,0>(
224  
            empty_init, first)
224  
            empty_init, first)
225  
        , empty_value<R1,1>(
225  
        , empty_value<R1,1>(
226  
            empty_init, next)
226  
            empty_init, next)
227  
    {
227  
    {
228  
    }
228  
    }
229  

229  

230  
private:
230  
private:
231  
    impl2(impl2&&) noexcept = default;
231  
    impl2(impl2&&) noexcept = default;
232  
    impl2(impl2 const&) noexcept = default;
232  
    impl2(impl2 const&) noexcept = default;
233  

233  

234  
    void
234  
    void
235  
    move(void* dest
235  
    move(void* dest
236  
        ) noexcept override
236  
        ) noexcept override
237  
    {
237  
    {
238  
        ::new(dest) impl2(
238  
        ::new(dest) impl2(
239  
            std::move(*this));
239  
            std::move(*this));
240  
    }
240  
    }
241  

241  

242  
    void
242  
    void
243  
    copy(void* dest
243  
    copy(void* dest
244  
        ) const noexcept override
244  
        ) const noexcept override
245  
    {
245  
    {
246  
        ::new(dest) impl2(*this);
246  
        ::new(dest) impl2(*this);
247  
    }
247  
    }
248  

248  

249  
    system::result<T>
249  
    system::result<T>
250  
    first(
250  
    first(
251  
        char const*& it,
251  
        char const*& it,
252  
        char const* end)
252  
        char const* end)
253  
            const noexcept override
253  
            const noexcept override
254  
    {
254  
    {
255  
        return grammar::parse(it, end,
255  
        return grammar::parse(it, end,
256  
            empty_value<
256  
            empty_value<
257  
                R0,0>::get());
257  
                R0,0>::get());
258  
    }
258  
    }
259  

259  

260  
    system::result<T>
260  
    system::result<T>
261  
    next(
261  
    next(
262  
        char const*& it,
262  
        char const*& it,
263  
        char const* end)
263  
        char const* end)
264  
            const noexcept override
264  
            const noexcept override
265  
    {
265  
    {
266  
        return grammar::parse(it, end,
266  
        return grammar::parse(it, end,
267  
            empty_value<
267  
            empty_value<
268  
                R1,1>::get());
268  
                R1,1>::get());
269  
    }
269  
    }
270  
};
270  
};
271  

271  

272  
//------------------------------------------------
272  
//------------------------------------------------
273  

273  

274  
// big
274  
// big
275  
template<class T>
275  
template<class T>
276  
template<
276  
template<
277  
    class R0, class R1>
277  
    class R0, class R1>
278  
struct any_rule<T>::impl2<R0, R1, false>
278  
struct any_rule<T>::impl2<R0, R1, false>
279  
    : impl_base
279  
    : impl_base
280  
{
280  
{
281  
    impl2(
281  
    impl2(
282  
        R0 const& first,
282  
        R0 const& first,
283  
        R1 const& next) noexcept
283  
        R1 const& next) noexcept
284  
    {
284  
    {
285  
        ::new(p_->addr()) impl{
285  
        ::new(p_->addr()) impl{
286  
            first, next};
286  
            first, next};
287  
    }
287  
    }
288  

288  

289  
private:
289  
private:
290  
    struct impl
290  
    struct impl
291  
    {
291  
    {
292  
        R0 first;
292  
        R0 first;
293  
        R1 next;
293  
        R1 next;
294  
    };
294  
    };
295  

295  

296  
    recycled_ptr<
296  
    recycled_ptr<
297  
        aligned_storage<impl>> p_;
297  
        aligned_storage<impl>> p_;
298  

298  

299  
    impl2(impl2&&) noexcept = default;
299  
    impl2(impl2&&) noexcept = default;
300  
    impl2(impl2 const&) noexcept = default;
300  
    impl2(impl2 const&) noexcept = default;
301  

301  

302  
    impl const&
302  
    impl const&
303  
    get() const noexcept
303  
    get() const noexcept
304  
    {
304  
    {
305  
        return *reinterpret_cast<
305  
        return *reinterpret_cast<
306  
            impl const*>(p_->addr());
306  
            impl const*>(p_->addr());
307  
    }
307  
    }
308  

308  

309  
    ~impl2()
309  
    ~impl2()
310  
    {
310  
    {
311  
        if(p_)
311  
        if(p_)
312  
            get().~impl();
312  
            get().~impl();
313  
    }
313  
    }
314  

314  

315  
    void
315  
    void
316  
    move(void* dest
316  
    move(void* dest
317  
        ) noexcept override
317  
        ) noexcept override
318  
    {
318  
    {
319  
        ::new(dest) impl2(
319  
        ::new(dest) impl2(
320  
            std::move(*this));
320  
            std::move(*this));
321  
    }
321  
    }
322  

322  

323  
    void
323  
    void
324  
    copy(void* dest
324  
    copy(void* dest
325  
        ) const noexcept override
325  
        ) const noexcept override
326  
    {
326  
    {
327  
        ::new(dest) impl2(*this);
327  
        ::new(dest) impl2(*this);
328  
    }
328  
    }
329  

329  

330  
    system::result<T>
330  
    system::result<T>
331  
    first(
331  
    first(
332  
        char const*& it,
332  
        char const*& it,
333  
        char const* end)
333  
        char const* end)
334  
            const noexcept override
334  
            const noexcept override
335  
    {
335  
    {
336  
        return grammar::parse(
336  
        return grammar::parse(
337  
            it, end, get().first);
337  
            it, end, get().first);
338  
    }
338  
    }
339  

339  

340  
    system::result<T>
340  
    system::result<T>
341  
    next(
341  
    next(
342  
        char const*& it,
342  
        char const*& it,
343  
        char const* end)
343  
        char const* end)
344  
            const noexcept override
344  
            const noexcept override
345  
    {
345  
    {
346  
        return grammar::parse(
346  
        return grammar::parse(
347  
            it, end, get().next);
347  
            it, end, get().next);
348  
    }
348  
    }
349  
};
349  
};
350  

350  

351  
//------------------------------------------------
351  
//------------------------------------------------
352  

352  

353  
template<class T>
353  
template<class T>
354  
typename any_rule<T>::impl_base&
354  
typename any_rule<T>::impl_base&
355  
any_rule<T>::
355  
any_rule<T>::
356  
get() noexcept
356  
get() noexcept
357  
{
357  
{
358  
    return *reinterpret_cast<
358  
    return *reinterpret_cast<
359  
        impl_base*>(sb_.addr());
359  
        impl_base*>(sb_.addr());
360  
}
360  
}
361  

361  

362  
template<class T>
362  
template<class T>
363  
typename any_rule<T>::impl_base const&
363  
typename any_rule<T>::impl_base const&
364  
any_rule<T>::
364  
any_rule<T>::
365  
get() const noexcept
365  
get() const noexcept
366  
{
366  
{
367  
    return *reinterpret_cast<
367  
    return *reinterpret_cast<
368  
        impl_base const*>(sb_.addr());
368  
        impl_base const*>(sb_.addr());
369  
}
369  
}
370  

370  

371  

371  

372  
template<class T>
372  
template<class T>
373  
any_rule<T>::
373  
any_rule<T>::
374  
any_rule() noexcept
374  
any_rule() noexcept
375  
{
375  
{
376  
    ::new(sb_.addr()) impl_base{};
376  
    ::new(sb_.addr()) impl_base{};
377  
    char const* it = nullptr;
377  
    char const* it = nullptr;
378  
    get().first(it, nullptr);
378  
    get().first(it, nullptr);
379  
    get().next(it, nullptr);
379  
    get().next(it, nullptr);
380  
}
380  
}
381  

381  

382  

382  

383  
template<class T>
383  
template<class T>
384  
any_rule<T>::
384  
any_rule<T>::
385  
any_rule(any_rule&& other) noexcept
385  
any_rule(any_rule&& other) noexcept
386  
{
386  
{
387  
    other.get().move(sb_.addr());
387  
    other.get().move(sb_.addr());
388  
}
388  
}
389  

389  

390  

390  

391  
template<class T>
391  
template<class T>
392  
any_rule<T>::
392  
any_rule<T>::
393  
any_rule(any_rule const& other) noexcept
393  
any_rule(any_rule const& other) noexcept
394  
{
394  
{
395  
    other.get().copy(sb_.addr());
395  
    other.get().copy(sb_.addr());
396  
}
396  
}
397  

397  

398  

398  

399  
template<class T>
399  
template<class T>
400  
any_rule<T>&
400  
any_rule<T>&
401  
any_rule<T>::
401  
any_rule<T>::
402  
operator=(any_rule&& other) noexcept
402  
operator=(any_rule&& other) noexcept
403  
{
403  
{
404  
    if(this == &other)
404  
    if(this == &other)
405  
        return *this;
405  
        return *this;
406  
    get().~impl_base();
406  
    get().~impl_base();
407  
    other.get().move(sb_.addr());
407  
    other.get().move(sb_.addr());
408  
    return *this;
408  
    return *this;
409  
}
409  
}
410  

410  

411  

411  

412  
template<class T>
412  
template<class T>
413  
any_rule<T>&
413  
any_rule<T>&
414  
any_rule<T>::
414  
any_rule<T>::
415  
operator=(any_rule const& other) noexcept
415  
operator=(any_rule const& other) noexcept
416  
{
416  
{
417  
    if(this == &other)
417  
    if(this == &other)
418  
        return *this;
418  
        return *this;
419  
    get().~impl_base();
419  
    get().~impl_base();
420  
    other.get().copy(sb_.addr());
420  
    other.get().copy(sb_.addr());
421  
    return *this;
421  
    return *this;
422  
}
422  
}
423  

423  

424  

424  

425  
template<class T>
425  
template<class T>
426  
any_rule<T>::
426  
any_rule<T>::
427  
~any_rule()
427  
~any_rule()
428  
{
428  
{
429  
    get().~impl_base();
429  
    get().~impl_base();
430  
}
430  
}
431  

431  

432  

432  

433  
template<class T>
433  
template<class T>
434  
template<class R>
434  
template<class R>
435  
any_rule<T>::
435  
any_rule<T>::
436  
any_rule(
436  
any_rule(
437  
    R const& next)
437  
    R const& next)
438  
{
438  
{
439  
    static_assert(
439  
    static_assert(
440  
        ::boost::urls::grammar::is_rule<R>::value,
440  
        ::boost::urls::grammar::is_rule<R>::value,
441  
        "Rule requirements not met");
441  
        "Rule requirements not met");
442  
    static_assert(
442  
    static_assert(
443  
        std::is_same<typename R::value_type, T>::value,
443  
        std::is_same<typename R::value_type, T>::value,
444  
        "Rule value_type mismatch");
444  
        "Rule value_type mismatch");
445  

445  

446  
    BOOST_CORE_STATIC_ASSERT(
446  
    BOOST_CORE_STATIC_ASSERT(
447  
        sizeof(impl1<R, false>) <=
447  
        sizeof(impl1<R, false>) <=
448  
            BufferSize);
448  
            BufferSize);
449  

449  

450  
    ::new(sb_.addr()) impl1<R,
450  
    ::new(sb_.addr()) impl1<R,
451  
        sizeof(impl1<R, true>) <=
451  
        sizeof(impl1<R, true>) <=
452  
            BufferSize>(next);
452  
            BufferSize>(next);
453  
}
453  
}
454  

454  

455  
//------------------------------------------------
455  
//------------------------------------------------
456  

456  

457  
template<class T>
457  
template<class T>
458  
template<
458  
template<
459  
    class R0, class R1>
459  
    class R0, class R1>
460  
any_rule<T>::
460  
any_rule<T>::
461  
any_rule(
461  
any_rule(
462  
    R0 const& first,
462  
    R0 const& first,
463  
    R1 const& next)
463  
    R1 const& next)
464  
{
464  
{
465  
    static_assert(
465  
    static_assert(
466  
        ::boost::urls::grammar::is_rule<R0>::value,
466  
        ::boost::urls::grammar::is_rule<R0>::value,
467  
        "Rule requirements not met");
467  
        "Rule requirements not met");
468  
    static_assert(
468  
    static_assert(
469  
        ::boost::urls::grammar::is_rule<R1>::value,
469  
        ::boost::urls::grammar::is_rule<R1>::value,
470  
        "Rule requirements not met");
470  
        "Rule requirements not met");
471  
    static_assert(
471  
    static_assert(
472  
        std::is_same<typename R0::value_type, T>::value,
472  
        std::is_same<typename R0::value_type, T>::value,
473  
        "First rule value_type mismatch");
473  
        "First rule value_type mismatch");
474  
    static_assert(
474  
    static_assert(
475  
        std::is_same<typename R1::value_type, T>::value,
475  
        std::is_same<typename R1::value_type, T>::value,
476  
        "Next rule value_type mismatch");
476  
        "Next rule value_type mismatch");
477  

477  

478  
    BOOST_CORE_STATIC_ASSERT(
478  
    BOOST_CORE_STATIC_ASSERT(
479  
        sizeof(impl2<R0, R1, false>) <=
479  
        sizeof(impl2<R0, R1, false>) <=
480  
            BufferSize);
480  
            BufferSize);
481  

481  

482  
    ::new(sb_.addr()) impl2<R0, R1,
482  
    ::new(sb_.addr()) impl2<R0, R1,
483  
        sizeof(impl2<R0, R1, true>
483  
        sizeof(impl2<R0, R1, true>
484  
            ) <= BufferSize>(
484  
            ) <= BufferSize>(
485  
                first, next);
485  
                first, next);
486  
}
486  
}
487  

487  

488  
//------------------------------------------------
488  
//------------------------------------------------
489  

489  

490  
template<class T>
490  
template<class T>
491  
system::result<T>
491  
system::result<T>
492  
any_rule<T>::
492  
any_rule<T>::
493  
first(
493  
first(
494  
    char const*& it,
494  
    char const*& it,
495  
    char const* end) const noexcept
495  
    char const* end) const noexcept
496  
{
496  
{
497  
    return get().first(it, end);
497  
    return get().first(it, end);
498  
}
498  
}
499  

499  

500  
//------------------------------------------------
500  
//------------------------------------------------
501  

501  

502  
template<class T>
502  
template<class T>
503  
system::result<T>
503  
system::result<T>
504  
any_rule<T>::
504  
any_rule<T>::
505  
next(
505  
next(
506  
    char const*& it,
506  
    char const*& it,
507  
    char const* end) const noexcept
507  
    char const* end) const noexcept
508  
{
508  
{
509  
    return get().next(it, end);
509  
    return get().next(it, end);
510  
}
510  
}
511  

511  

512  
//------------------------------------------------
512  
//------------------------------------------------
513  
//
513  
//
514  
// range
514  
// range
515  
//
515  
//
516  
//------------------------------------------------
516  
//------------------------------------------------
517  

517  

518  
template<class T, class RangeRule>
518  
template<class T, class RangeRule>
519  
range<T, RangeRule>::
519  
range<T, RangeRule>::
520  
~range() = default;
520  
~range() = default;
521  

521  

522  
template<class T, class RangeRule>
522  
template<class T, class RangeRule>
523  
range<T, RangeRule>::
523  
range<T, RangeRule>::
524  
range() noexcept = default;
524  
range() noexcept = default;
525  

525  

526  
template<class T, class RangeRule>
526  
template<class T, class RangeRule>
527  
range<T, RangeRule>::
527  
range<T, RangeRule>::
528  
range(
528  
range(
529  
    range&& other) noexcept
529  
    range&& other) noexcept
530  
    : detail::range_base_storage<
530  
    : detail::range_base_storage<
531  
        RangeRule>(std::move(other.rule()))
531  
        RangeRule>(std::move(other.rule()))
532  
    , s_(other.s_)
532  
    , s_(other.s_)
533  
    , n_(other.n_)
533  
    , n_(other.n_)
534  
{
534  
{
535  
    other.s_ = {};
535  
    other.s_ = {};
536  
    other.n_ = 0;
536  
    other.n_ = 0;
537  
}
537  
}
538  

538  

539  
template<class T, class RangeRule>
539  
template<class T, class RangeRule>
540  
range<T, RangeRule>::
540  
range<T, RangeRule>::
541  
range(
541  
range(
542  
    range const& other) noexcept
542  
    range const& other) noexcept
543  
    : detail::range_base_storage<
543  
    : detail::range_base_storage<
544  
        RangeRule>(other.rule())
544  
        RangeRule>(other.rule())
545  
    , s_(other.s_)
545  
    , s_(other.s_)
546  
    , n_(other.n_)
546  
    , n_(other.n_)
547  
{
547  
{
548  
}
548  
}
549  

549  

550  
template<class T, class RangeRule>
550  
template<class T, class RangeRule>
551  
auto
551  
auto
552  
range<T, RangeRule>::
552  
range<T, RangeRule>::
553  
operator=(range&& other) noexcept
553  
operator=(range&& other) noexcept
554  
    -> range&
554  
    -> range&
555  
{
555  
{
556  
    if(this == &other)
556  
    if(this == &other)
557  
        return *this;
557  
        return *this;
558  
    static_cast<
558  
    static_cast<
559  
        detail::range_base_storage<
559  
        detail::range_base_storage<
560  
            RangeRule>&>(*this) =
560  
            RangeRule>&>(*this) =
561  
        std::move(static_cast<
561  
        std::move(static_cast<
562  
            detail::range_base_storage<
562  
            detail::range_base_storage<
563  
                RangeRule>&>(other));
563  
                RangeRule>&>(other));
564  
    s_ = other.s_;
564  
    s_ = other.s_;
565  
    n_ = other.n_;
565  
    n_ = other.n_;
566  
    other.s_ = {};
566  
    other.s_ = {};
567  
    other.n_ = 0;
567  
    other.n_ = 0;
568  
    return *this;
568  
    return *this;
569  
}
569  
}
570  

570  

571  
template<class T, class RangeRule>
571  
template<class T, class RangeRule>
572  
auto
572  
auto
573  
range<T, RangeRule>::
573  
range<T, RangeRule>::
574  
operator=(range const& other) noexcept
574  
operator=(range const& other) noexcept
575  
    -> range&
575  
    -> range&
576  
{
576  
{
577  
    if(this == &other)
577  
    if(this == &other)
578  
        return *this;
578  
        return *this;
579  
    static_cast<
579  
    static_cast<
580  
        detail::range_base_storage<
580  
        detail::range_base_storage<
581  
            RangeRule>&>(*this) =
581  
            RangeRule>&>(*this) =
582  
        static_cast<
582  
        static_cast<
583  
            detail::range_base_storage<
583  
            detail::range_base_storage<
584  
                RangeRule> const&>(other);
584  
                RangeRule> const&>(other);
585  
    s_ = other.s_;
585  
    s_ = other.s_;
586  
    n_ = other.n_;
586  
    n_ = other.n_;
587  
    return *this;
587  
    return *this;
588  
}
588  
}
589  

589  

590  
//------------------------------------------------
590  
//------------------------------------------------
591  
//
591  
//
592  
// iterator
592  
// iterator
593  
//
593  
//
594  
//------------------------------------------------
594  
//------------------------------------------------
595  

595  

596  
template<class T, class RangeRule>
596  
template<class T, class RangeRule>
597  
class range<T, RangeRule>::
597  
class range<T, RangeRule>::
598  
    iterator
598  
    iterator
599  
{
599  
{
600  
public:
600  
public:
601  
    using value_type = T;
601  
    using value_type = T;
602  
    using reference = T const&;
602  
    using reference = T const&;
603  
    using pointer = void const*;
603  
    using pointer = void const*;
604  
    using difference_type =
604  
    using difference_type =
605  
        std::ptrdiff_t;
605  
        std::ptrdiff_t;
606  
    using iterator_category =
606  
    using iterator_category =
607  
        std::forward_iterator_tag;
607  
        std::forward_iterator_tag;
608  

608  

609  
    iterator() = default;
609  
    iterator() = default;
610  
    iterator(
610  
    iterator(
611  
        iterator const&) = default;
611  
        iterator const&) = default;
612  
    iterator& operator=(
612  
    iterator& operator=(
613  
        iterator const&) = default;
613  
        iterator const&) = default;
614  

614  

615  
    reference
615  
    reference
616  
    operator*() const noexcept
616  
    operator*() const noexcept
617  
    {
617  
    {
618  
        return *rv_;
618  
        return *rv_;
619  
    }
619  
    }
620  

620  

621  
    bool
621  
    bool
622  
    operator==(
622  
    operator==(
623  
        iterator const& other) const noexcept
623  
        iterator const& other) const noexcept
624  
    {
624  
    {
625  
        // can't compare iterators
625  
        // can't compare iterators
626  
        // from different containers!
626  
        // from different containers!
627  
        BOOST_ASSERT(r_ == other.r_);
627  
        BOOST_ASSERT(r_ == other.r_);
628  

628  

629  
        return p_ == other.p_;
629  
        return p_ == other.p_;
630  
    }
630  
    }
631  

631  

632  
    bool
632  
    bool
633  
    operator!=(
633  
    operator!=(
634  
        iterator const& other) const noexcept
634  
        iterator const& other) const noexcept
635  
    {
635  
    {
636  
        return !(*this == other);
636  
        return !(*this == other);
637  
    }
637  
    }
638  

638  

639  
    iterator&
639  
    iterator&
640  
    operator++() noexcept
640  
    operator++() noexcept
641  
    {
641  
    {
642  
        BOOST_ASSERT(
642  
        BOOST_ASSERT(
643  
            p_ != nullptr);
643  
            p_ != nullptr);
644  
        auto const end =
644  
        auto const end =
645  
            r_->s_.data() +
645  
            r_->s_.data() +
646  
            r_->s_.size();
646  
            r_->s_.size();
647  
        rv_ = r_->rule().next(p_, end);
647  
        rv_ = r_->rule().next(p_, end);
648  
        if( !rv_ )
648  
        if( !rv_ )
649  
            p_ = nullptr;
649  
            p_ = nullptr;
650  
        return *this;
650  
        return *this;
651  
    }
651  
    }
652  

652  

653  
    iterator
653  
    iterator
654  
    operator++(int) noexcept
654  
    operator++(int) noexcept
655  
    {
655  
    {
656  
        auto tmp = *this;
656  
        auto tmp = *this;
657  
        ++*this;
657  
        ++*this;
658  
        return tmp;
658  
        return tmp;
659  
    }
659  
    }
660  

660  

661  
private:
661  
private:
662  
    friend class range<T, RangeRule>;
662  
    friend class range<T, RangeRule>;
663  

663  

664  
    range<T, RangeRule> const* r_ = nullptr;
664  
    range<T, RangeRule> const* r_ = nullptr;
665  
    char const* p_ = nullptr;
665  
    char const* p_ = nullptr;
666  
    system::result<T> rv_;
666  
    system::result<T> rv_;
667  

667  

668  
    iterator(
668  
    iterator(
669  
        range<T, RangeRule> const& r) noexcept
669  
        range<T, RangeRule> const& r) noexcept
670  
        : r_(&r)
670  
        : r_(&r)
671  
        , p_(r.s_.data())
671  
        , p_(r.s_.data())
672  
    {
672  
    {
673  
        auto const end =
673  
        auto const end =
674  
            r_->s_.data() +
674  
            r_->s_.data() +
675  
            r_->s_.size();
675  
            r_->s_.size();
676  
        rv_ = r_->rule().first(p_, end);
676  
        rv_ = r_->rule().first(p_, end);
677  
        if( !rv_ )
677  
        if( !rv_ )
678  
            p_ = nullptr;
678  
            p_ = nullptr;
679  
    }
679  
    }
680  

680  

681  
    constexpr
681  
    constexpr
682  
    iterator(
682  
    iterator(
683  
        range<T, RangeRule> const& r,
683  
        range<T, RangeRule> const& r,
684  
        int) noexcept
684  
        int) noexcept
685  
        : r_(&r)
685  
        : r_(&r)
686  
        , p_(nullptr)
686  
        , p_(nullptr)
687  
    {
687  
    {
688  
    }
688  
    }
689  
};
689  
};
690  

690  

691  
//------------------------------------------------
691  
//------------------------------------------------
692  

692  

693  
template<class T, class RangeRule>
693  
template<class T, class RangeRule>
694  
typename range<T, RangeRule>::iterator
694  
typename range<T, RangeRule>::iterator
695  
range<T, RangeRule>::
695  
range<T, RangeRule>::
696  
begin() const noexcept
696  
begin() const noexcept
697  
{
697  
{
698  
    return iterator(*this);
698  
    return iterator(*this);
699  
}
699  
}
700  

700  

701  
//------------------------------------------------
701  
//------------------------------------------------
702  

702  

703  
template<class T, class RangeRule>
703  
template<class T, class RangeRule>
704  
typename range<T, RangeRule>::iterator
704  
typename range<T, RangeRule>::iterator
705  
range<T, RangeRule>::
705  
range<T, RangeRule>::
706  
end() const noexcept
706  
end() const noexcept
707  
{
707  
{
708  
    return iterator(*this, 0);
708  
    return iterator(*this, 0);
709  
}
709  
}
710  

710  

711  
//------------------------------------------------
711  
//------------------------------------------------
712  

712  

713  
template<class T, class RangeRule>
713  
template<class T, class RangeRule>
714  
range<T, RangeRule>::
714  
range<T, RangeRule>::
715  
range(
715  
range(
716  
    core::string_view s,
716  
    core::string_view s,
717  
    std::size_t n,
717  
    std::size_t n,
718  
    RangeRule const& rule) noexcept
718  
    RangeRule const& rule) noexcept
719  
    : detail::range_base_storage<
719  
    : detail::range_base_storage<
720  
        RangeRule>(rule)
720  
        RangeRule>(rule)
721  
    , s_(s)
721  
    , s_(s)
722  
    , n_(n)
722  
    , n_(n)
723  
{
723  
{
724  
}
724  
}
725  

725  

726  
//------------------------------------------------
726  
//------------------------------------------------
727  

727  

728  
template<class T, class RangeRule>
728  
template<class T, class RangeRule>
729  
range<T, RangeRule>::
729  
range<T, RangeRule>::
730  
range(
730  
range(
731  
    core::string_view s,
731  
    core::string_view s,
732  
    std::size_t n,
732  
    std::size_t n,
733  
    RangeRule&& rule) noexcept
733  
    RangeRule&& rule) noexcept
734  
    : detail::range_base_storage<
734  
    : detail::range_base_storage<
735  
        RangeRule>(std::move(rule))
735  
        RangeRule>(std::move(rule))
736  
    , s_(s)
736  
    , s_(s)
737  
    , n_(n)
737  
    , n_(n)
738  
{
738  
{
739  
}
739  
}
740  

740  

741  
//------------------------------------------------
741  
//------------------------------------------------
742  

742  

743  
template<class R>
743  
template<class R>
744  
auto
744  
auto
745  
implementation_defined::range_rule_t<R>::
745  
implementation_defined::range_rule_t<R>::
746  
parse(
746  
parse(
747  
    char const*& it,
747  
    char const*& it,
748  
    char const* end) const ->
748  
    char const* end) const ->
749  
        system::result<value_type>
749  
        system::result<value_type>
750  
{
750  
{
751  
    using T = typename R::value_type;
751  
    using T = typename R::value_type;
752  

752  

753  
    std::size_t n = 0;
753  
    std::size_t n = 0;
754  
    auto const it0 = it;
754  
    auto const it0 = it;
755  
    auto it1 = it;
755  
    auto it1 = it;
756  
    auto rv = (grammar::parse)(
756  
    auto rv = (grammar::parse)(
757  
        it, end, next_);
757  
        it, end, next_);
758  
    if( !rv )
758  
    if( !rv )
759  
    {
759  
    {
760  
        if(rv.error() != error::end_of_range)
760  
        if(rv.error() != error::end_of_range)
761  
        {
761  
        {
762  
            // rewind unless error::end_of_range
762  
            // rewind unless error::end_of_range
763  
            it = it1;
763  
            it = it1;
764  
        }
764  
        }
765  
        if(n < N_)
765  
        if(n < N_)
766  
        {
766  
        {
767  
            // too few
767  
            // too few
768  
            BOOST_URL_RETURN_EC(
768  
            BOOST_URL_RETURN_EC(
769  
                error::mismatch);
769  
                error::mismatch);
770  
        }
770  
        }
771  
        // good
771  
        // good
772  
        return range<T>(
772  
        return range<T>(
773  
            core::string_view(it0, it - it0),
773  
            core::string_view(it0, it - it0),
774  
                n, any_rule<T>(next_));
774  
                n, any_rule<T>(next_));
775  
    }
775  
    }
776  
    for(;;)
776  
    for(;;)
777  
    {
777  
    {
778  
        ++n;
778  
        ++n;
779  
        it1 = it;
779  
        it1 = it;
780  
        rv = (grammar::parse)(
780  
        rv = (grammar::parse)(
781  
            it, end, next_);
781  
            it, end, next_);
782  
        if( !rv )
782  
        if( !rv )
783  
        {
783  
        {
784  
            if(rv.error() != error::end_of_range)
784  
            if(rv.error() != error::end_of_range)
785  
            {
785  
            {
786  
                // rewind unless error::end_of_range
786  
                // rewind unless error::end_of_range
787  
                it = it1;
787  
                it = it1;
788  
            }
788  
            }
789  
            break;
789  
            break;
790  
        }
790  
        }
791  
        if(n >= M_)
791  
        if(n >= M_)
792  
        {
792  
        {
793  
            // too many
793  
            // too many
794  
            BOOST_URL_RETURN_EC(
794  
            BOOST_URL_RETURN_EC(
795  
                error::mismatch);
795  
                error::mismatch);
796  
        }
796  
        }
797  
    }
797  
    }
798  
    if(n < N_)
798  
    if(n < N_)
799  
    {
799  
    {
800  
        // too few
800  
        // too few
801  
        BOOST_URL_RETURN_EC(
801  
        BOOST_URL_RETURN_EC(
802  
            error::mismatch);
802  
            error::mismatch);
803  
    }
803  
    }
804  
    // good
804  
    // good
805  
    return range<T>(
805  
    return range<T>(
806  
        core::string_view(it0, it - it0),
806  
        core::string_view(it0, it - it0),
807  
            n, any_rule<T>(next_));
807  
            n, any_rule<T>(next_));
808  
}
808  
}
809  

809  

810  
//------------------------------------------------
810  
//------------------------------------------------
811  

811  

812  
template<class R0, class R1>
812  
template<class R0, class R1>
813  
auto
813  
auto
814  
implementation_defined::range_rule_t<R0, R1>::
814  
implementation_defined::range_rule_t<R0, R1>::
815  
parse(
815  
parse(
816  
    char const*& it,
816  
    char const*& it,
817  
    char const* end) const ->
817  
    char const* end) const ->
818  
        system::result<range<typename
818  
        system::result<range<typename
819  
            R0::value_type>>
819  
            R0::value_type>>
820  
{
820  
{
821  
    using T = typename R0::value_type;
821  
    using T = typename R0::value_type;
822  

822  

823  
    std::size_t n = 0;
823  
    std::size_t n = 0;
824  
    auto const it0 = it;
824  
    auto const it0 = it;
825  
    auto it1 = it;
825  
    auto it1 = it;
826  
    auto rv = (grammar::parse)(
826  
    auto rv = (grammar::parse)(
827  
        it, end, first_);
827  
        it, end, first_);
828  
    if( !rv )
828  
    if( !rv )
829  
    {
829  
    {
830  
        if(rv.error() != error::end_of_range)
830  
        if(rv.error() != error::end_of_range)
831  
        {
831  
        {
832  
            it = it1;
832  
            it = it1;
833  
        }
833  
        }
834  
        if(n < N_)
834  
        if(n < N_)
835  
        {
835  
        {
836  
            BOOST_URL_RETURN_EC(
836  
            BOOST_URL_RETURN_EC(
837  
                error::mismatch);
837  
                error::mismatch);
838  
        }
838  
        }
839  
        return range<T>(
839  
        return range<T>(
840  
            core::string_view(it0, it - it0),
840  
            core::string_view(it0, it - it0),
841  
                n, any_rule<T>(first_, next_));
841  
                n, any_rule<T>(first_, next_));
842  
    }
842  
    }
843  
    for(;;)
843  
    for(;;)
844  
    {
844  
    {
845  
        ++n;
845  
        ++n;
846  
        it1 = it;
846  
        it1 = it;
847  
        rv = (grammar::parse)(
847  
        rv = (grammar::parse)(
848  
            it, end, next_);
848  
            it, end, next_);
849  
        if( !rv )
849  
        if( !rv )
850  
        {
850  
        {
851  
            if(rv.error() != error::end_of_range)
851  
            if(rv.error() != error::end_of_range)
852  
            {
852  
            {
853  
                // rewind unless error::end_of_range
853  
                // rewind unless error::end_of_range
854  
                it = it1;
854  
                it = it1;
855  
            }
855  
            }
856  
            break;
856  
            break;
857  
        }
857  
        }
858  
        if(n >= M_)
858  
        if(n >= M_)
859  
        {
859  
        {
860  
            // too many
860  
            // too many
861  
            BOOST_URL_RETURN_EC(
861  
            BOOST_URL_RETURN_EC(
862  
                error::mismatch);
862  
                error::mismatch);
863  
        }
863  
        }
864  
    }
864  
    }
865  
    if(n < N_)
865  
    if(n < N_)
866  
    {
866  
    {
867  
        // too few
867  
        // too few
868  
        BOOST_URL_RETURN_EC(
868  
        BOOST_URL_RETURN_EC(
869  
            error::mismatch);
869  
            error::mismatch);
870  
    }
870  
    }
871  
    // good
871  
    // good
872  
    return range<T>(
872  
    return range<T>(
873  
        core::string_view(it0, it - it0),
873  
        core::string_view(it0, it - it0),
874  
            n, any_rule<T>(first_, next_));
874  
            n, any_rule<T>(first_, next_));
875  
}
875  
}
876  

876  

877  
} // grammar
877  
} // grammar
878  
} // urls
878  
} // urls
879  
} // boost
879  
} // boost
880  

880  

881  
#endif
881  
#endif