neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
quick_string.hpp
Go to the documentation of this file.
1// quick_string.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <string>
40#include <array>
41#include <set>
42#include <algorithm>
43#include <memory>
44#include <iterator>
45#include <type_traits>
46#include <stdexcept>
47#include <iostream>
48#include <string_view>
50
51namespace neolib
52{
53 template <typename charT, typename Traits = std::char_traits<charT>, typename Alloc = std::allocator<charT> >
55 {
56 public:
57 typedef typename std::basic_string<charT, Traits, Alloc> string_type;
58 typedef typename string_type::traits_type traits_type;
59 typedef typename string_type::allocator_type allocator_type;
60 typedef typename string_type::value_type value_type;
61 typedef typename string_type::size_type size_type;
62 typedef typename string_type::difference_type difference_type;
63 typedef typename string_type::reference reference;
64 typedef typename string_type::pointer pointer;
65 typedef typename string_type::iterator iterator;
66 typedef typename string_type::const_reference const_reference;
67 typedef typename string_type::const_pointer const_pointer;
68 typedef typename string_type::const_iterator const_iterator;
69 typedef std::reverse_iterator<iterator> reverse_iterator;
70 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
71 typedef typename std::basic_string_view<charT, Traits> string_view_type;
72 typedef typename string_view_type::const_reference view_const_reference;
73 typedef typename string_view_type::const_pointer view_const_pointer;
74 typedef typename string_view_type::const_iterator view_const_iterator;
75 typedef std::reverse_iterator<view_const_iterator> view_const_reverse_iterator;
76 static const size_type npos;
77 private:
78 typedef std::pair<string_view_type, Alloc> view_contents_type;
79 typedef std::variant<std::monostate, string_type, view_contents_type> contents_type;
80 public:
81 struct not_view_string : std::logic_error { not_view_string() : std::logic_error("neolib::basic_quick_string::not_view_string") {} };
82 public:
83 // construct/copy/destroy
84 explicit basic_quick_string(const Alloc& a = Alloc()) :
85 iContents{ string_type{ a } }
86 {
87 }
89 iContents{ str }
90 {
91 }
93 iContents{ str.iContents }
94 {
95 }
97 iContents{ std::move(str.iContents) }
98 {
99 }
101 iContents{ view_contents_type{ string_view_type{ str.cbegin() + pos, (n == npos ? str.size() - pos : n) }, str.get_allocator() } }
102 {
103 }
104 basic_quick_string(const charT* s, size_type n, const Alloc& a = Alloc()) :
105 iContents{ view_contents_type{ string_view_type{ s, n }, a } }
106 {
107 }
108 basic_quick_string(const charT* s, const Alloc& a = Alloc()) :
109 iContents{ view_contents_type{ string_view_type{ s }, a } }
110 {
111 }
112 basic_quick_string(size_type n, charT c, const Alloc& a = Alloc()) :
113 iContents{ string_type{ n, c, a } }
114 {
115 }
116 template <typename SFINAE = void*>
117 basic_quick_string(const charT* begin, const charT* end, const Alloc& a = Alloc(), typename std::enable_if<!std::is_same<view_const_iterator, const charT*>::value, SFINAE>::type=0) :
118 iContents{ view_contents_type{ string_view_type{ begin, static_cast<size_type>(end - begin) }, a } }
119 {
120 }
121 basic_quick_string(charT* begin, charT* end, const Alloc& a = Alloc()) :
122 iContents{ view_contents_type{ string_view_type{ const_cast<const charT*>(begin), static_cast<size_type>(end - begin) }, a } }
123 {
124 }
125 template<class InputIterator>
126 basic_quick_string(InputIterator begin, InputIterator end, const Alloc& a = Alloc()) :
127 iContents{ string_type{ begin, end, a } }
128 {
129 }
130 basic_quick_string(const basic_quick_string& str, const Alloc& a) :
131 iContents{ std::holds_alternative<string_type>(str.iContents) ?
132 contents_type{ string_type{ std::get<string_type>(str.iContents), a } } :
133 contents_type{ view_contents_type{ std::get<view_contents_type>(str.iContents).first, a } } }
134 {
135 }
137 iContents{ view_contents_type{ string_view_type{ &*begin, static_cast<size_type>(std::distance(begin, end)) }, a } }
138 {
139 }
141 iContents{ view_contents_type{ string_view_type{ &*begin, static_cast<size_type>(std::distance(begin, end)) }, a } }
142 {
143 }
145 {
146 iContents = str.iContents;
147 return *this;
148 }
150 {
151 iContents = view_contents_type{ string_view_type{ s }, Alloc{} };
152 return *this;
153 }
155 {
156 iContents = string_type{ 1, c };
157 return *this;
158 }
159 // iterators
160 iterator begin() { return get_string().begin(); }
161 view_const_iterator begin() const { return is_view() ? get_view_string().begin() : static_cast<string_view_type>(get_string()).begin(); }
162 view_const_iterator cbegin() const { return is_view() ? get_view_string().begin() : static_cast<string_view_type>(get_string()).begin(); }
163 iterator end() { return get_string().end(); }
164 view_const_iterator end() const { return is_view() ? get_view_string().end() : static_cast<string_view_type>(get_string()).end(); }
165 view_const_iterator cend() const { return is_view() ? get_view_string().end() : static_cast<string_view_type>(get_string()).end(); }
172 // capacity
173 size_type size() const { return is_view() ? get_view_string().end() - get_view_string().begin() : get_string().size(); }
174 size_type length() const { return is_view() ? get_view_string().end() - get_view_string().begin() : get_string().length(); }
175 size_type max_size() const { return get_string().max_size(); }
176 void resize(size_type n, charT c) { get_string().resize(n, c); }
177 void resize(size_type n) { get_string().resize(n); }
178 size_type capacity() const { return get_string().capacity(); }
179 void reserve(size_type res_arg = 0) { get_string().reserve(res_arg); }
180 void shrink_to_fit() { get_string().shrink_to_fit(); }
181 void clear() { get_string().clear(); }
182 bool empty() const { return is_view() ? get_view_string().begin() == get_view_string().end() : get_string().empty(); }
183 // element access
185 {
186 if (is_view())
187 return get_view_string()[pos];
188 else
189 return get_string()[pos];
190 }
192 {
193 return get_string()[pos];
194 }
196 {
197 if (is_view())
198 return get_view_string().at(n);
199 else
200 return get_string().at(n);
201 }
203 {
204 return get_string().at(n);
205 }
207 {
208 if (is_view())
209 return get_view_string().back();
210 else
211 return get_string().back();
212 }
214 {
215 return get_string().back();
216 }
217 // modifiers
218 basic_quick_string& operator+=(const basic_quick_string& str) { get_string().operator+=(str.to_std_string_view()); return *this; }
219 basic_quick_string& operator+=(const string_type& str) { get_string().operator+=(str); return *this; }
220 basic_quick_string& operator+=(const charT* s) { get_string().operator+=(s); return *this; }
221 basic_quick_string& operator+=(charT c) { get_string().operator+=(c); return *this; }
222 basic_quick_string& append(const basic_quick_string& str) { get_string().append(str.to_std_string_view()); return *this; }
223 basic_quick_string& append(const string_type& str) { get_string().append(str); return *this; }
224 basic_quick_string& append(const basic_quick_string& str, size_type pos, size_type n) { get_string().append(str.to_std_string_view(), pos, n); return *this; }
225 basic_quick_string& append(const string_type& str, size_type pos, size_type n) { get_string().append(str, pos, n); return *this; }
226 basic_quick_string& append(const charT* s, size_type n) { get_string().append(s, n); return *this; }
227 basic_quick_string& append(const charT* s) { get_string().append(s); return *this; }
228 basic_quick_string& append(size_type n, charT c) { get_string().append(n, c); return *this; }
229 template<class InputIterator>
230 basic_quick_string& append(InputIterator first, InputIterator last) { get_string().append(first, last); return *this; }
231 void push_back(charT c) { get_string().push_back(c); }
232 basic_quick_string& assign(const basic_quick_string& str) { get_string().assign(str.to_std_string_view()); return *this; }
233 basic_quick_string& assign(const string_type& str) { get_string().assign(str); return *this; }
234 basic_quick_string& assign(const basic_quick_string& str, size_type pos, size_type n) { get_string().assign(str.to_std_string_view(), pos, n); return *this; }
235 basic_quick_string& assign(const string_type& str, size_type pos, size_type n) { get_string().assign(str, pos, n); return *this; }
236 basic_quick_string& assign(const charT* s, size_type n) { get_string().assign(s, n); return *this; }
237 basic_quick_string& assign(const charT* s) { get_string().assign(s); return *this; }
238 basic_quick_string& assign(size_type n, charT c) { get_string().assign(n, c); return *this; }
239 template<class InputIterator>
240 basic_quick_string& assign(InputIterator first, InputIterator last) { get_string().assign(first, last); return *this; }
241 basic_quick_string& insert(size_type pos1, const basic_quick_string& str) { get_string().insert(pos1, str.to_std_string_view()); return *this; }
242 basic_quick_string& insert(size_type pos1, const string_type& str) { get_string().insert(pos1, str); return *this; }
243 basic_quick_string& insert(size_type pos1, const basic_quick_string& str, size_type pos2, size_type n) { get_string().insert(pos1, str.to_std_string_view(), pos2, n); return *this; }
244 basic_quick_string& insert(size_type pos1, const string_type& str, size_type pos2, size_type n) { get_string().insert(pos1, str, pos2, n); return *this; }
245 basic_quick_string& insert(size_type pos, const charT* s, size_type n) { get_string().insert(pos, s, n); return *this; }
246 basic_quick_string& insert(size_type pos, const charT* s) { get_string().insert(pos, s); return *this; }
247 basic_quick_string& insert(size_type pos, size_type n, charT c) { get_string().insert(pos, n, c); return *this; }
248 iterator insert(const_iterator p, charT c) { return get_string().insert(p, c); }
249 iterator insert(const_iterator p, size_type n, charT c) { return get_string().insert(p, n, c); }
250 template<class InputIterator>
251 iterator insert(const_iterator p, InputIterator first, InputIterator last) { return get_string().insert(p, first, last); }
252 basic_quick_string& erase(size_type pos = 0, size_type n = npos) { get_string().erase(pos, n); return *this; }
253 iterator erase(iterator p) { return get_string().erase(p); }
254 iterator erase(iterator first, iterator last) { return get_string().erase(first, last); }
255 basic_quick_string& replace(size_type pos1, size_type n1, const basic_quick_string& str) { get_string().replace(pos1, n1, str.to_std_string_view()); return *this; }
256 basic_quick_string& replace(size_type pos1, size_type n1, const string_type& str) { get_string().replace(pos1, n1, str); return *this; }
257 basic_quick_string& replace(size_type pos1, size_type n1, const basic_quick_string& str, size_type pos2, size_type n2) { get_string().replace(pos1, n1, str.to_std_string_view(), pos2, n2); return *this; }
258 basic_quick_string& replace(size_type pos1, size_type n1, const string_type& str, size_type pos2, size_type n2) { get_string().replace(pos1, n1, str, pos2, n2); return *this; }
259 basic_quick_string& replace(size_type pos, size_type n1, const charT* s, size_type n2) { get_string().replace(pos, n1, s, n2); return *this; }
260 basic_quick_string& replace(size_type pos, size_type n1, const charT* s) { get_string().replace(pos, n1, s); return *this; }
261 basic_quick_string& replace(size_type pos, size_type n1, size_type n2, charT c) { get_string().replace(pos, n1, n2, c); return *this; }
262 basic_quick_string& replace(iterator i1, iterator i2, const basic_quick_string& str) { get_string().replace(i1, i2, str.to_std_string_view()); return *this; }
263 basic_quick_string& replace(iterator i1, iterator i2, const string_type& str) { get_string().replace(i1, i2, str); return *this; }
264 basic_quick_string& replace(iterator i1, iterator i2, const charT* s, size_type n) { get_string().replace(i1, i2, s, n); return *this; }
265 basic_quick_string& replace(iterator i1, iterator i2, const charT* s) { get_string().replace(i1, i2, s); return *this; }
266 basic_quick_string& replace(iterator i1, iterator i2, size_type n, charT c) { get_string().replace(i1, i2, n, c); return *this; }
267 template<class InputIterator>
268 basic_quick_string& replace(iterator i1, iterator i2, InputIterator j1, InputIterator j2) { get_string().replace(i1, i2, j1, j2); return *this; }
269 size_type copy(charT* s, size_type n, size_type pos = 0) const
270 {
271 if (is_view())
272 return get_view_string().copy(s, n, pos);
273 else
274 return get_string().copy(s, n, pos);
275 }
277 {
278 std::swap(iContents, str.iContents);
279 }
280 // string_type operations:
281 const charT* c_str() const // explicit
282 {
283 return get_string().c_str();
284 }
285 const charT* data() const
286 {
287 if (is_view())
288 return get_view_string().data();
289 else
290 return get_string().data();
291 }
293 {
294 if (is_view())
295 return std::get<view_contents_type>(iContents).second;
296 else
297 return get_string().get_allocator();
298 }
299 size_type find(const basic_quick_string& str, size_type pos = 0) const
300 {
301 if (is_view())
302 return get_view_string().find(str.to_std_string_view(), pos);
303 else
304 return get_string().find(str.to_std_string_view(), pos);
305 }
306 size_type find(const string_type& str, size_type pos = 0) const
307 {
308 if (is_view())
309 return get_view_string().find(str, pos);
310 else
311 return get_string().find(str, pos);
312 }
313 size_type find(const charT* s, size_type pos, size_type n) const
314 {
315 if (is_view())
316 return get_view_string().find(s, pos, n);
317 else
318 return get_string().find(s, pos, n);
319 }
320 size_type find(const charT* s, size_type pos = 0) const
321 {
322 if (is_view())
323 return get_view_string().find(s, pos);
324 else
325 return get_string().find(s, pos);
326 }
327 size_type find(charT c, size_type pos = 0) const
328 {
329 if (is_view())
330 return get_view_string().find(c, pos);
331 else
332 return get_string().find(c, pos);
333 }
335 {
336 if (is_view())
337 return get_view_string().rfind(str.to_std_string_view(), pos);
338 else
339 return get_string().rfind(str.to_std_string_view(), pos);
340 }
341 size_type rfind(const string_type& str, size_type pos = npos) const
342 {
343 if (is_view())
344 return get_view_string().rfind(str, pos);
345 else
346 return get_string().rfind(str, pos);
347 }
348 size_type rfind(const charT* s, size_type pos, size_type n) const
349 {
350 if (is_view())
351 return get_view_string().rfind(s, pos, n);
352 else
353 return get_string().rfind(s, pos, n);
354 }
355 size_type rfind(const charT* s, size_type pos = npos) const
356 {
357 if (is_view())
358 return get_view_string().rfind(s, pos);
359 else
360 return get_string().rfind(s, pos);
361 }
362 size_type rfind(charT c, size_type pos = npos) const
363 {
364 if (is_view())
365 return get_view_string().rfind(c, pos);
366 else
367 return get_string().rfind(c, pos);
368 }
370 {
371 if (is_view())
372 return get_view_string().find_first_of(str.to_std_string_view(), pos);
373 else
374 return get_string().find_first_of(str.to_std_string_view(), pos);
375 }
376 size_type find_first_of(const string_type& str, size_type pos = 0) const
377 {
378 if (is_view())
379 return get_view_string().find_first_of(str, pos);
380 else
381 return get_string().find_first_of(str, pos);
382 }
383 size_type find_first_of(const charT* s, size_type pos, size_type n) const
384 {
385 if (is_view())
386 return get_view_string().find_first_of(s, pos, n);
387 else
388 return get_string().find_first_of(s, pos, n);
389 }
390 size_type find_first_of(const charT* s, size_type pos = 0) const
391 {
392 if (is_view())
393 return get_view_string().find_first_of(s, pos);
394 else
395 return get_string().find_first_of(s, pos);
396 }
397 size_type find_first_of(charT c, size_type pos = 0) const
398 {
399 if (is_view())
400 return get_view_string().find_first_of(c, pos);
401 else
402 return get_string().find_first_of(c, pos);
403 }
405 {
406 if (is_view())
407 return get_view_string().find_last_of(str.to_std_string_view(), pos);
408 else
409 return get_string().find_last_of(str.to_std_string_view(), pos);
410 }
412 {
413 if (is_view())
414 return get_view_string().find_last_of(str, pos);
415 else
416 return get_string().find_last_of(str, pos);
417 }
418 size_type find_last_of(const charT* s, size_type pos, size_type n) const
419 {
420 if (is_view())
421 return get_view_string().find_last_of(s, pos, n);
422 else
423 return get_string().find_last_of(s, pos, n);
424 }
425 size_type find_last_of(const charT* s, size_type pos = npos) const
426 {
427 if (is_view())
428 return get_view_string().find_last_of(s, pos);
429 else
430 return get_string().find_last_of(s, pos);
431 }
432 size_type find_last_of(charT c, size_type pos = npos) const
433 {
434 if (is_view())
435 return get_view_string().find_last_of(c, pos);
436 else
437 return get_string().find_last_of(c, pos);
438 }
440 {
441 if (is_view())
442 return get_view_string().find_first_not_of(str.to_std_string_view(), pos);
443 else
444 return get_string().find_first_not_of(str.to_std_string_view(), pos);
445 }
447 {
448 if (is_view())
449 return get_view_string().find_first_not_of(str, pos);
450 else
451 return get_string().find_first_not_of(str, pos);
452 }
453 size_type find_first_not_of(const charT* s, size_type pos, size_type n) const
454 {
455 if (is_view())
456 return get_view_string().find_first_not_of(s, pos, n);
457 else
458 return get_string().find_first_not_of(s, pos, n);
459 }
460 size_type find_first_not_of(const charT* s, size_type pos = 0) const
461 {
462 if (is_view())
463 return get_view_string().find_first_not_of(s, pos);
464 else
465 return get_string().find_first_not_of(s, pos);
466 }
467 size_type find_first_not_of(charT c, size_type pos = 0) const
468 {
469 if (is_view())
470 return get_view_string().find_first_not_of(c, pos);
471 else
472 return get_string().find_first_not_of(c, pos);
473 }
475 {
476 if (is_view())
477 return get_view_string().find_last_of(str.to_std_string_view(), pos);
478 else
479 return get_string().find_last_of(str.to_std_string_view(), pos);
480 }
482 {
483 if (is_view())
484 return get_view_string().find_last_of(str, pos);
485 else
486 return get_string().find_last_of(str, pos);
487 }
488 size_type find_last_not_of(const charT* s, size_type pos, size_type n) const
489 {
490 if (is_view())
491 return get_view_string().find_last_of(s, pos, n);
492 else
493 return get_string().find_last_of(s, pos, n);
494 }
495 size_type find_last_not_of(const charT* s, size_type pos = npos) const
496 {
497 if (is_view())
498 return get_view_string().find_last_of(s, pos);
499 else
500 return get_string().find_last_of(s, pos);
501 }
503 {
504 if (is_view())
505 return get_view_string().find_last_of(c, pos);
506 else
507 return get_string().find_last_of(c, pos);
508 }
510 {
511 if (is_view())
512 return string_type{ get_view_string().substr(pos, n) };
513 else
514 return get_string().substr(pos, n);
515 }
516 int compare(const basic_quick_string& str) const
517 {
518 if (is_view())
519 return get_view_string().compare(str.to_std_string_view());
520 else
521 return to_std_string_view().compare(str.to_std_string_view());
522 }
523 int compare(const string_type& str) const
524 {
525 if (is_view())
526 return get_view_string().compare(str);
527 else
528 return get_string().compare(str);
529 }
530 int compare(size_type pos1, size_type n1, const string_type& str) const
531 {
532 return basic_quick_string(*this, pos1, n1).compare(str);
533 }
534 int compare(size_type pos1, size_type n1, const string_type& str, size_type pos2, size_type n2) const
535 {
536 return basic_quick_string(*this, pos1, n1).compare(basic_quick_string(basic_quick_string(str.begin(), str.end()), pos2, n2));
537 }
538 int compare(const charT* s) const
539 {
540 return compare(basic_quick_string(s));
541 }
542 int compare(size_type pos1, size_type n1, const charT* s) const
543 {
544 return basic_quick_string(*this, pos1, n1).compare(basic_quick_string(s));
545 }
546 int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const
547 {
548 return basic_quick_string(*this, pos1, n1).compare(basic_quick_string(s, n2));
549 }
550 public:
551 bool operator==(const basic_quick_string& that) const
552 {
553 return size() == that.size() && std::equal(begin(), end(), that.begin(), that.end());
554 }
555 std::strong_ordering operator<=>(const basic_quick_string& that) const
556 {
557 return std::lexicographical_compare_three_way(begin(), end(), that.begin(), that.end());
558 }
559 // basic_quick_string specific operations
560 public:
561 bool is_view() const
562 {
563 return std::holds_alternative<view_contents_type>(iContents);
564 }
566 {
567 return static_cast<string_view_type>(*this);
568 }
570 {
571 return static_cast<string_type>(*this);
572 }
573 public:
574 operator string_type() const
575 {
576 if (is_view())
577 return string_type{ get_view_string().begin(), get_view_string().end(), get_allocator() };
578 else
579 return get_string();
580 }
581 operator string_type&()
582 {
583 return get_string();
584 }
585 operator string_view_type() const
586 {
587 if (is_view())
588 return get_view_string();
589 else
590 return string_view_type{ get_string() };
591 }
592 private:
593 const string_type& get_string() const
594 {
595 if (is_view())
596 iContents = string_type{ get_view_string().begin(), get_view_string().end(), get_allocator() };
597 return std::get<string_type>(iContents);
598 }
599 string_type& get_string()
600 {
601 return const_cast<string_type&>(to_const(*this).get_string());
602 }
603 const string_view_type& get_view_string() const
604 {
605 if (is_view())
606 return std::get<view_contents_type>(iContents).first;
607 throw not_view_string();
608 }
609 string_view_type& get_view_string()
610 {
611 return const_cast<string_view_type&>(to_const(*this).get_view_string());
612 }
613 private:
614 mutable contents_type iContents;
615 };
616
617 template <typename charT, typename Traits, typename Alloc>
618 const typename basic_quick_string<charT, Traits, Alloc>::size_type basic_quick_string<charT, Traits, Alloc>::npos = basic_quick_string<charT, Traits, Alloc>::string_type::npos;
619
620 template<class charT,
621 class Traits,
622 class Alloc> inline
626 { // return basic_quick_string + basic_quick_string
627 return (basic_quick_string<charT, Traits, Alloc>(_Left) += _Right);
628 }
629
630 template<class charT,
631 class Traits,
632 class Alloc> inline
633 std::basic_string<charT, Traits, Alloc> operator+(
634 const std::basic_string<charT, Traits, Alloc>& _Left,
636 { // return NTCS + basic_quick_string
637 return _Left + static_cast<std::basic_string<charT, Traits, Alloc>>(_Right);
638 }
639
640 template<class charT,
641 class Traits,
642 class Alloc> inline
643 std::basic_string<charT, Traits, Alloc> operator+(
644 const charT *_Left,
646 { // return NTCS + basic_quick_string
647 return _Left + static_cast<std::basic_string<charT, Traits, Alloc>>(_Right);
648 }
649
650 template<class charT,
651 class Traits,
652 class Alloc> inline
653 std::basic_string<charT, Traits, Alloc> operator+(
654 const charT _Left,
656 { // return character + basic_quick_string
657 return _Left + static_cast<std::basic_string<charT, Traits, Alloc>>(_Right);
658 }
659
660 template<class charT,
661 class Traits,
662 class Alloc> inline
663 std::basic_string<charT, Traits, Alloc> operator+(
665 const std::basic_string<charT, Traits, Alloc>& _Right)
666 { // return basic_quick_string + NTCS
667 return static_cast<std::basic_string<charT, Traits, Alloc>>(_Left) + _Right;
668 }
669
670 template<class charT,
671 class Traits,
672 class Alloc> inline
673 std::basic_string<charT, Traits, Alloc> operator+(
675 const charT *_Right)
676 { // return basic_quick_string + NTCS
677 return static_cast<std::basic_string<charT, Traits, Alloc>>(_Left) + _Right;
678 }
679
680 template<class charT,
681 class Traits,
682 class Alloc> inline
683 std::basic_string<charT, Traits, Alloc> operator+(
685 const charT _Right)
686 { // return basic_quick_string + character
687 return static_cast<std::basic_string<charT, Traits, Alloc>>(_Left) + _Right;
688 }
689
690 template <typename charT>
692 {
693 public:
694 basic_character_map(const std::basic_string<charT>& Characters) :
695 iMap()
696 {
697 for (typename std::basic_string<charT>::const_iterator i = Characters.begin(); i != Characters.end(); ++i)
698 iMap[static_cast<typename std::make_unsigned<charT>::type>(*i)] = true;
699 }
700 public:
701 bool find(charT Character) const
702 {
703 return iMap[static_cast<typename std::make_unsigned<charT>::type>(Character)];
704 }
705 private:
706 std::array<bool, 256> iMap;
707 };
708
709 template <>
710 class basic_character_map<wchar_t>
711 {
712 public:
713 basic_character_map(const std::basic_string<wchar_t>& Characters)
714 {
715 for (std::basic_string<wchar_t>::const_iterator i = Characters.begin(); i != Characters.end(); ++i)
716 iMap.insert(*i);
717 }
718 public:
719 bool find(wchar_t Character) const
720 {
721 return iMap.find(Character) != iMap.end();
722 }
723 private:
724 std::set<wchar_t> iMap;
725 };
726
727 template <typename Elem, typename Traits, typename Alloc>
728 inline std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& aStream, const basic_quick_string<Elem, Traits, Alloc>& aString)
729 {
730 aStream << std::basic_string<Elem, Traits>{ aString.data(), aString.size() };
731 return aStream;
732 }
733
735
736 template <typename charT, typename Traits, typename Alloc>
738 {
739 return neolib::fast_hash(&*sv.to_std_string_view().cbegin(), sv.size());
740 }
741}
bool find(wchar_t Character) const
basic_character_map(const std::basic_string< wchar_t > &Characters)
bool find(charT Character) const
basic_character_map(const std::basic_string< charT > &Characters)
int compare(const string_type &str) const
size_type find_last_not_of(const charT *s, size_type pos=npos) const
basic_quick_string & assign(const string_type &str, size_type pos, size_type n)
size_type find(charT c, size_type pos=0) const
basic_quick_string & append(const charT *s, size_type n)
size_type find(const string_type &str, size_type pos=0) const
size_type find_last_of(const charT *s, size_type pos, size_type n) const
size_type find_last_of(charT c, size_type pos=npos) const
view_const_reverse_iterator rend() const
basic_quick_string & assign(InputIterator first, InputIterator last)
basic_quick_string & replace(size_type pos, size_type n1, size_type n2, charT c)
basic_quick_string & append(const charT *s)
basic_quick_string(const basic_quick_string &str, const Alloc &a)
basic_quick_string & operator=(const basic_quick_string &str)
basic_quick_string(basic_quick_string &&str)
const charT * data() const
basic_quick_string & replace(size_type pos1, size_type n1, const basic_quick_string &str)
basic_quick_string(charT *begin, charT *end, const Alloc &a=Alloc())
basic_quick_string & assign(size_type n, charT c)
basic_quick_string(const basic_quick_string &str, size_type pos, size_type n=npos)
size_type find_last_of(const charT *s, size_type pos=npos) const
std::reverse_iterator< const_iterator > const_reverse_iterator
static const size_type npos
size_type find_first_of(const string_type &str, size_type pos=0) const
string_type::const_pointer const_pointer
std::basic_string_view< charT, Traits > string_view_type
size_type find_last_not_of(charT c, size_type pos=npos) const
iterator insert(const_iterator p, size_type n, charT c)
string_type::iterator iterator
basic_quick_string & insert(size_type pos1, const string_type &str)
const_reference back() const
basic_quick_string & append(const string_type &str)
basic_quick_string & replace(size_type pos1, size_type n1, const string_type &str, size_type pos2, size_type n2)
basic_quick_string & replace(iterator i1, iterator i2, const basic_quick_string &str)
basic_quick_string & insert(size_type pos, const charT *s)
size_type rfind(const charT *s, size_type pos=npos) const
basic_quick_string & assign(const charT *s)
basic_quick_string & append(const basic_quick_string &str)
string_type substr(size_type pos=0, size_type n=npos) const
int compare(size_type pos1, size_type n1, const charT *s, size_type n2) const
basic_quick_string & operator=(charT c)
basic_quick_string & append(InputIterator first, InputIterator last)
basic_quick_string & replace(size_type pos, size_type n1, const charT *s)
size_type find_first_of(const basic_quick_string &str, size_type pos=0) const
string_type::difference_type difference_type
const_reference operator[](size_type pos) const
iterator erase(iterator p)
basic_quick_string & operator+=(const basic_quick_string &str)
size_type find_last_not_of(const string_type &str, size_type pos=npos) const
basic_quick_string(size_type n, charT c, const Alloc &a=Alloc())
void swap(basic_quick_string &str)
basic_quick_string & replace(iterator i1, iterator i2, const string_type &str)
basic_quick_string & assign(const string_type &str)
view_const_iterator begin() const
basic_quick_string & operator+=(const charT *s)
void reserve(size_type res_arg=0)
std::reverse_iterator< iterator > reverse_iterator
size_type find_first_of(const charT *s, size_type pos, size_type n) const
size_type find_first_not_of(const string_type &str, size_type pos=0) const
reference at(size_type n)
basic_quick_string & operator+=(const string_type &str)
size_type rfind(const charT *s, size_type pos, size_type n) const
view_const_reverse_iterator crend() const
string_type::value_type value_type
basic_quick_string & erase(size_type pos=0, size_type n=npos)
basic_quick_string & replace(iterator i1, iterator i2, const charT *s)
string_type::const_iterator const_iterator
view_const_iterator cend() const
string_view_type::const_iterator view_const_iterator
int compare(size_type pos1, size_type n1, const string_type &str) const
const charT * c_str() const
basic_quick_string & append(const basic_quick_string &str, size_type pos, size_type n)
size_type rfind(const basic_quick_string &str, size_type pos=npos) const
string_view_type to_std_string_view() const
string_view_type::const_pointer view_const_pointer
int compare(size_type pos1, size_type n1, const string_type &str, size_type pos2, size_type n2) const
basic_quick_string & replace(iterator i1, iterator i2, const charT *s, size_type n)
string_type::const_reference const_reference
size_type copy(charT *s, size_type n, size_type pos=0) const
iterator insert(const_iterator p, InputIterator first, InputIterator last)
allocator_type get_allocator() const
std::reverse_iterator< view_const_iterator > view_const_reverse_iterator
size_type find_first_of(const charT *s, size_type pos=0) const
size_type find_last_of(const basic_quick_string &str, size_type pos=npos) const
size_type find_last_not_of(const charT *s, size_type pos, size_type n) const
basic_quick_string & operator+=(charT c)
size_type find_first_not_of(const basic_quick_string &str, size_type pos=0) const
basic_quick_string(InputIterator begin, InputIterator end, const Alloc &a=Alloc())
view_const_reverse_iterator crbegin() const
string_type::pointer pointer
iterator erase(iterator first, iterator last)
string_type::size_type size_type
size_type find(const charT *s, size_type pos, size_type n) const
string_view_type::const_reference view_const_reference
basic_quick_string & replace(iterator i1, iterator i2, InputIterator j1, InputIterator j2)
view_const_iterator end() const
basic_quick_string & replace(size_type pos1, size_type n1, const string_type &str)
basic_quick_string & replace(size_type pos1, size_type n1, const basic_quick_string &str, size_type pos2, size_type n2)
basic_quick_string & operator=(const charT *s)
basic_quick_string & insert(size_type pos1, const basic_quick_string &str, size_type pos2, size_type n)
basic_quick_string(const Alloc &a=Alloc())
basic_quick_string & assign(const charT *s, size_type n)
basic_quick_string & append(size_type n, charT c)
view_const_iterator cbegin() const
string_type::traits_type traits_type
basic_quick_string(view_const_iterator begin, view_const_iterator end, const Alloc &a=Alloc())
basic_quick_string & insert(size_type pos1, const string_type &str, size_type pos2, size_type n)
size_type find_last_of(const string_type &str, size_type pos=npos) const
size_type rfind(const string_type &str, size_type pos=npos) const
bool operator==(const basic_quick_string &that) const
int compare(const basic_quick_string &str) const
size_type rfind(charT c, size_type pos=npos) const
std::strong_ordering operator<=>(const basic_quick_string &that) const
basic_quick_string & insert(size_type pos1, const basic_quick_string &str)
basic_quick_string(const charT *begin, const charT *end, const Alloc &a=Alloc(), typename std::enable_if<!std::is_same< view_const_iterator, const charT * >::value, SFINAE >::type=0)
basic_quick_string(const charT *s, size_type n, const Alloc &a=Alloc())
string_type::reference reference
size_type find_first_not_of(charT c, size_type pos=0) const
basic_quick_string(const basic_quick_string &str)
basic_quick_string & insert(size_type pos, size_type n, charT c)
basic_quick_string & assign(const basic_quick_string &str, size_type pos, size_type n)
size_type find_first_not_of(const charT *s, size_type pos=0) const
string_type::allocator_type allocator_type
basic_quick_string & append(const string_type &str, size_type pos, size_type n)
reference operator[](size_type pos)
size_type find_last_not_of(const basic_quick_string &str, size_type pos=npos) const
int compare(const charT *s) const
basic_quick_string & replace(size_type pos, size_type n1, const charT *s, size_type n2)
basic_quick_string & insert(size_type pos, const charT *s, size_type n)
size_type find_first_not_of(const charT *s, size_type pos, size_type n) const
std::basic_string< charT, Traits, Alloc > string_type
size_type find_first_of(charT c, size_type pos=0) const
const_reference at(size_type n) const
size_type find(const charT *s, size_type pos=0) const
reverse_iterator rbegin()
basic_quick_string(const charT *s, const Alloc &a=Alloc())
basic_quick_string & replace(iterator i1, iterator i2, size_type n, charT c)
void resize(size_type n, charT c)
int compare(size_type pos1, size_type n1, const charT *s) const
iterator insert(const_iterator p, charT c)
basic_quick_string(const_iterator begin, const_iterator end, const Alloc &a=Alloc())
size_type find(const basic_quick_string &str, size_type pos=0) const
basic_quick_string & assign(const basic_quick_string &str)
view_const_reverse_iterator rbegin() const
string_type to_std_string() const
basic_quick_string(const string_type &str)
to_const_reference_t< T > to_const(T &&object)
Definition neolib.hpp:113
std::size_t hash_value(const neolib::basic_quick_string< charT, Traits, Alloc > &sv)
T fast_hash(const void *aInput, std::size_t aLength)
Definition fast_hash.hpp:79
bool holds_alternative(const lexer_atom< Token, Scope, CharT > &aAtom)
Definition lexer.hpp:213
basic_quick_string< char > quick_string
Definition plf_hive.h:79
void swap(plf::hive< element_type, allocator_type > &a, plf::hive< element_type, allocator_type > &b) noexcept(std::allocator_traits< allocator_type >::propagate_on_container_swap::value||std::allocator_traits< allocator_type >::is_always_equal::value)
Definition plf_hive.h:4776