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_OPTIONAL_RULE_HPP
10  
#ifndef BOOST_URL_GRAMMAR_OPTIONAL_RULE_HPP
11  
#define BOOST_URL_GRAMMAR_OPTIONAL_RULE_HPP
11  
#define BOOST_URL_GRAMMAR_OPTIONAL_RULE_HPP
12  

12  

13  
#include <boost/url/detail/config.hpp>
13  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/optional.hpp>
14  
#include <boost/url/optional.hpp>
15  
#include <boost/url/error_types.hpp>
15  
#include <boost/url/error_types.hpp>
16  
#include <boost/url/grammar/type_traits.hpp>
16  
#include <boost/url/grammar/type_traits.hpp>
17  
#include <boost/core/empty_value.hpp>
17  
#include <boost/core/empty_value.hpp>
18  
#include <boost/core/detail/static_assert.hpp>
18  
#include <boost/core/detail/static_assert.hpp>
19  
#include <boost/assert.hpp>
19  
#include <boost/assert.hpp>
20  

20  

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

24  

25  
namespace implementation_defined {
25  
namespace implementation_defined {
26  
template<class Rule>
26  
template<class Rule>
27  
struct optional_rule_t
27  
struct optional_rule_t
28  
    : private empty_value<Rule>
28  
    : private empty_value<Rule>
29  
{
29  
{
30  
    using value_type = boost::optional<
30  
    using value_type = boost::optional<
31  
        typename Rule::value_type>;
31  
        typename Rule::value_type>;
32  

32  

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

37  

38  
    constexpr
38  
    constexpr
39  
    optional_rule_t(
39  
    optional_rule_t(
40  
        Rule const& r) noexcept
40  
        Rule const& r) noexcept
41  
        : empty_value<Rule>(
41  
        : empty_value<Rule>(
42  
            empty_init,
42  
            empty_init,
43  
            r)
43  
            r)
44  
    {
44  
    {
45  
    }
45  
    }
46  
};
46  
};
47  
} // implementation_defined
47  
} // implementation_defined
48  

48  

49  
/** Match a rule, or the empty string
49  
/** Match a rule, or the empty string
50  

50  

51  
    Optional BNF elements are denoted with
51  
    Optional BNF elements are denoted with
52  
    square brackets. If the specified rule
52  
    square brackets. If the specified rule
53  
    returns any error it is treated as if
53  
    returns any error it is treated as if
54  
    the rule did not match.
54  
    the rule did not match.
55  

55  

56  
    @par Value Type
56  
    @par Value Type
57  
    @code
57  
    @code
58  
    using value_type = optional< typename Rule::value_type >;
58  
    using value_type = optional< typename Rule::value_type >;
59  
    @endcode
59  
    @endcode
60  

60  

61  
    @par Example
61  
    @par Example
62  
    Rules are used with the function @ref grammar::parse.
62  
    Rules are used with the function @ref grammar::parse.
63  
    @code
63  
    @code
64  
    system::result< optional< core::string_view > > rv = parse( "", optional_rule( token_rule( alpha_chars ) ) );
64  
    system::result< optional< core::string_view > > rv = parse( "", optional_rule( token_rule( alpha_chars ) ) );
65  
    @endcode
65  
    @endcode
66  

66  

67  
    @par BNF
67  
    @par BNF
68  
    @code
68  
    @code
69  
    optional     = [ rule ]
69  
    optional     = [ rule ]
70  
    @endcode
70  
    @endcode
71  

71  

72  
    @par Specification
72  
    @par Specification
73  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.8"
73  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.8"
74  
        >3.8.  Optional Sequence (rfc5234)</a>
74  
        >3.8.  Optional Sequence (rfc5234)</a>
75  

75  

76  
    @param r The rule to match
76  
    @param r The rule to match
77  
    @return The adapted rule
77  
    @return The adapted rule
78  

78  

79  
    @see
79  
    @see
80  
        @ref alpha_chars,
80  
        @ref alpha_chars,
81  
        @ref parse,
81  
        @ref parse,
82  
        @ref optional,
82  
        @ref optional,
83  
        @ref token_rule.
83  
        @ref token_rule.
84  
*/
84  
*/
85  
template<BOOST_URL_CONSTRAINT(Rule) R>
85  
template<BOOST_URL_CONSTRAINT(Rule) R>
86  
auto
86  
auto
87  
constexpr
87  
constexpr
88  
optional_rule(
88  
optional_rule(
89  
    R const& r) ->
89  
    R const& r) ->
90  
        implementation_defined::optional_rule_t<R>
90  
        implementation_defined::optional_rule_t<R>
91  
{
91  
{
92  
    BOOST_CORE_STATIC_ASSERT(grammar::is_rule<R>::value);
92  
    BOOST_CORE_STATIC_ASSERT(grammar::is_rule<R>::value);
93  
    return { r };
93  
    return { r };
94  
}
94  
}
95  

95  

96  
} // grammar
96  
} // grammar
97  
} // urls
97  
} // urls
98  
} // boost
98  
} // boost
99  

99  

100  
#include <boost/url/grammar/impl/optional_rule.hpp>
100  
#include <boost/url/grammar/impl/optional_rule.hpp>
101  

101  

102  
#endif
102  
#endif