Line data Source code
1 : //
2 : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 : #ifndef BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP
12 : #define BOOST_URL_GRAMMAR_DETAIL_CI_STRING_HPP
13 :
14 : #include <boost/core/detail/string_view.hpp>
15 : #include <boost/assert.hpp>
16 : #include <cstdint>
17 : #include <iterator>
18 : #include <type_traits>
19 :
20 : namespace boost {
21 : namespace urls {
22 : namespace grammar {
23 : namespace detail {
24 :
25 : template<class T, class = void>
26 : struct is_char_iter : std::false_type {};
27 :
28 : template<class T>
29 : struct is_char_iter<T, void_t<
30 : decltype(std::declval<char&>() =
31 : *std::declval<T const&>()),
32 : decltype(std::declval<T&>() =
33 : ++std::declval<T&>()),
34 : decltype(std::declval<bool&>() =
35 : std::declval<T const&>() ==
36 : std::declval<T const&>())
37 : > > : std::integral_constant<bool,
38 : std::is_copy_constructible<T>::value>
39 : {
40 : };
41 :
42 : template<class T, class = void>
43 : struct is_char_range : std::false_type {};
44 :
45 : template<class T>
46 : struct is_char_range<T, void_t<
47 : decltype(std::declval<T const&>().begin()),
48 : decltype(std::declval<T const&>().end())
49 : > > : std::integral_constant<bool,
50 : is_char_iter<decltype(
51 : std::declval<T const&>(
52 : ).begin())>::value &&
53 : is_char_iter<decltype(
54 : std::declval<T const&>(
55 : ).end())>::value>
56 : {
57 : };
58 :
59 : template<class T>
60 : struct type_id_impl
61 : {
62 : static
63 : constexpr
64 : char cid = 0;
65 : };
66 :
67 : template<class T>
68 : constexpr
69 : char
70 : type_id_impl<T>::cid;
71 :
72 : template<class T>
73 : constexpr
74 : std::uintptr_t
75 756 : type_id() noexcept
76 : {
77 : return std::uintptr_t(
78 756 : &type_id_impl<T>::cid);
79 : }
80 :
81 : //------------------------------------------------
82 :
83 : constexpr
84 : char
85 23499 : to_lower(char c) noexcept
86 : {
87 : return
88 22297 : (c >= 'A' &&
89 : c <= 'Z')
90 488 : ? c + 'a' - 'A'
91 45796 : : c;
92 : }
93 :
94 : constexpr
95 : char
96 189 : to_upper(char c) noexcept
97 : {
98 : return
99 85 : (c >= 'a' &&
100 : c <= 'z')
101 85 : ? c - ('a' - 'A')
102 274 : : c;
103 : }
104 :
105 : //------------------------------------------------
106 :
107 : template<class S0, class S1>
108 : auto
109 252 : ci_is_equal(
110 : S0 const& s0,
111 : S1 const& s1) ->
112 : typename std::enable_if<
113 : ! std::is_convertible<
114 : S0, core::string_view>::value ||
115 : ! std::is_convertible<
116 : S1, core::string_view>::value,
117 : bool>::type
118 : {
119 : /* If you get a compile error here, it
120 : means that a range you passed does
121 : not meet the requirements stated
122 : in the documentation.
123 : */
124 : static_assert(
125 : is_char_range<S0>::value,
126 : "Type requirements not met");
127 : static_assert(
128 : is_char_range<S1>::value,
129 : "Type requirements not met");
130 :
131 : // Arguments are sorted by type to
132 : // reduce the number of function
133 : // template instantiations. This
134 : // works because:
135 : //
136 : // ci_is_equal(s0,s1) == ci_is_equal(s1,s0)
137 : //
138 126 : BOOST_ASSERT(
139 : detail::type_id<S0>() <=
140 : detail::type_id<S1>());
141 :
142 252 : auto it0 = s0.begin();
143 252 : auto it1 = s1.begin();
144 252 : auto const end0 = s0.end();
145 252 : auto const end1 = s1.end();
146 : for(;;)
147 : {
148 352 : if(it0 == end0)
149 64 : return it1 == end1;
150 288 : if(it1 == end1)
151 0 : return false;
152 576 : if( to_lower(*it0) !=
153 288 : to_lower(*it1))
154 188 : return false;
155 100 : ++it0;
156 100 : ++it1;
157 : }
158 : }
159 :
160 : //------------------------------------------------
161 :
162 : BOOST_URL_DECL
163 : bool
164 : ci_is_equal(
165 : core::string_view s0,
166 : core::string_view s1) noexcept;
167 :
168 : BOOST_URL_DECL
169 : bool
170 : ci_is_less(
171 : core::string_view s0,
172 : core::string_view s1) noexcept;
173 :
174 : } // detail
175 : } // grammar
176 : } // urls
177 : } // boost
178 :
179 : #endif
|