Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : //
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)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 : #ifndef BOOST_URL_GRAMMAR_CHARSET_HPP
11 : #define BOOST_URL_GRAMMAR_CHARSET_HPP
12 :
13 : #include <boost/url/detail/config.hpp>
14 : #include <boost/url/grammar/detail/charset.hpp>
15 : #include <boost/static_assert.hpp>
16 : #include <cstdint>
17 : #include <type_traits>
18 : #include <utility>
19 :
20 : namespace boost {
21 : namespace urls {
22 : namespace grammar {
23 :
24 : namespace see_below
25 : {
26 : template<class T, class = void>
27 : struct is_charset : std::false_type {};
28 :
29 : template<class T>
30 : struct is_charset<T, void_t<
31 : decltype(
32 : std::declval<bool&>() =
33 : std::declval<T const&>().operator()(
34 : std::declval<char>())
35 : ) > > : std::true_type
36 : {
37 : };
38 : }
39 :
40 : /** Alias for `std::true_type` if T satisfies <em>CharSet</em>.
41 :
42 : This metafunction determines if the
43 : type `T` meets these requirements of
44 : <em>CharSet</em>:
45 :
46 : @li An instance of `T` is invocable
47 : with this equivalent function signature:
48 : @code
49 : bool T::operator()( char ) const noexcept;
50 : @endcode
51 :
52 : @par Example
53 : Use with `enable_if` on the return value:
54 : @code
55 : template< class CharSet >
56 : typename std::enable_if< is_charset<T>::value >::type
57 : func( CharSet const& cs );
58 : @endcode
59 :
60 : @tparam T the type to check.
61 : */
62 : template<class T>
63 : using is_charset = BOOST_URL_SEE_BELOW(see_below::is_charset<T>);
64 :
65 : //------------------------------------------------
66 :
67 : /** Find the first character in the string that is in the set.
68 :
69 : @par Exception Safety
70 : Throws nothing.
71 :
72 : @return A pointer to the found character,
73 : otherwise the value `last`.
74 :
75 : @param first A pointer to the first character
76 : in the string to search.
77 :
78 : @param last A pointer to one past the last
79 : character in the string to search.
80 :
81 : @param cs The character set to use.
82 :
83 : @see
84 : @ref find_if_not.
85 : */
86 : template<class CharSet>
87 : char const*
88 2884 : find_if(
89 : char const* const first,
90 : char const* const last,
91 : CharSet const& cs) noexcept
92 : {
93 : // If you get a compile error here
94 : // it means your type does not meet
95 : // the requirements. Please check the
96 : // documentation.
97 : static_assert(
98 : is_charset<CharSet>::value,
99 : "CharSet requirements not met");
100 :
101 5768 : return detail::find_if(first, last, cs,
102 2884 : detail::has_find_if<CharSet>{});
103 : }
104 :
105 : /** Find the first character in the string that is not in CharSet
106 :
107 : @par Exception Safety
108 : Throws nothing.
109 :
110 : @return A pointer to the found character,
111 : otherwise the value `last`.
112 :
113 : @param first A pointer to the first character
114 : in the string to search.
115 :
116 : @param last A pointer to one past the last
117 : character in the string to search.
118 :
119 : @param cs The character set to use.
120 :
121 : @see
122 : @ref find_if_not.
123 : */
124 : template<class CharSet>
125 : char const*
126 17724 : find_if_not(
127 : char const* const first,
128 : char const* const last,
129 : CharSet const& cs) noexcept
130 : {
131 : // If you get a compile error here
132 : // it means your type does not meet
133 : // the requirements. Please check the
134 : // documentation.
135 : static_assert(
136 : is_charset<CharSet>::value,
137 : "CharSet requirements not met");
138 :
139 35448 : return detail::find_if_not(first, last, cs,
140 17724 : detail::has_find_if_not<CharSet>{});
141 : }
142 :
143 : //------------------------------------------------
144 :
145 : #ifndef BOOST_URL_DOCS
146 : namespace implementation_defined {
147 :
148 : template<class CharSet>
149 : struct charset_ref
150 : {
151 : CharSet const& cs_;
152 :
153 : constexpr
154 : bool
155 : operator()(char ch) const noexcept
156 : {
157 : return cs_(ch);
158 : }
159 :
160 : char const*
161 : find_if(
162 : char const* first,
163 : char const* last) const noexcept
164 : {
165 : return grammar::find_if(
166 : first, last, cs_);
167 : }
168 :
169 : char const*
170 2384 : find_if_not(
171 : char const* first,
172 : char const* last) const noexcept
173 : {
174 2384 : return grammar::find_if_not(
175 2384 : first, last, cs_ );
176 : }
177 : };
178 :
179 : } // implementation_defined
180 : #endif
181 :
182 : /** Return a reference to a character set
183 :
184 : This function returns a character set which
185 : references the specified object. This is
186 : used to reduce the number of bytes of
187 : storage (`sizeof`) required by a combinator
188 : when it stores a copy of the object.
189 : <br>
190 : Ownership of the object is not transferred;
191 : the caller is responsible for ensuring the
192 : lifetime of the object is extended until it
193 : is no longer referenced. For best results,
194 : `ref` should only be used with compile-time
195 : constants.
196 : */
197 : #ifdef BOOST_URL_DOCS
198 : template<class CharSet>
199 : constexpr
200 : __implementation_defined__
201 : ref(CharSet const& cs) noexcept;
202 : #else
203 :
204 : /** Return a reference to a character set
205 :
206 : This function returns a character set which
207 : references the specified object. This is
208 : used to reduce the number of bytes of
209 : storage (`sizeof`) required by a combinator
210 : when it stores a copy of the object.
211 : <br>
212 : Ownership of the object is not transferred;
213 : the caller is responsible for ensuring the
214 : lifetime of the object is extended until it
215 : is no longer referenced. For best results,
216 : `ref` should only be used with compile-time
217 : constants.
218 : */
219 : template<class CharSet>
220 : constexpr
221 : typename std::enable_if<
222 : is_charset<CharSet>::value &&
223 : ! std::is_same<CharSet,
224 : implementation_defined::charset_ref<CharSet> >::value,
225 : implementation_defined::charset_ref<CharSet> >::type
226 2234 : ref(CharSet const& cs) noexcept
227 : {
228 : return implementation_defined::charset_ref<
229 2234 : CharSet>{cs};
230 : }
231 : #endif
232 :
233 : } // grammar
234 : } // urls
235 : } // boost
236 :
237 : #endif
|