Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:07:54

0001 //
0002 // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_GRAMMAR_CHARSET_HPP
0011 #define BOOST_URL_GRAMMAR_CHARSET_HPP
0012 
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/url/grammar/detail/charset.hpp>
0015 #include <boost/static_assert.hpp>
0016 #include <cstdint>
0017 #include <type_traits>
0018 #include <utility>
0019 
0020 #ifdef BOOST_URL_HAS_CONCEPTS
0021 #include <concepts>
0022 #endif
0023 
0024 namespace boost {
0025 namespace urls {
0026 namespace grammar {
0027 
0028 namespace implementation_defined
0029 {
0030 template<class T, class = void>
0031 struct is_charset : std::false_type {};
0032 
0033 template<class T>
0034 struct is_charset<T, void_t<
0035     decltype(
0036     std::declval<bool&>() =
0037         std::declval<T const&>().operator()(
0038             std::declval<char>())
0039             ) > > : std::true_type
0040 {
0041 };
0042 }
0043 
0044 /** Alias for `std::true_type` if T satisfies @ref CharSet.
0045 
0046     This metafunction determines if the
0047     type `T` meets these requirements of
0048     <em>CharSet</em>:
0049 
0050     @li An instance of `T` is invocable
0051     with this equivalent function signature:
0052     @code
0053     bool T::operator()( char ) const noexcept;
0054     @endcode
0055 
0056     @par Example
0057     Use with `enable_if` on the return value:
0058     @code
0059     template< class CharSet >
0060     typename std::enable_if< is_charset<T>::value >::type
0061     func( CharSet const& cs );
0062     @endcode
0063 
0064     @tparam T the type to check.
0065 */
0066 template<class T>
0067 using is_charset = BOOST_URL_SEE_BELOW(implementation_defined::is_charset<T>);
0068 
0069 #ifdef BOOST_URL_HAS_CONCEPTS
0070 /** Concept for a CharSet
0071 
0072     A `CharSet` is a unary predicate which is invocable with
0073     this equivalent signature:
0074 
0075     @code
0076     bool( char ch ) const noexcept;
0077     @endcode
0078 
0079     The predicate returns `true` if `ch` is a member of the
0080     set, or `false` otherwise.
0081 
0082     @par Exemplar
0083 
0084     For best results, it is suggested that all constructors and
0085     member functions for character sets be marked `constexpr`.
0086 
0087     @code
0088     struct CharSet
0089     {
0090         bool operator()( char c ) const noexcept;
0091 
0092         // These are both optional. If either or both are left
0093         // unspecified, a default implementation will be used.
0094         //
0095         char const* find_if( char const* first, char const* last ) const noexcept;
0096         char const* find_if_not( char const* first, char const* last ) const noexcept;
0097     };
0098     @endcode
0099 
0100     @par Models
0101 
0102     @li @ref alnum_chars
0103     @li @ref alpha_chars
0104     @li @ref digit_chars
0105     @li @ref hexdig_chars
0106     @li @ref lut_chars
0107 
0108     @see
0109         @ref is_charset,
0110         @ref find_if,
0111         @ref find_if_not.
0112 
0113  */
0114 template <class T>
0115 concept CharSet =
0116     requires (T const t, char c)
0117 {
0118     { t(c) } -> std::convertible_to<bool>;
0119 };
0120 #endif
0121 
0122 
0123 //------------------------------------------------
0124 
0125 /** Find the first character in the string that is in the set.
0126 
0127     @par Exception Safety
0128     Throws nothing.
0129 
0130     @return A pointer to the found character,
0131     otherwise the value `last`.
0132 
0133     @param first A pointer to the first character
0134     in the string to search.
0135 
0136     @param last A pointer to one past the last
0137     character in the string to search.
0138 
0139     @param cs The character set to use.
0140 
0141     @see
0142         @ref find_if_not.
0143 */
0144 template<BOOST_URL_CONSTRAINT(CharSet) CS>
0145 char const*
0146 find_if(
0147     char const* const first,
0148     char const* const last,
0149     CS const& cs) noexcept
0150 {
0151     // If you get a compile error here
0152     // it means your type does not meet
0153     // the requirements. Please check the
0154     // documentation.
0155     static_assert(
0156         is_charset<CS>::value,
0157         "CharSet requirements not met");
0158 
0159     return detail::find_if(first, last, cs,
0160         detail::has_find_if<CS>{});
0161 }
0162 
0163 /** Find the first character in the string that is not in CharSet
0164 
0165     @par Exception Safety
0166     Throws nothing.
0167 
0168     @return A pointer to the found character,
0169     otherwise the value `last`.
0170 
0171     @param first A pointer to the first character
0172     in the string to search.
0173 
0174     @param last A pointer to one past the last
0175     character in the string to search.
0176 
0177     @param cs The character set to use.
0178 
0179     @see
0180         @ref find_if_not.
0181 */
0182 template<BOOST_URL_CONSTRAINT(CharSet) CS>
0183 char const*
0184 find_if_not(
0185     char const* const first,
0186     char const* const last,
0187     CS const& cs) noexcept
0188 {
0189     // If you get a compile error here
0190     // it means your type does not meet
0191     // the requirements. Please check the
0192     // documentation.
0193     static_assert(
0194         is_charset<CS>::value,
0195         "CharSet requirements not met");
0196 
0197     return detail::find_if_not(first, last, cs,
0198         detail::has_find_if_not<CS>{});
0199 }
0200 
0201 //------------------------------------------------
0202 
0203 namespace implementation_defined {
0204 template<class CharSet>
0205 struct charset_ref
0206 {
0207     CharSet const& cs_;
0208 
0209     constexpr
0210     bool
0211     operator()(char ch) const noexcept
0212     {
0213         return cs_(ch);
0214     }
0215 
0216     char const*
0217     find_if(
0218         char const* first,
0219         char const* last) const noexcept
0220     {
0221         return grammar::find_if(
0222             first, last, cs_);
0223     }
0224 
0225     char const*
0226     find_if_not(
0227         char const* first,
0228         char const* last) const noexcept
0229     {
0230         return grammar::find_if_not(
0231             first, last, cs_ );
0232     }
0233 };
0234 } // implementation_defined
0235 
0236 /** Return a reference to a character set
0237 
0238     This function returns a character set which
0239     references the specified object. This is
0240     used to reduce the number of bytes of
0241     storage (`sizeof`) required by a combinator
0242     when it stores a copy of the object.
0243     <br>
0244     Ownership of the object is not transferred;
0245     the caller is responsible for ensuring the
0246     lifetime of the object is extended until it
0247     is no longer referenced. For best results,
0248     `ref` should only be used with compile-time
0249     constants.
0250 
0251     @tparam CharSet The character set type
0252     @param cs The character set to use
0253     @return The character set as a reference type
0254 */
0255 template<BOOST_URL_CONSTRAINT(CharSet) CS>
0256 constexpr
0257 typename std::enable_if<
0258     is_charset<CS>::value &&
0259     ! std::is_same<CS,
0260         implementation_defined::charset_ref<CS> >::value,
0261     implementation_defined::charset_ref<CS> >::type
0262 ref(CS const& cs) noexcept
0263 {
0264     return implementation_defined::charset_ref<CS>{cs};
0265 }
0266 
0267 } // grammar
0268 } // urls
0269 } // boost
0270 
0271 #endif