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

12  

13  
#include <boost/url/detail/config.hpp>
13  
#include <boost/url/detail/config.hpp>
14  
#include <boost/core/detail/string_view.hpp>
14  
#include <boost/core/detail/string_view.hpp>
15  
#include <boost/url/grammar/charset.hpp>
15  
#include <boost/url/grammar/charset.hpp>
16  
#include <boost/url/grammar/error.hpp>
16  
#include <boost/url/grammar/error.hpp>
17  
#include <boost/url/grammar/type_traits.hpp>
17  
#include <boost/url/grammar/type_traits.hpp>
18  
#include <type_traits>
18  
#include <type_traits>
19  

19  

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

23  

24  
namespace implementation_defined {
24  
namespace implementation_defined {
25  
struct ch_delim_rule
25  
struct ch_delim_rule
26  
{
26  
{
27  
    using value_type = core::string_view;
27  
    using value_type = core::string_view;
28  

28  

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

34  

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

40  

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

45  

46  
/** Match a character literal
46  
/** Match a character literal
47  

47  

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

55  

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

60  

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

66  

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

71  

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

74  

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

85  

86  
//------------------------------------------------
86  
//------------------------------------------------
87  

87  

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

93  

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

100  

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

121  

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

126  

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

128  

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

137  

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

142  

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

148  

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

151  

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

173  

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

176  

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

180  

181  
#endif
181  
#endif