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