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

13  

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

21  

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

25  

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

33  

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

39  

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

50  

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

52  

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

57  

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

62  

61  
    @par Example
63  
    @par Example
62  
    Rules are used with the function @ref grammar::parse.
64  
    Rules are used with the function @ref grammar::parse.
63  
    @code
65  
    @code
64  
    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 ) ) );
65  
    @endcode
67  
    @endcode
66  

68  

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

73  

72  
    @par Specification
74  
    @par Specification
73  
    @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"
74  
        >3.8.  Optional Sequence (rfc5234)</a>
76  
        >3.8.  Optional Sequence (rfc5234)</a>
75  

77  

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

80  

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

97  

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

101  

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

103  

102  
#endif
104  
#endif