include/boost/url/grammar/charset.hpp

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