Line data Source code
1 : // Snap Websites Servers -- a string extension with all compare made case insensitive
2 : // Copyright (c) 2013-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 2 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, write to the Free Software
16 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 : #pragma once
18 :
19 :
20 : // self
21 : //
22 : #include <libutf8/libutf8.h>
23 :
24 : // C++
25 : //
26 : #include <string>
27 :
28 :
29 :
30 : namespace snap
31 : {
32 :
33 :
34 :
35 : /** \brief Case insensitive string.
36 : *
37 : * This class is an overload of the string template which allows you to
38 : * create case insensitive strings as far as the comparison operators
39 : * are concerned. All the other functions still work the same way.
40 : *
41 : * This is particularly useful if you manage an std::map<> with a string as
42 : * the key, string which should not be case sensitive.
43 : *
44 : * The comparisons are done using the libutf8::u8casecmp() function.
45 : *
46 : * \sa u8casecmp()
47 : */
48 : template<
49 : class _CharT,
50 : class _Traits = std::char_traits<_CharT>,
51 : class _Alloc = std::allocator<_CharT>
52 : >
53 32 : class case_insensitive_basic_string
54 : : public std::basic_string<_CharT, _Traits, _Alloc>
55 : {
56 : public:
57 : typedef typename std::basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
58 :
59 1 : case_insensitive_basic_string() noexcept(std::is_nothrow_default_constructible<_Alloc>::value)
60 1 : : std::basic_string<_CharT, _Traits, _Alloc>()
61 : {
62 1 : }
63 :
64 1 : explicit case_insensitive_basic_string(_Alloc const & __a)
65 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__a)
66 : {
67 1 : }
68 :
69 1 : case_insensitive_basic_string(size_type __n, _CharT __c, _Alloc const & __a = _Alloc())
70 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__n, __c, __a)
71 : {
72 1 : }
73 :
74 : // the following are for C++17 and over
75 : // (and then the next two constructors will not set __n)
76 : //
77 : //case_insensitive_basic_string(std::basic_string<_CharT, _Traits, _Alloc> const & __str, size_type __pos, _Alloc const & __a = _Alloc())
78 : // : std::basic_string<_CharT, _Traits, _Alloc>(__str, __pos, __a)
79 : //{
80 : //}
81 : //
82 : //case_insensitive_basic_string(case_insensitive_basic_string const & __str, size_type __pos, _Alloc const & __a = _Alloc())
83 : // : std::basic_string<_CharT, _Traits, _Alloc>(static_cast<std::basic_string<_CharT, _Traits, _Alloc> const &>(__str), __pos, __a)
84 : //{
85 : //}
86 :
87 2 : case_insensitive_basic_string(std::basic_string<_CharT, _Traits, _Alloc> const & __str, size_type __pos, size_type __n = std::basic_string<_CharT, _Traits, _Alloc>::npos, _Alloc const & __a = _Alloc())
88 2 : : std::basic_string<_CharT, _Traits, _Alloc>(__str, __pos, __n, __a)
89 : {
90 2 : }
91 :
92 2 : case_insensitive_basic_string(case_insensitive_basic_string const & __str, size_type __pos, size_type __n = std::basic_string<_CharT, _Traits, _Alloc>::npos, _Alloc const & __a = _Alloc())
93 2 : : std::basic_string<_CharT, _Traits, _Alloc>(__str, __pos, __n, __a)
94 : {
95 2 : }
96 :
97 1 : case_insensitive_basic_string(_CharT const * __d, size_type __n, _Alloc const & __a = _Alloc())
98 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__d, __n, __a)
99 : {
100 1 : }
101 :
102 17 : case_insensitive_basic_string(_CharT const * __d, _Alloc const & __a = _Alloc())
103 17 : : std::basic_string<_CharT, _Traits, _Alloc>(__d, __a)
104 : {
105 17 : }
106 :
107 : template<class _InputIterator>
108 1 : case_insensitive_basic_string(_InputIterator __beg, _InputIterator __end, _Alloc const & __a = _Alloc())
109 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__beg, __end, __a)
110 : {
111 1 : }
112 :
113 1 : case_insensitive_basic_string(std::basic_string<_CharT, _Traits, _Alloc> const & __str)
114 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__str)
115 : {
116 1 : }
117 :
118 1 : case_insensitive_basic_string(case_insensitive_basic_string const & __str)
119 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__str)
120 : {
121 1 : }
122 :
123 1 : case_insensitive_basic_string(std::basic_string<_CharT, _Traits, _Alloc> && __str) noexcept
124 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__str)
125 : {
126 1 : }
127 :
128 : case_insensitive_basic_string(case_insensitive_basic_string && __str) noexcept
129 : : std::basic_string<_CharT, _Traits, _Alloc>(__str)
130 : {
131 : }
132 :
133 1 : case_insensitive_basic_string(std::basic_string<_CharT, _Traits, _Alloc> && __str, _Alloc const & __a)
134 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__str, __a)
135 : {
136 1 : }
137 :
138 1 : case_insensitive_basic_string(case_insensitive_basic_string && __str, _Alloc const & __a)
139 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__str, __a)
140 : {
141 1 : }
142 :
143 1 : case_insensitive_basic_string(std::initializer_list<_CharT> __l, _Alloc const & __a = _Alloc())
144 1 : : std::basic_string<_CharT, _Traits, _Alloc>(__l, __a)
145 : {
146 1 : }
147 :
148 :
149 3 : friend bool operator == (case_insensitive_basic_string const & lhs, std::basic_string<_CharT, _Traits, _Alloc> const & rhs)
150 : {
151 3 : return libutf8::u8casecmp(lhs, rhs) == 0;
152 : }
153 :
154 2 : friend bool operator == (case_insensitive_basic_string const & lhs, case_insensitive_basic_string const & rhs)
155 : {
156 2 : return libutf8::u8casecmp(lhs, rhs) == 0;
157 : }
158 :
159 3 : friend bool operator == (std::basic_string<_CharT, _Traits, _Alloc> const & lhs, case_insensitive_basic_string const & rhs)
160 : {
161 3 : return libutf8::u8casecmp(lhs, rhs) == 0;
162 : }
163 :
164 16 : friend bool operator == (case_insensitive_basic_string const & lhs, _CharT const * rhs)
165 : {
166 16 : return libutf8::u8casecmp(lhs, rhs) == 0;
167 : }
168 :
169 1 : friend bool operator == (_CharT const * lhs, case_insensitive_basic_string const & rhs)
170 : {
171 1 : return libutf8::u8casecmp(lhs, rhs) == 0;
172 : }
173 :
174 1 : friend bool operator != (case_insensitive_basic_string const & lhs, std::basic_string<_CharT, _Traits, _Alloc> const & rhs)
175 : {
176 1 : return libutf8::u8casecmp(lhs, rhs) != 0;
177 : }
178 :
179 2 : friend bool operator != (case_insensitive_basic_string const & lhs, case_insensitive_basic_string const & rhs)
180 : {
181 2 : return libutf8::u8casecmp(lhs, rhs) != 0;
182 : }
183 :
184 1 : friend bool operator != (std::basic_string<_CharT, _Traits, _Alloc> const & lhs, case_insensitive_basic_string const & rhs)
185 : {
186 1 : return libutf8::u8casecmp(lhs, rhs) != 0;
187 : }
188 :
189 1 : friend bool operator != (case_insensitive_basic_string const & lhs, _CharT const * rhs)
190 : {
191 1 : return libutf8::u8casecmp(lhs, rhs) != 0;
192 : }
193 :
194 1 : friend bool operator != (_CharT const * lhs, case_insensitive_basic_string const & rhs)
195 : {
196 1 : return libutf8::u8casecmp(lhs, rhs) != 0;
197 : }
198 :
199 1 : friend bool operator < (case_insensitive_basic_string const & lhs, std::basic_string<_CharT, _Traits, _Alloc> const & rhs)
200 : {
201 1 : return libutf8::u8casecmp(lhs, rhs) < 0;
202 : }
203 :
204 2 : friend bool operator < (case_insensitive_basic_string const & lhs, case_insensitive_basic_string const & rhs)
205 : {
206 2 : return libutf8::u8casecmp(lhs, rhs) < 0;
207 : }
208 :
209 1 : friend bool operator < (std::basic_string<_CharT, _Traits, _Alloc> const & lhs, case_insensitive_basic_string const & rhs)
210 : {
211 1 : return libutf8::u8casecmp(lhs, rhs) < 0;
212 : }
213 :
214 1 : friend bool operator < (case_insensitive_basic_string const & lhs, _CharT const * rhs)
215 : {
216 1 : return libutf8::u8casecmp(lhs, rhs) < 0;
217 : }
218 :
219 1 : friend bool operator < (_CharT const * lhs, case_insensitive_basic_string const & rhs)
220 : {
221 1 : return libutf8::u8casecmp(lhs, rhs) < 0;
222 : }
223 :
224 1 : friend bool operator <= (case_insensitive_basic_string const & lhs, std::basic_string<_CharT, _Traits, _Alloc> const & rhs)
225 : {
226 1 : return libutf8::u8casecmp(lhs, rhs) <= 0;
227 : }
228 :
229 2 : friend bool operator <= (case_insensitive_basic_string const & lhs, case_insensitive_basic_string const & rhs)
230 : {
231 2 : return libutf8::u8casecmp(lhs, rhs) <= 0;
232 : }
233 :
234 1 : friend bool operator <= (std::basic_string<_CharT, _Traits, _Alloc> const & lhs, case_insensitive_basic_string const & rhs)
235 : {
236 1 : return libutf8::u8casecmp(lhs, rhs) <= 0;
237 : }
238 :
239 1 : friend bool operator <= (case_insensitive_basic_string const & lhs, _CharT const * rhs)
240 : {
241 1 : return libutf8::u8casecmp(lhs, rhs) <= 0;
242 : }
243 :
244 1 : friend bool operator <= (_CharT const * lhs, case_insensitive_basic_string const & rhs)
245 : {
246 1 : return libutf8::u8casecmp(lhs, rhs) <= 0;
247 : }
248 :
249 1 : friend bool operator > (case_insensitive_basic_string const & lhs, std::basic_string<_CharT, _Traits, _Alloc> const & rhs)
250 : {
251 1 : return libutf8::u8casecmp(lhs, rhs) > 0;
252 : }
253 :
254 2 : friend bool operator > (case_insensitive_basic_string const & lhs, case_insensitive_basic_string const & rhs)
255 : {
256 2 : return libutf8::u8casecmp(lhs, rhs) > 0;
257 : }
258 :
259 1 : friend bool operator > (std::basic_string<_CharT, _Traits, _Alloc> const & lhs, case_insensitive_basic_string const & rhs)
260 : {
261 1 : return libutf8::u8casecmp(lhs, rhs) > 0;
262 : }
263 :
264 1 : friend bool operator > (case_insensitive_basic_string const & lhs, _CharT const * rhs)
265 : {
266 1 : return libutf8::u8casecmp(lhs, rhs) > 0;
267 : }
268 :
269 1 : friend bool operator > (_CharT const * lhs, case_insensitive_basic_string const & rhs)
270 : {
271 1 : return libutf8::u8casecmp(lhs, rhs) > 0;
272 : }
273 :
274 1 : friend bool operator >= (case_insensitive_basic_string const & lhs, std::basic_string<_CharT, _Traits, _Alloc> const & rhs)
275 : {
276 1 : return libutf8::u8casecmp(lhs, rhs) >= 0;
277 : }
278 :
279 2 : friend bool operator >= (case_insensitive_basic_string const & lhs, case_insensitive_basic_string const & rhs)
280 : {
281 2 : return libutf8::u8casecmp(lhs, rhs) >= 0;
282 : }
283 :
284 1 : friend bool operator >= (std::basic_string<_CharT, _Traits, _Alloc> const & lhs, case_insensitive_basic_string const & rhs)
285 : {
286 1 : return libutf8::u8casecmp(lhs, rhs) >= 0;
287 : }
288 :
289 1 : friend bool operator >= (case_insensitive_basic_string const & lhs, _CharT const * rhs)
290 : {
291 1 : return libutf8::u8casecmp(lhs, rhs) >= 0;
292 : }
293 :
294 1 : friend bool operator >= (_CharT const * lhs, case_insensitive_basic_string const & rhs)
295 : {
296 1 : return libutf8::u8casecmp(lhs, rhs) >= 0;
297 : }
298 : };
299 :
300 :
301 : typedef case_insensitive_basic_string<char> case_insensitive_string;
302 :
303 : // TODO add support for other types
304 : //typedef case_insensitive_basic_string<wchar_t> case_insensitive_wstring;
305 : //typedef case_insensitive_basic_string<char16_t> case_insensitive_u16string;
306 : //typedef case_insensitive_basic_string<char32_t> case_insensitive_u32string;
307 :
308 :
309 : }
310 : // snap namespace
311 : // vim: ts=4 sw=4 et
|