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_VARIANT_RULE_HPP
10  
#ifndef BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
11  
#define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
11  
#define BOOST_URL_GRAMMAR_VARIANT_RULE_HPP
12  

12  

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

18  

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

22  

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

32  

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

38  

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

46  

47  
private:
47  
private:
48  

48  

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

52  

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

54  

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

59  

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

63  

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

68  

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

76  

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

85  

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

90  

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

96  

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

114  

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

118  

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

120  

121  
#endif
121  
#endif