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

13  

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

21  

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

25  

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

33  

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

39  

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

50  

51  
/** Match a rule, or the empty string
51  
/** Match a rule, or the empty string
52  

52  

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

57  

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

62  

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

68  

69  
    @par BNF
69  
    @par BNF
70  
    @code
70  
    @code
71  
    optional     = [ rule ]
71  
    optional     = [ rule ]
72  
    @endcode
72  
    @endcode
73  

73  

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

77  

78  
    @param r The rule to match
78  
    @param r The rule to match
79  
    @return The adapted rule
79  
    @return The adapted rule
80  

80  

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

97  

98  
} // grammar
98  
} // grammar
99  
} // urls
99  
} // urls
100  
} // boost
100  
} // boost
101  

101  

102  
#include <boost/url/grammar/impl/optional_rule.hpp>
102  
#include <boost/url/grammar/impl/optional_rule.hpp>
103  

103  

104  
#endif
104  
#endif