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_DELIM_RULE_HPP
11  
#ifndef BOOST_URL_GRAMMAR_DELIM_RULE_HPP
12  
#define BOOST_URL_GRAMMAR_DELIM_RULE_HPP
12  
#define BOOST_URL_GRAMMAR_DELIM_RULE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/core/detail/string_view.hpp>
15  
#include <boost/core/detail/string_view.hpp>
16  
#include <boost/url/grammar/charset.hpp>
16  
#include <boost/url/grammar/charset.hpp>
17  
#include <boost/url/grammar/error.hpp>
17  
#include <boost/url/grammar/error.hpp>
18  
#include <boost/url/grammar/type_traits.hpp>
18  
#include <boost/url/grammar/type_traits.hpp>
19  
#include <type_traits>
19  
#include <type_traits>
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  
struct ch_delim_rule
26  
struct ch_delim_rule
27  
{
27  
{
28  
    using value_type = core::string_view;
28  
    using value_type = core::string_view;
29  

29  

30  
    constexpr
30  
    constexpr
31  
    ch_delim_rule(char ch) noexcept
31  
    ch_delim_rule(char ch) noexcept
32  
        : ch_(ch)
32  
        : ch_(ch)
33  
    {
33  
    {
34  
    }
34  
    }
35  

35  

36  
    BOOST_URL_CXX20_CONSTEXPR
36  
    BOOST_URL_CXX20_CONSTEXPR
37  
    system::result<value_type>
37  
    system::result<value_type>
38  
    parse(
38  
    parse(
39  
        char const*& it,
39  
        char const*& it,
40  
        char const* end) const noexcept;
40  
        char const* end) const noexcept;
41  

41  

42  
private:
42  
private:
43  
    char ch_;
43  
    char ch_;
44  
};
44  
};
45  
} // implementation_defined
45  
} // implementation_defined
46  

46  

47  
/** Match a character literal
47  
/** Match a character literal
48  

48  

49  
    This matches the specified character.
49  
    This matches the specified character.
50  
    The value is a reference to the character
50  
    The value is a reference to the character
51  
    in the underlying buffer, expressed as a
51  
    in the underlying buffer, expressed as a
52  
    `core::string_view`. The function @ref squelch
52  
    `core::string_view`. The function @ref squelch
53  
    may be used to turn this into `void` instead.
53  
    may be used to turn this into `void` instead.
54  
    If there is no more input, the error code
54  
    If there is no more input, the error code
55  
    @ref error::need_more is returned.
55  
    @ref error::need_more is returned.
56  

56  

57  
    @par Value Type
57  
    @par Value Type
58  
    @code
58  
    @code
59  
    using value_type = core::string_view;
59  
    using value_type = core::string_view;
60  
    @endcode
60  
    @endcode
61  

61  

62  
    @par Example
62  
    @par Example
63  
    Rules are used with the function @ref parse.
63  
    Rules are used with the function @ref parse.
64  
    @code
64  
    @code
65  
    system::result< core::string_view > rv = parse( ".", delim_rule('.') );
65  
    system::result< core::string_view > rv = parse( ".", delim_rule('.') );
66  
    @endcode
66  
    @endcode
67  

67  

68  
    @par BNF
68  
    @par BNF
69  
    @code
69  
    @code
70  
    char        = %00-FF
70  
    char        = %00-FF
71  
    @endcode
71  
    @endcode
72  

72  

73  
    @param ch The character to match
73  
    @param ch The character to match
74  
    @return A rule which matches the character.
74  
    @return A rule which matches the character.
75  

75  

76  
    @see
76  
    @see
77  
        @ref parse,
77  
        @ref parse,
78  
        @ref squelch.
78  
        @ref squelch.
79  
*/
79  
*/
80  
constexpr
80  
constexpr
81  
implementation_defined::ch_delim_rule
81  
implementation_defined::ch_delim_rule
82  
delim_rule( char ch ) noexcept
82  
delim_rule( char ch ) noexcept
83  
{
83  
{
84  
    return {ch};
84  
    return {ch};
85  
}
85  
}
86  

86  

87  
//------------------------------------------------
87  
//------------------------------------------------
88  

88  

