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

10  

10  
#ifndef BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
11  
#ifndef BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
11  
#define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
12  
#define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
12  

13  

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

19  

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

23  

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

33  

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

40  

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

48  

47  
private:
49  
private:
48  

50  

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

54  

53  
/** Match one of a set of rules
55  
/** Match one of a set of rules
54  

56  

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

61  

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

65  

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

70  

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

78  

77  
    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(
78  
        "/index.html?width=full",
80  
        "/index.html?width=full",
79  
        variant_rule(
81  
        variant_rule(
80  
            origin_form_rule,
82  
            origin_form_rule,
81  
            absolute_uri_rule,
83  
            absolute_uri_rule,
82  
            authority_rule,
84  
            authority_rule,
83  
            delim_rule('*') ) );
85  
            delim_rule('*') ) );
84  
    @endcode
86  
    @endcode
85  

87  

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

92  

91  
    @par Specification
93  
    @par Specification
92  
    @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"
93  
        >3.2.  Alternatives (rfc5234)</a>
95  
        >3.2.  Alternatives (rfc5234)</a>
94  
    @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"
95  
        >5.3.  Request Target (rfc7230)</a>
97  
        >5.3.  Request Target (rfc7230)</a>
96  

98  

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

116  

115  
} // grammar
117  
} // grammar
116  
} // urls
118  
} // urls
117  
} // boost
119  
} // boost
118  

120  

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

122  

121  
#endif
123  
#endif