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  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
11  
#ifndef BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
12  
#define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
12  
#define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/error_types.hpp>
15  
#include <boost/url/error_types.hpp>
16  
#include <boost/url/variant.hpp>
16  
#include <boost/url/variant.hpp>
17  
#include <boost/url/grammar/detail/tuple.hpp>
17  
#include <boost/url/grammar/detail/tuple.hpp>
18  
#include <boost/url/grammar/type_traits.hpp>
18  
#include <boost/url/grammar/type_traits.hpp>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace urls {
21  
namespace urls {
22  
namespace grammar {
22  
namespace grammar {
23  

23  

24  
namespace implementation_defined {
24  
namespace implementation_defined {
25  
template<
25  
template<
26  
    class R0, class... Rn>
26  
    class R0, class... Rn>
27  
class variant_rule_t
27  
class variant_rule_t
28  
{
28  
{
29  
public:
29  
public:
30  
    using value_type = variant2::variant<
30  
    using value_type = variant2::variant<
31  
        typename R0::value_type,
31  
        typename R0::value_type,
32  
        typename Rn::value_type...>;
32  
        typename Rn::value_type...>;
33  

33  

34  
    BOOST_URL_CXX20_CONSTEXPR
34  
    BOOST_URL_CXX20_CONSTEXPR
35  
    auto
35  
    auto
36  
    parse(
36  
    parse(
37  
        char const*& it,
37  
        char const*& it,
38  
        char const* end) const ->
38  
        char const* end) const ->
39  
            system::result<value_type>;
39  
            system::result<value_type>;
40  

40  

41  
    constexpr
41  
    constexpr
42  
    variant_rule_t(
42  
    variant_rule_t(
43  
        R0 const& r0,
43  
        R0 const& r0,
44  
        Rn const&... rn) noexcept
44  
        Rn const&... rn) noexcept
45  
        : rn_(r0, rn...)
45  
        : rn_(r0, rn...)
46  
    {
46  
    {
47  
    }
47  
    }
48  

48  

49  
private:
49  
private:
50  

50  

51  
    detail::tuple<R0, Rn...> rn_;
51  
    detail::tuple<R0, Rn...> rn_;
52  
};
52  
};
53  
} // implementation_defined
53  
} // implementation_defined
54  

54  

55  
/** Match one of a set of rules
55  
/** Match one of a set of rules
56  

56  

57  
    Each specified rule is tried in sequence.
57  
    Each specified rule is tried in sequence.
58  
    When the first match occurs, the result
58  
    When the first match occurs, the result
59  
    is stored and returned in the variant. If
59  
    is stored and returned in the variant. If
60  
    no match occurs, an error is returned.
60  
    no match occurs, an error is returned.
61  

61  

62  
    @param r0 The first rule to match
62  
    @param r0 The first rule to match
63  
    @param rn A list of one or more rules to match
63  
    @param rn A list of one or more rules to match
64  
    @return The variant rule
64  
    @return The variant rule
65  

65  

66  
    @par Value Type
66  
    @par Value Type
67  
    @code
67  
    @code
68  
    using value_type = variant< typename Rules::value_type... >;
68  
    using value_type = variant< typename Rules::value_type... >;
69  
    @endcode
69  
    @endcode
70  

70  

71  
    @par Example
71  
    @par Example
72  
    Rules are used with the function @ref parse.
72  
    Rules are used with the function @ref parse.
73  
    @code
73  
    @code
74  
    // request-target = origin-form
74  
    // request-target = origin-form
75  
    //                / absolute-form
75  
    //                / absolute-form
76  
    //                / authority-form
76  
    //                / authority-form
77  
    //                / asterisk-form
77  
    //                / asterisk-form
78  

78  

79  
    system::result< variant< url_view, url_view, authority_view, core::string_view > > rv = grammar::parse(
79  
    system::result< variant< url_view, url_view, authority_view, core::string_view > > rv = grammar::parse(
80  
        "/index.html?width=full",
80  
        "/index.html?width=full",
81  
        variant_rule(
81  
        variant_rule(
82  
            origin_form_rule,
82  
            origin_form_rule,
83  
            absolute_uri_rule,
83  
            absolute_uri_rule,
84  
            authority_rule,
84  
            authority_rule,
85  
            delim_rule('*') ) );
85  
            delim_rule('*') ) );
86  
    @endcode
86  
    @endcode
87  

87  

88  
    @par BNF
88  
    @par BNF
89  
    @code
89  
    @code
90  
    variant     = rule1 / rule2 / rule3...
90  
    variant     = rule1 / rule2 / rule3...
91  
    @endcode
91  
    @endcode
92  

92  

93  
    @par Specification
93  
    @par Specification
94  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.2"
94  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.2"
95  
        >3.2.  Alternatives (rfc5234)</a>
95  
        >3.2.  Alternatives (rfc5234)</a>
96  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-5.3"
96  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-5.3"
97  
        >5.3.  Request Target (rfc7230)</a>
97  
        >5.3.  Request Target (rfc7230)</a>
98  

98  

99  
    @see
99  
    @see
100  
        @ref absolute_uri_rule,
100  
        @ref absolute_uri_rule,
101  
        @ref authority_rule,
101  
        @ref authority_rule,
102  
        @ref delim_rule,
102  
        @ref delim_rule,
103  
        @ref parse,
103  
        @ref parse,
104  
        @ref origin_form_rule,
104  
        @ref origin_form_rule,
105  
        @ref url_view.
105  
        @ref url_view.
106  
*/
106  
*/
107  
template<
107  
template<
108  
    BOOST_URL_CONSTRAINT(Rule) R0,
108  
    BOOST_URL_CONSTRAINT(Rule) R0,
109  
    BOOST_URL_CONSTRAINT(Rule)... Rn>
109  
    BOOST_URL_CONSTRAINT(Rule)... Rn>
110  
constexpr
110  
constexpr
111  
auto
111  
auto
112  
variant_rule(
112  
variant_rule(
113  
    R0 const& r0,
113  
    R0 const& r0,
114  
    Rn const&... rn) noexcept ->
114  
    Rn const&... rn) noexcept ->
115  
        implementation_defined::variant_rule_t<R0, Rn...>;
115  
        implementation_defined::variant_rule_t<R0, Rn...>;
116  

116  

117  
} // grammar
117  
} // grammar
118  
} // urls
118  
} // urls
119  
} // boost
119  
} // boost
120  

120  

121  
#include <boost/url/grammar/impl/variant_rule.hpp>
121  
#include <boost/url/grammar/impl/variant_rule.hpp>
122  

122  

123  
#endif
123  
#endif