89  
namespace implementation_defined {
89  
namespace implementation_defined {
90  
template<class CharSet>
90  
template<class CharSet>
91  
struct cs_delim_rule
91  
struct cs_delim_rule
92  
{
92  
{
93  
    using value_type = core::string_view;
93  
    using value_type = core::string_view;
94  

94  

95  
    constexpr
95  
    constexpr
96  
    cs_delim_rule(
96  
    cs_delim_rule(
97  
        CharSet const& cs) noexcept
97  
        CharSet const& cs) noexcept
98  
        : cs_(cs)
98  
        : cs_(cs)
99  
    {
99  
    {
100  
    }
100  
    }
101  

101  

102  
    system::result<value_type>
102  
    system::result<value_type>
103  
    parse(
103  
    parse(
104  
        char const*& it,
104  
        char const*& it,
105  
        char const* end) const noexcept
105  
        char const* end) const noexcept
106  
    {
106  
    {
107  
        if(it == end)
107  
        if(it == end)
108  
        {
108  
        {
109  
            // end
109  
            // end
110  
            BOOST_URL_RETURN_EC(
110  
            BOOST_URL_RETURN_EC(
111  
                error::need_more);
111  
                error::need_more);
112  
        }
112  
        }
113  
        if(! cs_(*it))
113  
        if(! cs_(*it))
114  
        {
114  
        {
115  
            // wrong character
115  
            // wrong character
116  
            BOOST_URL_RETURN_EC(
116  
            BOOST_URL_RETURN_EC(
117  
                error::mismatch);
117  
                error::mismatch);
118  
        }
118  
        }
119  
        return core::string_view{
119  
        return core::string_view{
120  
            it++, 1 };
120  
            it++, 1 };
121  
    }
121  
    }
122  

122  

123  
private:
123  
private:
124  
    CharSet cs_;
124  
    CharSet cs_;
125  
};
125  
};
126  
} // implementation_defined
126  
} // implementation_defined
127  

127  

128  
/** Match a single character from a character set
128  
/** Match a single character from a character set
129  

129  

130  
    This matches exactly one character which
130  
    This matches exactly one character which
131  
    belongs to the specified character set.
131  
    belongs to the specified character set.
132  
    The value is a reference to the character
132  
    The value is a reference to the character
133  
    in the underlying buffer, expressed as a
133  
    in the underlying buffer, expressed as a
134  
    `core::string_view`. The function @ref squelch
134  
    `core::string_view`. The function @ref squelch
135  
    may be used to turn this into `void` instead.
135  
    may be used to turn this into `void` instead.
136  
    If there is no more input, the error code
136  
    If there is no more input, the error code
137  
    @ref error::need_more is returned.
137  
    @ref error::need_more is returned.
138  

138  

139  
    @par Value Type
139  
    @par Value Type
140  
    @code
140  
    @code
141  
    using value_type = core::string_view;
141  
    using value_type = core::string_view;
142  
    @endcode
142  
    @endcode
143  

143  

144  
    @par Example
144  
    @par Example
145  
    Rules are used with the function @ref parse.
145  
    Rules are used with the function @ref parse.
146  
    @code
146  
    @code
147  
    system::result< core::string_view > rv = parse( "X", delim_rule( alpha_chars ) );
147  
    system::result< core::string_view > rv = parse( "X", delim_rule( alpha_chars ) );
148  
    @endcode
148  
    @endcode
149  

149  

150  
    @param cs The character set to use.
150  
    @param cs The character set to use.
151  
    @return A rule which matches a single character from the set.
151  
    @return A rule which matches a single character from the set.
152  

152  

153  
    @see
153  
    @see
154  
        @ref alpha_chars,
154  
        @ref alpha_chars,
155  
        @ref parse,
155  
        @ref parse,
156  
        @ref squelch.
156  
        @ref squelch.
157  
*/
157  
*/
158  
template<BOOST_URL_CONSTRAINT(CharSet) CS>
158  
template<BOOST_URL_CONSTRAINT(CharSet) CS>
159  
constexpr
159  
constexpr
160  
typename std::enable_if<
160  
typename std::enable_if<
161  
    ! std::is_convertible<
161  
    ! std::is_convertible<
162  
        CS, char>::value,
162  
        CS, char>::value,
163  
    implementation_defined::cs_delim_rule<CS>>::type
163  
    implementation_defined::cs_delim_rule<CS>>::type
164  
delim_rule(
164  
delim_rule(
165  
    CS const& cs) noexcept
165  
    CS const& cs) noexcept
166  
{
166  
{
167  
    // If you get a compile error here it
167  
    // If you get a compile error here it
168  
    // means that your type does not meet
168  
    // means that your type does not meet
169  
    // the requirements for a CharSet.
169  
    // the requirements for a CharSet.
170  
    // Please consult the documentation.
170  
    // Please consult the documentation.
171  
    static_assert(
171  
    static_assert(
172  
        is_charset<CS>::value,
172  
        is_charset<CS>::value,
173  
        "CharSet requirements not met");
173  
        "CharSet requirements not met");
174  

174  

175  
    return implementation_defined::cs_delim_rule<CS>(cs);
175  
    return implementation_defined::cs_delim_rule<CS>(cs);
176  
}
176  
}
177  

177  

178  
} // grammar
178  
} // grammar
179  
} // urls
179  
} // urls
180  
} // boost
180  
} // boost
181  

181  

182  
#include <boost/url/grammar/impl/delim_rule.hpp>
182  
#include <boost/url/grammar/impl/delim_rule.hpp>
183  

183  

184  
#endif
184  
#endif