GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/grammar/charset.hpp
Date: 2025-11-10 19:06:22
Exec Total Coverage
Lines: 11 11 100.0%
Functions: 20 20 100.0%
Branches: 0 0 -%

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