Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:27

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 namespace boost {
0021 namespace urls {
0022 namespace grammar {
0023 
0024 /** Alias for `std::true_type` if T satisfies <em>CharSet</em>.
0025 
0026     This metafunction determines if the
0027     type `T` meets these requirements of
0028     <em>CharSet</em>:
0029 
0030     @li An instance of `T` is invocable
0031     with this equivalent function signature:
0032     @code
0033     bool T::operator()( char ) const noexcept;
0034     @endcode
0035 
0036     @par Example
0037     Use with `enable_if` on the return value:
0038     @code
0039     template< class CharSet >
0040     typename std::enable_if< is_charset<T>::value >::type
0041     func( CharSet const& cs );
0042     @endcode
0043 
0044     @tparam T the type to check.
0045 */
0046 #ifdef BOOST_URL_DOCS
0047 template<class T>
0048 using is_charset = __see_below__;
0049 #else
0050 template<class T, class = void>
0051 struct is_charset : std::false_type {};
0052 
0053 template<class T>
0054 struct is_charset<T, void_t<
0055     decltype(
0056     std::declval<bool&>() =
0057         std::declval<T const&>().operator()(
0058             std::declval<char>())
0059             ) > > : std::true_type
0060 {
0061 };
0062 #endif
0063 
0064 //------------------------------------------------
0065 
0066 /** Find the first character in the string that is in the set.
0067 
0068     @par Exception Safety
0069     Throws nothing.
0070 
0071     @return A pointer to the found character,
0072     otherwise the value `last`.
0073 
0074     @param first A pointer to the first character
0075     in the string to search.
0076 
0077     @param last A pointer to one past the last
0078     character in the string to search.
0079 
0080     @param cs The character set to use.
0081 
0082     @see
0083         @ref find_if_not.
0084 */
0085 template<class CharSet>
0086 char const*
0087 find_if(
0088     char const* const first,
0089     char const* const last,
0090     CharSet const& cs) noexcept
0091 {
0092     // If you get a compile error here
0093     // it means your type does not meet
0094     // the requirements. Please check the
0095     // documentation.
0096     static_assert(
0097         is_charset<CharSet>::value,
0098         "CharSet requirements not met");
0099 
0100     return detail::find_if(first, last, cs,
0101         detail::has_find_if<CharSet>{});
0102 }
0103 
0104 /** Find the first character in the string that is not in CharSet
0105 
0106     @par Exception Safety
0107     Throws nothing.
0108 
0109     @return A pointer to the found character,
0110     otherwise the value `last`.
0111 
0112     @param first A pointer to the first character
0113     in the string to search.
0114 
0115     @param last A pointer to one past the last
0116     character in the string to search.
0117 
0118     @param cs The character set to use.
0119 
0120     @see
0121         @ref find_if_not.
0122 */
0123 template<class CharSet>
0124 char const*
0125 find_if_not(
0126     char const* const first,
0127     char const* const last,
0128     CharSet const& cs) noexcept
0129 {
0130     // If you get a compile error here
0131     // it means your type does not meet
0132     // the requirements. Please check the
0133     // documentation.
0134     static_assert(
0135         is_charset<CharSet>::value,
0136         "CharSet requirements not met");
0137 
0138     return detail::find_if_not(first, last, cs,
0139         detail::has_find_if_not<CharSet>{});
0140 }
0141 
0142 //------------------------------------------------
0143 
0144 #ifndef BOOST_URL_DOCS
0145 namespace detail {
0146 
0147 template<class CharSet>
0148 struct charset_ref
0149 {
0150     CharSet const& cs_;
0151 
0152     constexpr
0153     bool
0154     operator()(char ch) const noexcept
0155     {
0156         return cs_(ch);
0157     }
0158 
0159     char const*
0160     find_if(
0161         char const* first,
0162         char const* last) const noexcept
0163     {
0164         return grammar::find_if(
0165             first, last, cs_);
0166     }
0167 
0168     char const*
0169     find_if_not(
0170         char const* first,
0171         char const* last) const noexcept
0172     {
0173         return grammar::find_if_not(
0174             first, last, cs_ );
0175     }
0176 };
0177 
0178 } // detail
0179 #endif
0180 
0181 /** Return a reference to a character set
0182 
0183     This function returns a character set which
0184     references the specified object. This is
0185     used to reduce the number of bytes of
0186     storage (`sizeof`) required by a combinator
0187     when it stores a copy of the object.
0188     <br>
0189     Ownership of the object is not transferred;
0190     the caller is responsible for ensuring the
0191     lifetime of the object is extended until it
0192     is no longer referenced. For best results,
0193     `ref` should only be used with compile-time
0194     constants.
0195 */
0196 template<class CharSet>
0197 constexpr
0198 #ifdef BOOST_URL_DOCS
0199 __implementation_defined__
0200 #else
0201 typename std::enable_if<
0202     is_charset<CharSet>::value &&
0203     ! std::is_same<CharSet,
0204         detail::charset_ref<CharSet> >::value,
0205     detail::charset_ref<CharSet> >::type
0206 #endif
0207 ref(CharSet const& cs) noexcept
0208 {
0209     return detail::charset_ref<
0210         CharSet>{cs};
0211 }
0212 
0213 } // grammar
0214 } // urls
0215 } // boost
0216 
0217 #endif