File indexing completed on 2025-01-18 09:53:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP
0012 #define BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP
0013
0014 #include <boost/core/detail/string_view.hpp>
0015 #include <boost/assert.hpp>
0016 #include <cstdint>
0017 #include <iterator>
0018 #include <type_traits>
0019
0020 namespace boost {
0021 namespace urls {
0022 namespace grammar {
0023 namespace detail {
0024
0025 template<class T, class = void>
0026 struct is_char_iter : std::false_type {};
0027
0028 template<class T>
0029 struct is_char_iter<T, void_t<
0030 decltype(std::declval<char&>() =
0031 *std::declval<T const&>()),
0032 decltype(std::declval<T&>() =
0033 ++std::declval<T&>()),
0034 decltype(std::declval<bool&>() =
0035 std::declval<T const&>() ==
0036 std::declval<T const&>())
0037 > > : std::integral_constant<bool,
0038 std::is_copy_constructible<T>::value>
0039 {
0040 };
0041
0042 template<class T, class = void>
0043 struct is_char_range : std::false_type {};
0044
0045 template<class T>
0046 struct is_char_range<T, void_t<
0047 decltype(std::declval<T const&>().begin()),
0048 decltype(std::declval<T const&>().end())
0049 > > : std::integral_constant<bool,
0050 is_char_iter<decltype(
0051 std::declval<T const&>(
0052 ).begin())>::value &&
0053 is_char_iter<decltype(
0054 std::declval<T const&>(
0055 ).end())>::value>
0056 {
0057 };
0058
0059 template<class T>
0060 struct type_id_impl
0061 {
0062 static
0063 constexpr
0064 char cid = 0;
0065 };
0066
0067 template<class T>
0068 constexpr
0069 char
0070 type_id_impl<T>::cid;
0071
0072 template<class T>
0073 constexpr
0074 std::uintptr_t
0075 type_id() noexcept
0076 {
0077 return std::uintptr_t(
0078 &type_id_impl<T>::cid);
0079 }
0080
0081
0082
0083 constexpr
0084 char
0085 to_lower(char c) noexcept
0086 {
0087 return
0088 (c >= 'A' &&
0089 c <= 'Z')
0090 ? c + 'a' - 'A'
0091 : c;
0092 }
0093
0094 constexpr
0095 char
0096 to_upper(char c) noexcept
0097 {
0098 return
0099 (c >= 'a' &&
0100 c <= 'z')
0101 ? c - ('a' - 'A')
0102 : c;
0103 }
0104
0105
0106
0107 template<class S0, class S1>
0108 auto
0109 ci_is_equal(
0110 S0 const& s0,
0111 S1 const& s1) ->
0112 typename std::enable_if<
0113 ! std::is_convertible<
0114 S0, core::string_view>::value ||
0115 ! std::is_convertible<
0116 S1, core::string_view>::value,
0117 bool>::type
0118 {
0119
0120
0121
0122
0123
0124 static_assert(
0125 is_char_range<S0>::value,
0126 "Type requirements not met");
0127 static_assert(
0128 is_char_range<S1>::value,
0129 "Type requirements not met");
0130
0131
0132
0133
0134
0135
0136
0137
0138 BOOST_ASSERT(
0139 detail::type_id<S0>() <=
0140 detail::type_id<S1>());
0141
0142 auto it0 = s0.begin();
0143 auto it1 = s1.begin();
0144 auto const end0 = s0.end();
0145 auto const end1 = s1.end();
0146 for(;;)
0147 {
0148 if(it0 == end0)
0149 return it1 == end1;
0150 if(it1 == end1)
0151 return false;
0152 if( to_lower(*it0) !=
0153 to_lower(*it1))
0154 return false;
0155 ++it0;
0156 ++it1;
0157 }
0158 }
0159
0160
0161
0162 BOOST_URL_DECL
0163 bool
0164 ci_is_equal(
0165 core::string_view s0,
0166 core::string_view s1) noexcept;
0167
0168 BOOST_URL_DECL
0169 bool
0170 ci_is_less(
0171 core::string_view s0,
0172 core::string_view s1) noexcept;
0173
0174 }
0175 }
0176 }
0177 }
0178
0179 #endif