19 #ifndef LIB_CS_STRING_H
20 #define LIB_CS_STRING_H
30 #include <type_traits>
34 #include <cs_string_iterator.h>
35 #include <cs_encoding.h>
37 #define UCHAR(x) (U ## x)
42 class CsBasicStringView;
44 using CsString = CsBasicString<utf8>;
45 using CsString_utf8 = CsBasicString<utf8>;
46 using CsString_utf16 = CsBasicString<utf16>;
48 template <
typename E,
typename A>
52 using difference_type = std::ptrdiff_t;
53 using size_type = std::ptrdiff_t;
54 using value_type = CsChar;
56 using const_iterator = CsStringIterator<E, A>;
57 using iterator = CsStringIterator<E, A>;
58 using const_reverse_iterator = CsStringReverseIterator<const_iterator>;
59 using reverse_iterator = CsStringReverseIterator<iterator>;
61 using const_storage_iterator =
typename std::vector<
typename E::storage_unit, A>::const_iterator;
62 using const_storage_reverse_iterator =
typename std::vector<
typename E::storage_unit, A>::const_reverse_iterator;
64 static constexpr const size_type npos = -1;
71 explicit CsBasicString(
const A &a)
77 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
78 std::is_same<T,
char *>::value>::type>
79 CsBasicString(
const T &str,
const A &a = A());
83 CsBasicString(
const char (&str)[N],
const A &a = A());
87 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
88 std::is_same<T,
char *>::value>::type>
89 CsBasicString(
const T &str, size_type size,
const A &a = A());
93 CsBasicString(
const char (&str)[N], size_type size,
const A &a = A());
96 CsBasicString(
const char16_t *str,
const A &a = A());
97 CsBasicString(
const char16_t *str, size_type size,
const A &a = A());
99 CsBasicString(
const char32_t *str,
const A &a = A());
100 CsBasicString(
const char32_t *str, size_type size,
const A &a = A());
104 CsBasicString(
const CsBasicString &str, size_type indexStart,
const A &a = A());
105 CsBasicString(
const CsBasicString &str, size_type indexStart, size_type size,
const A &a = A());
108 CsBasicString(size_type count, CsChar c,
const A &a = A());
113 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
114 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
115 CsBasicString(CsBasicStringView<U> str,
const A &a = A());
117 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
118 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
119 CsBasicString(CsBasicStringView<U> str, size_type indexStart, size_type size,
const A &a = A());
122 template <
typename Iterator>
123 CsBasicString(Iterator begin, Iterator end,
const A &a = A());
125 CsBasicString(const_iterator begin, const_iterator end,
const A &a = A());
128 CsBasicString(
const CsBasicString &str) =
default;
129 CsBasicString(
const CsBasicString &str,
const A &a);
132 CsBasicString(CsBasicString && str) =
default;
133 CsBasicString(CsBasicString && str,
const A &a);
136 #if defined(__cpp_char8_t
)
139 CsBasicString(
const char8_t *str,
const A &a = A());
140 CsBasicString(
const char8_t *str, size_type size,
const A &a = A());
142 static CsBasicString fromUtf8(
const char8_t *str, size_type numOfChars = -1,
const A &a = A());
147 CsBasicString &operator=(
const CsBasicString &str) =
default;
148 CsBasicString &operator=(CsBasicString &&str) =
default;
153 CsBasicString &operator=(CsChar c);
156 template <
typename T>
157 CsBasicString &operator=(
const T &str);
162 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
163 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
164 CsBasicString &operator=(CsBasicStringView<U> str);
166 CsBasicString &operator+=(
const CsBasicString &str);
171 CsBasicString &operator+=(CsChar c);
174 template <
typename T>
175 CsBasicString &operator+=(
const T &str);
180 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
181 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
182 CsBasicString &operator+=(CsBasicStringView<U> str);
184 CsChar operator[](size_type index)
const;
186 const_iterator advance(const_iterator begin, size_type count)
const;
187 iterator advance(iterator begin, size_type count);
190 CsBasicString &append(
const CsBasicString &str);
191 CsBasicString &append(
const CsBasicString &str, size_type indexStart, size_type size = npos);
193 CsBasicString &append(CsChar c);
194 CsBasicString &append(size_type count, CsChar c);
196 template <
typename Iterator>
197 CsBasicString &append(Iterator begin, Iterator end);
199 CsBasicString &append(const_iterator begin, const_iterator end);
203 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
204 std::is_same<T,
char *>::value>::type>
205 CsBasicString &append(
const T &str, size_type size);
209 CsBasicString &append(
const char (&str)[N], size_type size);
213 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
214 std::is_same<T,
char *>::value>::type>
215 CsBasicString &append(
const T &str);
220 CsBasicString &append(
const char (&str)[N]);
225 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
226 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
227 CsBasicString &append(CsBasicStringView<U> str);
229 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
230 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
231 CsBasicString &append(CsBasicStringView<U> str, size_type indexStart, size_type size);
233 CsBasicString &assign(size_type count, CsChar c);
234 CsBasicString &assign(
const CsBasicString &str);
235 CsBasicString &assign(
const CsBasicString &str, size_type indexStart, size_type size = npos);
236 CsBasicString &assign(CsBasicString &&str);
239 template <
typename T>
240 CsBasicString &assign(
const T &str, size_type size);
243 template <
typename T>
244 CsBasicString &assign(
const T &str);
246 template <
typename Iterator>
247 CsBasicString &assign(Iterator begin, Iterator end);
252 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
253 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
254 CsBasicString &assign(CsBasicStringView<U> str);
256 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
257 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
258 CsBasicString &assign(CsBasicStringView<U> str, size_type indexStart, size_type size);
260 CsChar at(size_type index)
const;
266 CsBasicString &erase(size_type indexStart = 0, size_type size = npos);
267 iterator erase(const_iterator iter);
268 iterator erase(const_iterator iter_begin, const_iterator iter_end);
271 const_iterator find_fast(CsChar c)
const;
272 const_iterator find_fast(CsChar c, const_iterator iter_begin)
const;
274 const_iterator find_fast(
const CsBasicString &str)
const;
275 const_iterator find_fast(
const CsBasicString &str, const_iterator iter_begin)
const;
278 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
279 std::is_same<T,
char *>::value>::type>
280 const_iterator find_fast(
const T &str, const_iterator iter_begin, size_type size)
const;
284 const_iterator find_fast(
const char (&str)[N], const_iterator iter_begin, size_type size)
const;
287 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
288 std::is_same<T,
char *>::value>::type>
289 const_iterator find_fast(
const T &str)
const;
292 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
293 std::is_same<T,
char *>::value>::type>
294 const_iterator find_fast(
const T &str, const_iterator iter_begin)
const;
298 const_iterator find_fast(
const char (&str)[N])
const;
302 const_iterator find_fast(
const char (&str)[N], const_iterator iter_begin)
const;
305 const_iterator rfind_fast(CsChar c)
const;
306 const_iterator rfind_fast(CsChar c, const_iterator iter_end)
const;
308 const_iterator rfind_fast(
const CsBasicString &str)
const;
309 const_iterator rfind_fast(
const CsBasicString &str, const_iterator iter_end)
const;
312 size_type find(
const CsBasicString &str, size_type indexStart = 0)
const;
315 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
316 std::is_same<T,
char *>::value>::type>
317 size_type find(
const T &str, size_type indexStart, size_type size)
const;
321 size_type find(
const char (&str)[N], size_type indexStart, size_type size)
const;
324 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
325 std::is_same<T,
char *>::value>::type>
326 size_type find(
const T &str, size_type indexStart = 0)
const;
330 size_type find(
const char (&str)[N], size_type indexStart = 0)
const;
332 size_type find(CsChar c, size_type indexStart = 0)
const;
339 size_type find_first_of(
const CsBasicString &str, size_type indexStart = 0)
const;
342 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
343 std::is_same<T,
char *>::value>::type>
344 size_type find_first_of(
const T &str, size_type indexStart, size_type size)
const;
348 size_type find_first_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
351 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
352 std::is_same<T,
char *>::value>::type>
353 size_type find_first_of(
const T &str, size_type indexStart = 0)
const;
357 size_type find_first_of(
const char (&str)[N], size_type indexStart = 0)
const;
359 size_type find_first_of(CsChar c, size_type indexStart = 0)
const;
366 size_type find_last_of(
const CsBasicString &str, size_type indexStart = npos)
const;
369 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
370 std::is_same<T,
char *>::value>::type>
371 size_type find_last_of(
const T &str, size_type indexStart, size_type size)
const;
375 size_type find_last_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
378 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
379 std::is_same<T,
char *>::value>::type>
380 size_type find_last_of(
const T &str, size_type indexStart = npos)
const;
384 size_type find_last_of(
const char (&str)[N], size_type indexStart = npos)
const;
386 size_type find_last_of(CsChar c, size_type indexStart = npos)
const;
393 size_type find_first_not_of(
const CsBasicString &str, size_type indexStart = 0)
const;
396 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
397 std::is_same<T,
char *>::value>::type>
398 size_type find_first_not_of(
const T &str, size_type indexStart, size_type size)
const;
402 size_type find_first_not_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
405 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
406 std::is_same<T,
char *>::value>::type>
407 size_type find_first_not_of(
const T &strc, size_type indexStart = 0)
const;
411 size_type find_first_not_of(
const char (&str)[N], size_type indexStart = 0)
const;
413 size_type find_first_not_of(CsChar c, size_type indexStart= 0)
const;
420 size_type find_last_not_of(
const CsBasicString &str, size_type indexStart = npos)
const;
423 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
424 std::is_same<T,
char *>::value>::type>
425 size_type find_last_not_of(
const T &str, size_type indexStart, size_type size)
const;
429 size_type find_last_not_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
432 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
433 std::is_same<T,
char *>::value>::type>
434 size_type find_last_not_of(
const T &str, size_type indexStart = npos)
const;
438 size_type find_last_not_of(
const char (&str)[N], size_type indexStart = npos)
const;
440 size_type find_last_not_of(CsChar c, size_type indexStart = npos)
const;
447 size_type rfind(
const CsBasicString &str, size_type indexStart = npos)
const;
450 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
451 std::is_same<T,
char *>::value>::type>
452 size_type rfind(
const T &str, size_type indexStart, size_type size)
const;
456 size_type rfind(
const char (&str)[N], size_type indexStart, size_type size)
const;
459 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
460 std::is_same<T,
char *>::value>::type>
461 size_type rfind(
const T &str, size_type indexStart = npos)
const;
465 size_type rfind(
const char (&str)[N], size_type indexStart = npos)
const;
467 size_type rfind(CsChar c, size_type indexStart = npos)
const;
473 CsChar front()
const;
475 static CsBasicString fromUtf8(
const char *str, size_type numOfChars = -1,
const A &a = A());
476 static CsBasicString fromUtf16(
const char16_t *str, size_type numOfChars = -1,
const A &a = A());
478 A getAllocator()
const;
480 CsBasicString &insert(size_type indexStart, size_type count, CsChar c);
483 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
484 std::is_same<T,
char *>::value>::type>
485 CsBasicString &insert(size_type indexStart,
const T &str);
489 CsBasicString &insert(size_type indexStart,
const char (&str)[N]);
492 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
493 std::is_same<T,
char *>::value>::type>
494 CsBasicString &insert(size_type indexStart,
const T &str, size_type size);
498 CsBasicString &insert(size_type indexStart,
const char (&str)[N], size_type size);
500 CsBasicString &insert(size_type indexStart,
const CsBasicString &str);
502 CsBasicString &insert(size_type indexStart,
const CsBasicString &str,
503 size_type srcStart, size_type size = npos);
505 iterator insert(const_iterator posStart, CsChar c);
506 iterator insert(const_iterator posStart, size_type count, CsChar c);
507 iterator insert(const_iterator posStart,
const CsBasicString &str);
510 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
511 std::is_same<T,
char *>::value>::type>
512 iterator insert(const_iterator posStart,
const T &str, size_type size);
516 iterator insert(const_iterator posStart,
const char (&str)[N], size_type size);
518 template <
typename Iterator>
519 iterator insert(const_iterator posStart, Iterator begin, Iterator end);
524 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
525 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
526 iterator insert(size_type indexStart, CsBasicStringView<U> str);
528 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
529 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
530 iterator insert(size_type indexStart, CsBasicStringView<U> str, size_type srcStart, size_type size = npos);
533 void push_back(CsChar c);
535 CsBasicString &replace(size_type indexStart, size_type size,
const CsBasicString &str);
536 CsBasicString &replace(const_iterator first, const_iterator last,
const CsBasicString &str);
538 CsBasicString &replace(size_type indexStart, size_type count,
const CsBasicString &str,
539 size_type srcStart, size_type size = npos);
541 template <
class Iterator>
542 CsBasicString &replace(const_iterator first1, const_iterator last1, Iterator first2, Iterator last2);
545 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
546 std::is_same<T,
char *>::value>::type>
547 CsBasicString &replace(size_type indexStart, size_type count,
const T &str, size_type size);
551 CsBasicString &replace(size_type indexStart, size_type count,
const char (&str)[N], size_type size);
554 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
555 std::is_same<T,
char *>::value>::type>
556 CsBasicString &replace(const_iterator first, const_iterator last,
const T &str, size_type size);
560 CsBasicString &replace(const_iterator first, const_iterator last,
const char (&str)[N], size_type size);
563 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
564 std::is_same<T,
char *>::value>::type>
565 CsBasicString &replace(size_type indexStart, size_type size,
const T &str);
569 CsBasicString &replace(size_type indexStart, size_type size,
const char (&str)[N]);
572 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
573 std::is_same<T,
char *>::value>::type>
574 CsBasicString &replace(const_iterator first, const_iterator last,
const T &str);
578 CsBasicString &replace(const_iterator first, const_iterator last,
const char (&str)[N]);
580 CsBasicString &replace(size_type indexStart, size_type size, size_type count, CsChar c);
581 CsBasicString &replace(const_iterator first, const_iterator last, size_type count, CsChar c);
595 CsBasicString &replace(size_type indexStart, size_type count,
const T &str,
596 size_type srcStart, size_type size = npos);
599 CsBasicString &replace(const_iterator first, const_iterator last,
const T &str,
600 size_type srcStart, size_type size = npos);
602 iterator replace(const_iterator iter,
const CsBasicString &str);
604 void resize(size_type size);
605 void resize(size_type size, CsChar c);
607 void shrink_to_fit();
609 size_type size_storage()
const;
612 size_type size_codePoints()
const;
613 size_type size()
const;
614 size_type length()
const;
616 CsBasicString substr(size_type indexStart = 0, size_type size = npos)
const;
617 void swap(CsBasicString &str);
620 const_iterator begin()
const;
621 const_iterator cbegin()
const;
623 const_iterator end()
const;
624 const_iterator cend()
const;
626 const_reverse_iterator rbegin()
const;
627 const_reverse_iterator crbegin()
const;
629 const_reverse_iterator rend()
const;
630 const_reverse_iterator crend()
const;
633 const_storage_iterator storage_begin()
const;
634 const_storage_iterator storage_end()
const;
636 const_storage_reverse_iterator storage_rbegin()
const;
637 const_storage_reverse_iterator storage_rend()
const;
640 const typename E::storage_unit *constData()
const
646 using str_type =
typename std::vector<
typename E::storage_unit, A>;
647 using str_iter =
typename std::vector<
typename E::storage_unit, A>::const_iterator;
653 template <
typename E,
typename A>
654 CsBasicString<E, A>::CsBasicString(
const CsBasicString &str,
const A &a)
655 : m_string(str.m_string, a)
659 template <
typename E,
typename A>
660 CsBasicString<E, A>::CsBasicString(CsBasicString &&str,
const A &a)
661 : m_string(std::move(str.m_string), a)
665 template <
typename E,
typename A>
666 template <
typename T,
typename>
667 CsBasicString<E, A>::CsBasicString(
const T &str,
const A &a)
669 #ifndef CS_STRING_ALLOW_UNSAFE
670 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
674 *
this = CsBasicString::fromUtf8(str, -1, a);
677 template <
typename E,
typename A>
679 CsBasicString<E, A>::CsBasicString(
const char (&str)[N],
const A &a)
681 #if defined(Q_CC_MSVC)
682 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
686 *
this = CsBasicString::fromUtf8(str, N-1, a);
689 template <
typename E,
typename A>
690 template <
typename T,
typename>
691 CsBasicString<E, A>::CsBasicString(
const T &str, size_type size,
const A &a)
693 #ifndef CS_STRING_ALLOW_UNSAFE
694 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
698 *
this = CsBasicString::fromUtf8(str, size, a);
701 template <
typename E,
typename A>
703 CsBasicString<E, A>::CsBasicString(
const char (&str)[N], size_type size,
const A &a)
705 #if defined(Q_CC_MSVC)
706 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
710 *
this = CsBasicString::fromUtf8(str, size, a);
713 template <
typename E,
typename A>
714 CsBasicString<E, A>::CsBasicString(
const char16_t *str,
const A &a)
716 *
this = CsBasicString::fromUtf16(str, -1, a);
719 template <
typename E,
typename A>
720 CsBasicString<E, A>::CsBasicString(
const char16_t *str, size_type size,
const A &a)
722 *
this = CsBasicString::fromUtf16(str, size, a);
725 template <
typename E,
typename A>
726 CsBasicString<E, A>::CsBasicString(
const char32_t *str,
const A &a)
729 const char32_t *c = str;
732 E::insert(m_string, m_string.end() - 1, *c);
737 template <
typename E,
typename A>
738 CsBasicString<E, A>::CsBasicString(
const char32_t *str, size_type size,
const A &a)
741 const char32_t *c = str;
755 E::insert(m_string, m_string.end() - 1, *c);
760 template <
typename E,
typename A>
761 CsBasicString<E, A>::CsBasicString(
const CsBasicString &str, size_type indexStart,
const A &a)
764 const_iterator iter_begin = str.cbegin();
765 const_iterator iter_end = str.cend();
767 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
771 if (iter_begin == str.cend()) {
776 append(iter_begin, iter_end);
779 template <
typename E,
typename A>
780 CsBasicString<E, A>::CsBasicString(
const CsBasicString &str, size_type indexStart, size_type size,
const A &a)
783 const_iterator iter_begin = str.cbegin();
784 const_iterator iter_end;
786 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
790 if (iter_begin == str.cend()) {
796 iter_end = iter_begin;
798 for (size_type i = 0; i < size && iter_end != str.cend(); ++i) {
803 iter_end = str.cend();
807 append(iter_begin, iter_end);
810 template <
typename E,
typename A>
811 CsBasicString<E, A>::CsBasicString(size_type count, CsChar c,
const A &a)
814 E::insert(m_string, m_string.end() - 1, c, count);
817 template <
typename E,
typename A>
818 template <
typename U,
typename>
819 CsBasicString<E, A>::CsBasicString(CsBasicStringView<U> str,
const A &a)
820 : CsBasicString(str.begin(), str.end(), a)
822 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
823 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
824 "incompatible with the encoding for U");
827 template <
typename E,
typename A>
828 template <
typename U,
typename>
829 CsBasicString<E, A>::CsBasicString(CsBasicStringView<U> str, size_type indexStart, size_type size,
const A &a)
832 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
833 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
834 "incompatible with the encoding for U");
836 typename U::const_iterator iter_begin = str.cbegin();
837 typename U::const_iterator iter_end;
839 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
843 if (iter_begin == str.cend()) {
849 iter_end = iter_begin;
851 for (size_type i = 0; i < size && iter_end != str.cend(); ++i) {
856 iter_end = str.cend();
860 append(iter_begin, iter_end);
863 template <
typename E,
typename A>
864 template <
typename Iterator>
865 CsBasicString<E, A>::CsBasicString(Iterator begin, Iterator end,
const A &a)
868 for (Iterator item = begin; item != end; ++item) {
869 E::insert(m_string, m_string.end() - 1, *item);
873 template <
typename E,
typename A>
874 CsBasicString<E, A>::CsBasicString(const_iterator begin, const_iterator end,
const A &a)
875 : m_string(begin.codePointBegin(), end.codePointBegin(), a)
877 m_string.push_back(0);
881 template <
typename E,
typename A>
882 CsBasicString<E, A> &CsBasicString<E, A>::operator=(CsChar c)
885 m_string.push_back(0);
891 template <
typename E,
typename A>
892 template <
typename T>
893 CsBasicString<E, A> &CsBasicString<E, A>::operator=(
const T &str)
898 m_string.push_back(0);
904 template <
typename E,
typename A>
905 template <
typename U,
typename>
906 CsBasicString<E, A> &CsBasicString<E,A>::operator=(CsBasicStringView<U> str)
908 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
909 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
910 "incompatible with the encoding for U");
913 m_string.push_back(0);
919 template <
typename E,
typename A>
920 CsBasicString<E, A> &CsBasicString<E, A>::operator+=(
const CsBasicString &str)
926 template <
typename E,
typename A>
927 CsBasicString<E, A> &CsBasicString<E, A>::operator+=(CsChar c)
933 template <
typename E,
typename A>
934 template <
typename T>
935 CsBasicString<E, A> &CsBasicString<E, A>::operator+=(
const T &str)
943 template <
typename E,
typename A>
944 template <
typename U,
typename>
945 CsBasicString<E, A> &CsBasicString<E,A>::operator+=(CsBasicStringView<U> str)
947 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
948 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
949 "incompatible with the encoding for U");
955 template <
typename E,
typename A>
956 CsChar CsBasicString<E, A>::operator[](size_type index)
const
958 const_iterator iter = begin();
959 std::advance(iter, index);
966 template <
typename E,
typename A>
967 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::advance(const_iterator begin, size_type count)
const
969 return const_iterator(E::advance(begin.codePointBegin(), cend().codePointBegin(), count));
972 template <
typename E,
typename A>
973 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::advance(iterator begin, size_type count)
975 return iterator(E::advance(begin.codePointBegin(), end().codePointBegin(), count));
978 template <
typename E,
typename A>
979 CsBasicString<E, A> &CsBasicString<E, A>::append(
const CsBasicString &str)
985 template <
typename E,
typename A>
986 CsBasicString<E, A> &CsBasicString<E, A>::append(
const CsBasicString &str, size_type indexStart, size_type size)
988 size_type stringLen =
this->size();
989 insert(stringLen, str, indexStart, size);
994 template <
typename E,
typename A>
995 CsBasicString<E, A> &CsBasicString<E, A>::append(CsChar c)
997 E::insert(m_string, m_string.end() - 1, c);
1001 template <
typename E,
typename A>
1002 CsBasicString<E, A> &CsBasicString<E, A>::append(size_type count, CsChar c)
1004 E::insert(m_string, m_string.end() - 1, c, count);
1008 template <
typename E,
typename A>
1009 template <
typename Iterator>
1010 CsBasicString<E, A> &CsBasicString<E, A>::append(Iterator begin, Iterator end)
1012 for (Iterator item = begin; item != end; ++item) {
1013 E::insert(m_string, m_string.end() - 1, *item);
1019 template <
typename E,
typename A>
1020 CsBasicString<E, A> &CsBasicString<E, A>::append(const_iterator begin, const_iterator end)
1022 m_string.insert(m_string.end() - 1, begin.codePointBegin(), end.codePointBegin());
1027 template <
typename E,
typename A>
1028 template <
typename T,
typename>
1029 CsBasicString<E, A> &CsBasicString<E, A>::append(
const T &str, size_type size)
1031 #ifndef CS_STRING_ALLOW_UNSAFE
1032 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1036 if (str ==
nullptr) {
1041 this->append(CsBasicString::fromUtf8(str, size));
1046 template <
typename E,
typename A>
1048 CsBasicString<E, A> &CsBasicString<E, A>::append(
const char (&str)[N], size_type size)
1050 #if defined(Q_CC_MSVC)
1051 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1055 this->append(CsBasicString::fromUtf8(str, size));
1060 template <
typename E,
typename A>
1061 template <
typename T,
typename>
1062 CsBasicString<E, A> &CsBasicString<E, A>::append(
const T &str)
1064 #ifndef CS_STRING_ALLOW_UNSAFE
1065 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1069 if (str ==
nullptr) {
1074 this->append(CsBasicString::fromUtf8(str));
1079 template <
typename E,
typename A>
1081 CsBasicString<E, A> &CsBasicString<E, A>::append(
const char (&str)[N])
1083 #if defined(Q_CC_MSVC)
1084 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1088 this->append(CsBasicString::fromUtf8(str, N-1));
1093 template <
typename E,
typename A>
1094 template <
typename U,
typename>
1095 CsBasicString<E, A> &CsBasicString<E, A>::append(CsBasicStringView<U> str)
1097 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1098 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1099 "incompatible with the encoding for U");
1101 append(str.cbegin(), str.cend());
1105 template <
typename E,
typename A>
1106 template <
typename U,
typename>
1107 CsBasicString<E, A> &CsBasicString<E, A>::append(CsBasicStringView<U> str, size_type indexStart, size_type size)
1109 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1110 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1111 "incompatible with the encoding for U");
1113 typename U::const_iterator iter_begin = str.cbegin();
1114 typename U::const_iterator iter_end;
1116 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
1120 if (iter_begin == str.cend()) {
1125 iter_end = iter_begin;
1127 for (size_type i = 0; i < size && iter_end != str.cend(); ++i) {
1132 iter_end = str.cend();
1136 append(iter_begin, iter_end);
1140 template <
typename E,
typename A>
1141 CsBasicString<E, A> &CsBasicString<E, A>::assign(size_type count, CsChar c)
1149 template <
typename E,
typename A>
1150 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const CsBasicString &str)
1158 template <
typename E,
typename A>
1159 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const CsBasicString &str, size_type indexStart, size_type size)
1162 append(str, indexStart, size);
1167 template <
typename E,
typename A>
1168 CsBasicString<E, A> &CsBasicString<E, A>::assign(CsBasicString &&str)
1171 append(std::move(str));
1176 template <
typename E,
typename A>
1177 template <
typename T>
1178 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const T &str, size_type size)
1188 template <
typename E,
typename A>
1189 template <
typename T>
1190 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const T &str)
1200 template <
typename E,
typename A>
1201 template <
typename Iterator>
1202 CsBasicString<E, A> &CsBasicString<E, A>::assign(Iterator begin, Iterator end)
1210 template <
typename E,
typename A>
1211 template <
typename U,
typename>
1212 CsBasicString<E, A> &CsBasicString<E, A>::assign(CsBasicStringView<U> str)
1214 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1215 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1216 "incompatible with the encoding for U");
1219 append(str.cbegin(), str.cend());
1224 template <
typename E,
typename A>
1225 template <
typename U,
typename>
1226 CsBasicString<E, A> &CsBasicString<E, A>::assign(CsBasicStringView<U> str, size_type indexStart, size_type size)
1228 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1229 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1230 "incompatible with the encoding for U");
1233 append(str, indexStart, size);
1238 template <
typename E,
typename A>
1239 CsChar CsBasicString<E, A>::at(size_type index)
const
1241 const_iterator iter = begin();
1242 std::advance(iter, index);
1247 template <
typename E,
typename A>
1248 CsChar CsBasicString<E, A>::back()
const
1253 template <
typename E,
typename A>
1254 void CsBasicString<E, A>::clear()
1257 m_string.push_back(0);
1260 template <
typename E,
typename A>
1261 bool CsBasicString<E, A>::empty()
const
1263 return (m_string.size() == 1);
1266 template <
typename E,
typename A>
1267 CsBasicString<E, A> &CsBasicString<E, A>::erase(size_type indexStart, size_type size)
1269 const_iterator iter_begin = cbegin();
1270 const_iterator iter_end;
1272 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
1276 if (iter_begin == cend()) {
1281 iter_end = iter_begin;
1283 for (size_type i = 0; i < size && iter_end != cend(); ++i) {
1292 erase(iter_begin, iter_end);
1297 template <
typename E,
typename A>
1298 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::erase(const_iterator iter)
1300 auto [vbegin, vend] = iter.codePointRange();
1301 auto retval = m_string.erase(vbegin, vend);
1303 return const_iterator(retval);
1306 template <
typename E,
typename A>
1307 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::erase(const_iterator iter_begin, const_iterator iter_end)
1309 auto retval = m_string.erase(iter_begin.codePointBegin(), iter_end.codePointBegin());
1310 return const_iterator(retval);
1313 template <
typename E,
typename A>
1314 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const CsBasicString &str)
const
1316 return find_fast(str, begin());
1319 template <
typename E,
typename A>
1320 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const CsBasicString &str,
1321 const_iterator iter_begin)
const
1323 const_iterator iter_end = end();
1325 if (iter_begin == iter_end) {
1333 auto iter = iter_begin;
1336 while (iter != iter_end) {
1339 auto text_iter = iter + 1;
1340 auto pattern_iter = str.begin() + 1;
1342 while (text_iter != iter_end && pattern_iter != str.end()) {
1344 if (*text_iter == *pattern_iter) {
1354 if (pattern_iter == str.end()) {
1367 template <
typename E,
typename A>
1368 template <
typename T,
typename>
1369 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const T &str, const_iterator iter_begin,
1370 size_type size)
const
1372 #ifndef CS_STRING_ALLOW_UNSAFE
1373 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1376 const_iterator iter_end = cend();
1378 if (iter_begin == iter_end) {
1382 if (str ==
nullptr || str[0] ==
'\0') {
1387 return find_fast(CsBasicString::fromUtf8(str, size), iter_begin);
1391 template <
typename E,
typename A>
1393 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const char (&str)[N], const_iterator iter_begin,
1394 size_type size)
const
1396 #if defined(Q_CC_MSVC)
1397 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1401 return find_fast(CsBasicString::fromUtf8(str, size), iter_begin);
1405 template <
typename E,
typename A>
1406 template <
typename T,
typename>
1407 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const T &str)
const
1409 return find_fast(str, cbegin());
1413 template <
typename E,
typename A>
1414 template <
typename T,
typename>
1415 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const T &str, const_iterator iter_begin)
const
1417 #ifndef CS_STRING_ALLOW_UNSAFE
1418 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1421 const_iterator iter_end = cend();
1423 if (iter_begin == iter_end) {
1427 if (str ==
nullptr || str[0] ==
'\0') {
1432 return find_fast(CsBasicString::fromUtf8(str), iter_begin);
1436 template <
typename E,
typename A>
1438 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const char (&str)[N])
const
1440 return find_fast(str, cbegin());
1444 template <
typename E,
typename A>
1446 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const char (&str)[N], const_iterator iter_begin)
const
1448 #if defined(Q_CC_MSVC)
1449 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1453 return find_fast(CsBasicString::fromUtf8(str, N-1), iter_begin);
1456 template <
typename E,
typename A>
1457 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(CsChar c)
const
1459 return find_fast(c, begin());
1462 template <
typename E,
typename A>
1463 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(CsChar c, const_iterator iter_begin)
const
1465 const_iterator iter_end = end();
1467 if (iter_begin == iter_end) {
1471 auto iter = iter_begin;
1473 while (iter != iter_end) {
1485 template <
typename E,
typename A>
1486 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(CsChar c)
const
1488 return rfind_fast(c, end());
1491 template <
typename E,
typename A>
1492 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(CsChar c, const_iterator iter_end)
const
1494 const_iterator iter_begin = begin();
1496 if (iter_begin == iter_end) {
1500 auto iter = iter_end;
1502 while (iter != begin()) {
1514 template <
typename E,
typename A>
1515 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(
const CsBasicString &str)
const
1517 return rfind_fast(str, end());
1520 template <
typename E,
typename A>
1521 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(
const CsBasicString &str,
1522 const_iterator iter_end)
const
1524 const_iterator iter_begin = begin();
1526 if (iter_begin == iter_end) {
1534 auto iter = iter_end;
1535 auto str_end = str.end();
1538 while (iter != begin()) {
1543 auto text_iter = iter + 1;
1544 auto pattern_iter = str.begin() + 1;
1546 while (text_iter != end() && pattern_iter != str_end) {
1548 if (*text_iter == *pattern_iter) {
1558 if (pattern_iter == str_end) {
1569 template <
typename E,
typename A>
1570 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(CsChar c, size_type indexStart)
const
1572 const_iterator iter_begin = cbegin();
1574 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
1578 if (iter_begin == cend()) {
1583 size_type retval = indexStart;
1585 while (iter_begin != end()) {
1587 if (*iter_begin == c) {
1598 template <
typename E,
typename A>
1599 template <
typename T,
typename>
1600 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const T &str, size_type indexStart,
1601 size_type size)
const
1603 #ifndef CS_STRING_ALLOW_UNSAFE
1604 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1608 return find(CsBasicString::fromUtf8(str, size), indexStart);
1611 template <
typename E,
typename A>
1613 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const char (&str)[N], size_type indexStart,
1614 size_type size)
const
1616 #if defined(Q_CC_MSVC)
1617 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1621 return find(CsBasicString::fromUtf8(str, size), indexStart);
1624 template <
typename E,
typename A>
1625 template <
typename T,
typename>
1626 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const T &str, size_type indexStart)
const
1628 #ifndef CS_STRING_ALLOW_UNSAFE
1629 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1633 size_type stringLen =
this->size();
1635 if (str ==
nullptr || *str ==
'\0') {
1637 if (indexStart > stringLen) {
1644 if (indexStart >= stringLen) {
1649 return find(CsBasicString::fromUtf8(str), indexStart);
1652 template <
typename E,
typename A>
1654 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const char (&str)[N], size_type indexStart)
const
1656 #if defined(Q_CC_MSVC)
1657 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1661 return find(CsBasicString::fromUtf8(str, N-1), indexStart);
1664 template <
typename E,
typename A>
1665 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const CsBasicString &str, size_type indexStart)
const
1667 size_type stringLen =
this->size();
1671 if (indexStart > stringLen) {
1678 if (indexStart >= stringLen) {
1682 size_type retval = indexStart;
1683 auto iter = begin() + indexStart;
1686 while (iter != end()) {
1689 auto text_iter = iter + 1;
1690 auto pattern_iter = str.begin() + 1;
1692 while (text_iter != end() && pattern_iter != str.end()) {
1694 if (*text_iter == *pattern_iter) {
1704 if (pattern_iter == str.end()) {
1717 template <
typename E,
typename A>
1718 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(CsChar c, size_type indexStart)
const
1720 return find(c, indexStart);
1723 template <
typename E,
typename A>
1724 template <
typename T,
typename>
1725 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const T &str, size_type indexStart,
1726 size_type size)
const
1728 #ifndef CS_STRING_ALLOW_UNSAFE
1729 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1733 if (str ==
nullptr || *str ==
'\0' || indexStart >=
this->size()) {
1738 return find_first_of(CsBasicString::fromUtf8(str, size), indexStart);
1741 template <
typename E,
typename A>
1743 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const char (&str)[N], size_type indexStart,
1744 size_type size)
const
1746 #if defined(Q_CC_MSVC)
1747 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1751 return find_first_of(CsBasicString::fromUtf8(str, size), indexStart);
1754 template <
typename E,
typename A>
1755 template <
typename T,
typename>
1756 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const T &str, size_type indexStart)
const
1758 #ifndef CS_STRING_ALLOW_UNSAFE
1759 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1763 if (str ==
nullptr || *str ==
'\0' || indexStart >=
this->size()) {
1768 return find_first_of(CsBasicString::fromUtf8(str), indexStart);
1771 template <
typename E,
typename A>
1773 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const char (&str)[N],
1774 size_type indexStart)
const
1776 #if defined(Q_CC_MSVC)
1777 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1781 return find_first_of(CsBasicString::fromUtf8(str, N-1), indexStart);
1784 template <
typename E,
typename A>
1785 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const CsBasicString &str,
1786 size_type indexStart)
const
1788 if (str.empty() || indexStart >=
this->size()) {
1792 size_type retval = indexStart;
1793 auto iter = begin() + indexStart;
1795 while (iter != end()) {
1796 for (
auto c : str) {
1811 template <
typename E,
typename A>
1812 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(CsChar c, size_type indexStart)
const
1814 return rfind(c, indexStart);
1817 template <
typename E,
typename A>
1818 template <
typename T,
typename>
1819 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const T &str, size_type indexStart,
1820 size_type size)
const
1822 #ifndef CS_STRING_ALLOW_UNSAFE
1823 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1827 size_type stringLen =
this->size();
1829 if (str ==
nullptr || *str ==
'\0' || indexStart >= stringLen) {
1834 return find_last_of(CsBasicString::fromUtf8(str, size), indexStart);
1837 template <
typename E,
typename A>
1839 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const char (&str)[N],
1840 size_type indexStart, size_type size)
const
1842 #if defined(Q_CC_MSVC)
1843 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1847 return find_last_of(CsBasicString::fromUtf8(str, size), indexStart);
1850 template <
typename E,
typename A>
1851 template <
typename T,
typename>
1852 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const T &str, size_type indexStart)
const
1854 #ifndef CS_STRING_ALLOW_UNSAFE
1855 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1859 size_type stringLen =
this->size();
1861 if (str ==
nullptr || *str ==
'\0' || indexStart >= stringLen) {
1866 return find_last_of(CsBasicString::fromUtf8(str), indexStart);
1869 template <
typename E,
typename A>
1871 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const char (&str)[N],
1872 size_type indexStart)
const
1874 #if defined(Q_CC_MSVC)
1875 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1879 return find_last_of(CsBasicString::fromUtf8(str, N-1), indexStart);
1882 template <
typename E,
typename A>
1883 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const CsBasicString &str,
1884 size_type indexStart)
const
1886 size_type stringLen =
this->size();
1888 if (str.empty() || indexStart >= stringLen) {
1893 const_iterator iter;
1895 if (indexStart >= 0 && indexStart < stringLen) {
1896 retval = indexStart + 1;
1897 iter = begin() + indexStart + 1;
1905 while (iter != begin()) {
1909 for (CsChar c : str) {
1921 template <
typename E,
typename A>
1922 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(CsChar c, size_type indexStart)
const
1924 if (indexStart >=
this->size()) {
1928 size_type retval = indexStart;
1929 auto iter = begin() + indexStart;
1931 while (iter != end()) {
1944 template <
typename E,
typename A>
1945 template <
typename T,
typename>
1946 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const T &str,
1947 size_type indexStart, size_type size)
const
1949 #ifndef CS_STRING_ALLOW_UNSAFE
1950 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1954 size_type stringLen =
this->size();
1956 if (str ==
nullptr || *str ==
'\0') {
1958 if (indexStart >= stringLen) {
1965 if (indexStart >= stringLen) {
1970 return find_first_not_of(CsBasicString::fromUtf8(str, size), indexStart);
1973 template <
typename E,
typename A>
1975 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const char (&str)[N],
1976 size_type indexStart, size_type size)
const
1978 #if defined(Q_CC_MSVC)
1979 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1983 return find_first_not_of(CsBasicString::fromUtf8(str, size), indexStart);
1986 template <
typename E,
typename A>
1987 template <
typename T,
typename>
1988 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const T &str,
1989 size_type indexStart)
const
1991 #ifndef CS_STRING_ALLOW_UNSAFE
1992 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1996 size_type stringLen =
this->size();
1998 if (str ==
nullptr || *str ==
'\0') {
2000 if (indexStart >= stringLen) {
2007 if (indexStart >= stringLen) {
2012 return find_first_not_of(CsBasicString::fromUtf8(str), indexStart);
2015 template <
typename E,
typename A>
2017 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const char (&str)[N],
2018 size_type indexStart)
const
2020 #if defined(Q_CC_MSVC)
2021 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2025 return find_first_not_of(CsBasicString::fromUtf8(str, N-1), indexStart);
2028 template <
typename E,
typename A>
2029 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const CsBasicString &str,
2030 size_type indexStart)
const
2032 size_type stringLen =
this->size();
2036 if (indexStart >= stringLen) {
2043 if (indexStart >= stringLen) {
2047 size_type retval = indexStart;
2048 auto iter = begin() + indexStart;
2050 auto str_end = str.end();
2052 while (iter != end()) {
2053 const_iterator pattern_iter = str.begin();
2055 while (pattern_iter != str_end) {
2057 if (*iter == *pattern_iter) {
2065 if (pattern_iter == str_end) {
2077 template <
typename E,
typename A>
2078 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(CsChar c, size_type indexStart)
const
2080 size_type stringLen =
this->size();
2082 if (indexStart >= stringLen) {
2087 const_iterator iter;
2089 if (indexStart >= 0 && indexStart < stringLen) {
2090 retval = indexStart + 1;
2091 iter = begin() + indexStart + 1;
2099 while (iter != begin()) {
2111 template <
typename E,
typename A>
2112 template <
typename T,
typename>
2113 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const T &str, size_type indexStart,
2114 size_type size)
const
2116 #ifndef CS_STRING_ALLOW_UNSAFE
2117 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2121 size_type stringLen =
this->size();
2123 if (str ==
nullptr || *str ==
'\0') {
2125 if (indexStart > stringLen || indexStart == -1) {
2126 return stringLen - 1;
2133 return find_last_not_of(CsBasicString::fromUtf8(str, size), indexStart);
2136 template <
typename E,
typename A>
2138 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const char (&str)[N],
2139 size_type indexStart, size_type size)
const
2141 #if defined(Q_CC_MSVC)
2142 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2146 return find_last_not_of(CsBasicString::fromUtf8(str, size), indexStart);
2149 template <
typename E,
typename A>
2150 template <
typename T,
typename>
2151 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const T &str, size_type indexStart)
const
2153 #ifndef CS_STRING_ALLOW_UNSAFE
2154 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2158 size_type stringLen =
this->size();
2160 if (str ==
nullptr || *str ==
'\0') {
2162 if (indexStart > stringLen || indexStart == -1) {
2163 return stringLen - 1;
2170 return find_last_not_of(CsBasicString::fromUtf8(str), indexStart);
2173 template <
typename E,
typename A>
2175 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const char (&str)[N],
2176 size_type indexStart)
const
2178 #if defined(Q_CC_MSVC)
2179 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2183 return find_last_not_of(CsBasicString::fromUtf8(str, N-1), indexStart);
2186 template <
typename E,
typename A>
2187 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const CsBasicString &str,
2188 size_type indexStart)
const
2190 size_type stringLen =
this->size();
2194 if (indexStart > stringLen || indexStart == -1) {
2195 return stringLen - 1;
2202 const_iterator iter;
2204 if (indexStart >= 0 && indexStart < stringLen) {
2205 retval = indexStart + 1;
2206 iter = begin() + indexStart + 1;
2214 const_iterator str_end = str.end();
2216 while (iter != begin()) {
2220 const_iterator pattern_iter = str.begin();
2222 while (pattern_iter != str_end) {
2224 if (*iter == *pattern_iter) {
2232 if (pattern_iter == str_end) {
2241 template <
typename E,
typename A>
2242 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(CsChar c, size_type indexStart)
const
2244 size_type stringLen =
this->size();
2247 const_iterator iter;
2249 if (indexStart >= 0 && indexStart < stringLen) {
2250 retval = indexStart + 1;
2251 iter = begin() + indexStart + 1;
2259 while (iter != begin()) {
2271 template <
typename E,
typename A>
2272 template <
typename T,
typename>
2273 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const T &str, size_type indexStart,
2274 size_type size)
const
2276 #ifndef CS_STRING_ALLOW_UNSAFE
2277 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2281 size_type stringLen =
this->size();
2283 if (str ==
nullptr || *str ==
'\0') {
2285 if (indexStart > stringLen || indexStart == -1) {
2293 return rfind(CsBasicString::fromUtf8(str, size), indexStart);
2296 template <
typename E,
typename A>
2298 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const char (&str)[N],
2299 size_type indexStart, size_type size)
const
2301 #if defined(Q_CC_MSVC)
2302 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2306 return rfind(CsBasicString::fromUtf8(str, size), indexStart);
2309 template <
typename E,
typename A>
2310 template <
typename T,
typename>
2311 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const T &str, size_type indexStart)
const
2313 #ifndef CS_STRING_ALLOW_UNSAFE
2314 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2318 size_type stringLen =
this->size();
2320 if (str ==
nullptr || *str ==
'\0') {
2322 if (indexStart > stringLen || indexStart == -1) {
2330 return rfind(CsBasicString::fromUtf8(str), indexStart);
2333 template <
typename E,
typename A>
2335 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const char (&str)[N], size_type indexStart)
const
2337 #if defined(Q_CC_MSVC)
2338 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2342 return rfind(CsBasicString::fromUtf8(str, N-1), indexStart);
2345 template <
typename E,
typename A>
2346 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const CsBasicString &str, size_type indexStart)
const
2348 size_type stringLen =
this->size();
2352 if (indexStart > stringLen || indexStart == -1) {
2360 const_iterator iter;
2362 if (indexStart >= 0 && indexStart < stringLen) {
2363 retval = indexStart + 1;
2364 iter = begin() + indexStart + 1;
2372 const_iterator str_end = str.end();
2375 while (iter != begin()) {
2381 auto text_iter = iter + 1;
2382 auto pattern_iter = str.begin() + 1;
2384 while (text_iter != end() && pattern_iter != str_end) {
2386 if (*text_iter == *pattern_iter) {
2396 if (pattern_iter == str_end) {
2407 template <
typename E,
typename A>
2408 CsChar CsBasicString<E, A>::front()
const
2413 template <
typename E,
typename A>
2414 CsBasicString<E,A> CsBasicString<E, A>::fromUtf8(
const char *str, size_type numOfChars,
const A &a)
2416 CsBasicString retval(a);
2418 if (str ==
nullptr) {
2422 if (numOfChars < 0) {
2423 numOfChars = std::strlen(str);
2429 for (
int i = 0; i < numOfChars; ++i) {
2431 if ((str[i] & 0x80) == 0) {
2433 if (multi_size != 0) {
2436 retval.append(
UCHAR(
'\uFFFD'));
2439 retval.append(
static_cast<
char32_t>(str[i]));
2441 }
else if ((str[i] & 0xC0) == 0x80) {
2444 data = (data << 6) | (
static_cast<
char32_t>(str[i]) & 0x3F);
2446 if (multi_size == 2 && data >= 0x80 && data <= 0x7FF) {
2448 retval.append(data);
2450 }
else if (multi_size == 3 && data >= 0x800 && data <= 0xFFFF) {
2452 retval.append(data);
2454 }
else if (multi_size == 4 && data >= 0x10000 && data <= 0x10FFFF) {
2456 retval.append(data);
2460 }
else if ((str[i] & 0xE0) == 0xC0) {
2463 if (multi_size != 0) {
2465 retval.append(
UCHAR(
'\uFFFD'));
2469 data =
static_cast<
char32_t>(str[i]) & 0x1F;
2471 }
else if ((str[i] & 0xF0) == 0xE0) {
2474 if (multi_size != 0) {
2476 retval.append(
UCHAR(
'\uFFFD'));
2480 data =
static_cast<
char32_t>(str[i]) & 0x0F;
2482 }
else if ((str[i] & 0xF8) == 0xF0) {
2485 if (multi_size != 0) {
2487 retval.append(
UCHAR(
'\uFFFD'));
2491 data =
static_cast<
char32_t>(str[i]) & 0x07;
2496 if (multi_size != 0) {
2499 retval.append(
UCHAR(
'\uFFFD'));
2502 retval.append(
UCHAR(
'\uFFFD'));
2506 if (multi_size != 0) {
2508 retval.append(
UCHAR(
'\uFFFD'));
2514 #if defined(__cpp_char8_t
)
2517 template <
typename E,
typename A>
2518 CsBasicString<E,A> CsBasicString<E, A>::fromUtf8(
const char8_t *str, size_type numOfChars,
const A &a)
2520 CsBasicString retval(a);
2522 if (str ==
nullptr) {
2526 if (numOfChars < 0) {
2527 numOfChars = std::char_traits<
char8_t>::length(str);
2533 for (
int i = 0; i < numOfChars; ++i) {
2535 if ((str[i] & 0x80) == 0) {
2537 if (multi_size != 0) {
2540 retval.append(
UCHAR(
'\uFFFD'));
2543 retval.append(
static_cast<
char32_t>(str[i]));
2545 }
else if ((str[i] & 0xC0) == 0x80) {
2548 data = (data << 6) | (
static_cast<
char32_t>(str[i]) & 0x3F);
2550 if (multi_size == 2 && data >= 0x80 && data <= 0x7FF) {
2552 retval.append(data);
2554 }
else if (multi_size == 3 && data >= 0x800 && data <= 0xFFFF) {
2556 retval.append(data);
2558 }
else if (multi_size == 4 && data >= 0x10000 && data <= 0x10FFFF) {
2560 retval.append(data);
2564 }
else if ((str[i] & 0xE0) == 0xC0) {
2567 if (multi_size != 0) {
2569 retval.append(
UCHAR(
'\uFFFD'));
2573 data =
static_cast<
char32_t>(str[i]) & 0x1F;
2575 }
else if ((str[i] & 0xF0) == 0xE0) {
2578 if (multi_size != 0) {
2580 retval.append(
UCHAR(
'\uFFFD'));
2584 data =
static_cast<
char32_t>(str[i]) & 0x0F;
2586 }
else if ((str[i] & 0xF8) == 0xF0) {
2589 if (multi_size != 0) {
2591 retval.append(
UCHAR(
'\uFFFD'));
2595 data =
static_cast<
char32_t>(str[i]) & 0x07;
2600 if (multi_size != 0) {
2603 retval.append(
UCHAR(
'\uFFFD'));
2606 retval.append(
UCHAR(
'\uFFFD'));
2610 if (multi_size != 0) {
2612 retval.append(
UCHAR(
'\uFFFD'));
2620 template <
typename E,
typename A>
2621 CsBasicString<E,A> CsBasicString<E, A>::fromUtf16(
const char16_t *str, size_type numOfChars,
const A &a)
2623 CsBasicString retval(a);
2625 if (str ==
nullptr) {
2629 if (numOfChars < 0) {
2630 numOfChars = std::char_traits<
char16_t>::length(str);
2635 for (
int i = 0; i < numOfChars; ++i) {
2637 char16_t value = str[i];
2639 if (value < 0xD800 || value > 0xDFFF) {
2647 retval.append(
UCHAR(
'\uFFFD'));
2651 retval.append(
static_cast<
char32_t>(str[i]));
2653 }
else if (value >= 0xD800 && value <= 0xDBFF) {
2661 retval.append(
UCHAR(
'\uFFFD'));
2665 data =
static_cast<
char32_t>(value) & 0x3FF;
2667 }
else if (value >= 0xDC00 && value <= 0xDFFF) {
2672 retval.append(
UCHAR(
'\uFFFD'));
2675 data = (data << 10) | (
static_cast<
char32_t>(value) & 0x3FF);
2678 retval.append(data);
2685 retval.append(
UCHAR(
'\uFFFD'));
2691 retval.append(
UCHAR(
'\uFFFD'));
2697 template <
typename E,
typename A>
2698 A CsBasicString<E, A>::getAllocator()
const
2700 return m_string.get_allocator();
2703 template <
typename E,
typename A>
2704 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart, size_type count, CsChar c)
2706 const_iterator iter_begin = cbegin();
2709 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2713 if (i != indexStart) {
2714 throw std::out_of_range(
"CsString::insert index out of range");
2717 E::insert(m_string, iter_begin.codePointBegin(), c, count);
2722 template <
typename E,
typename A>
2723 template <
typename T,
typename>
2724 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const T &str)
2726 #ifndef CS_STRING_ALLOW_UNSAFE
2727 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2731 if (str ==
nullptr || *str ==
'\0') {
2736 return insert(indexStart, CsBasicString::fromUtf8(str));
2739 template <
typename E,
typename A>
2741 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const char (&str)[N])
2743 #if defined(Q_CC_MSVC)
2744 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2748 return insert(indexStart, CsBasicString::fromUtf8(str, N -1));
2751 template <
typename E,
typename A>
2752 template <
typename T,
typename>
2753 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const T &str, size_type size)
2755 #ifndef CS_STRING_ALLOW_UNSAFE
2756 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2760 if (str ==
nullptr || *str ==
'\0') {
2765 return insert(indexStart, CsBasicString::fromUtf8(str, size));
2768 template <
typename E,
typename A>
2770 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const char (&str)[N], size_type size)
2772 #if defined(Q_CC_MSVC)
2773 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2777 return insert(indexStart, CsBasicString::fromUtf8(str, size));
2780 template <
typename E,
typename A>
2781 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const CsBasicString &str)
2783 const_iterator iter_begin = cbegin();
2786 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2790 if (i != indexStart) {
2791 throw std::out_of_range(
"CsString::insert index out of range");
2794 for (CsChar c : str) {
2795 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), c);
2797 iter_begin = CsStringIterator<E, A>(iter_tmp);
2804 template <
typename E,
typename A>
2805 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const CsBasicString &str,
2806 size_type srcStart, size_type size)
2808 const_iterator iter_begin = cbegin();
2811 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2815 if (i != indexStart) {
2816 throw std::out_of_range(
"CsString::insert index out of range");
2819 const_iterator srcIter_begin = str.begin() + srcStart;
2820 const_iterator srcIter_end = srcIter_begin + size;
2822 for (
auto srcIter = srcIter_begin; srcIter != srcIter_end; ++srcIter) {
2824 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), *srcIter);
2826 iter_begin = CsStringIterator<E, A>(iter_tmp);
2833 template <
typename E,
typename A>
2834 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart, CsChar c)
2836 str_iter iter_tmp = E::insert(m_string, posStart.codePointBegin(), c);
2837 return CsStringIterator<E, A>(iter_tmp);
2840 template <
typename E,
typename A>
2841 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart, size_type count, CsChar c)
2843 str_iter iter_tmp = E::insert(m_string, posStart.codePointBegin(), c, count);
2844 return CsStringIterator<E, A>(iter_tmp);
2847 template <
typename E,
typename A>
2848 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
const CsBasicString &str)
2850 const_iterator iter = posStart;
2853 for (
auto c : str) {
2854 str_iter iter_tmp = E::insert(m_string, iter.codePointBegin(), c);
2856 iter = CsStringIterator<E, A>(iter_tmp);
2865 template <
typename E,
typename A>
2866 template <
typename T,
typename>
2867 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
const T &str,
2870 #ifndef CS_STRING_ALLOW_UNSAFE
2871 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2875 if (str ==
nullptr || *str ==
'\0') {
2880 return insert(posStart, CsBasicString::fromUtf8(str, size));
2883 template <
typename E,
typename A>
2885 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
const char (&str)[N], size_type size)
2887 #if defined(Q_CC_MSVC)
2888 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2892 return insert(posStart, CsBasicString::fromUtf8(str, size));
2895 template <
typename E,
typename A>
2896 template <
typename Iterator>
2897 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
2898 Iterator begin, Iterator end)
2900 const_iterator iter = posStart;
2903 for (
auto item = begin; item != end; ++item) {
2906 str_iter iter_tmp = E::insert(m_string, iter.codePointBegin(), c);
2908 iter = CsStringIterator<E, A>(iter_tmp);
2914 return (iter - count);
2917 template <
typename E,
typename A>
2918 template <
typename U,
typename>
2919 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(size_type indexStart, CsBasicStringView<U> str)
2921 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
2922 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
2923 "incompatible with the encoding for U");
2925 const_iterator iter_begin = cbegin();
2928 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2932 if (i != indexStart) {
2933 throw std::out_of_range(
"CsString::insert index out of range");
2936 for (CsChar c : str) {
2937 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), c);
2939 iter_begin = CsStringIterator<E, A>(iter_tmp);
2946 template <
typename E,
typename A>
2947 template <
typename U,
typename>
2948 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(size_type indexStart, CsBasicStringView<U> str,
2949 size_type srcStart, size_type size)
2951 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
2952 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
2953 "incompatible with the encoding for U");
2955 const_iterator iter_begin = cbegin();
2958 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2962 if (i != indexStart) {
2963 throw std::out_of_range(
"CsString::insert index out of range");
2966 typename U::const_iterator srcIter_begin = str.begin() + srcStart;
2967 typename U::const_iterator srcIter_end = srcIter_begin + size;
2969 for (
auto srcIter = srcIter_begin; srcIter != srcIter_end; ++srcIter) {
2971 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), *srcIter);
2973 iter_begin = CsStringIterator<E, A>(iter_tmp);
2980 template <
typename E,
typename A>
2981 auto CsBasicString<E, A>::length()
const -> size_type
2986 template <
typename E,
typename A>
2987 void CsBasicString<E, A>::pop_back()
2993 const_iterator iter = --end();
2997 template <
typename E,
typename A>
2998 void CsBasicString<E, A>::push_back(CsChar c)
3003 template <
typename E,
typename A>
3004 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type size,
const CsBasicString &str)
3006 const_iterator iter_begin = cbegin();
3007 const_iterator iter_end;
3010 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3014 if (i != indexStart) {
3015 throw std::out_of_range(
"CsString::replace index out of range");
3019 iter_end = iter_begin;
3021 for (size_type j = 0; j < size && iter_end != cend(); ++j) {
3030 auto iter = erase(iter_begin, iter_end);
3036 template <
typename E,
typename A>
3037 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
const CsBasicString &str)
3039 auto iter = erase(first, last);
3045 template <
typename E,
typename A>
3046 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const CsBasicString &str,
3047 size_type srcStart, size_type size)
3049 const_iterator iter_begin = cbegin();
3050 const_iterator iter_end;
3053 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3057 if (i != indexStart) {
3058 throw std::out_of_range(
"CsString::replace index out of range");
3062 iter_end = iter_begin;
3064 for (size_type j = 0; j < count && iter_end != cend(); ++j) {
3073 const_iterator srcIter_begin = str.begin() + srcStart;
3074 const_iterator srcIter_end = srcIter_begin + size;
3076 auto iter = erase(iter_begin, iter_end);
3077 insert(iter, srcIter_begin, srcIter_end);
3082 template <
typename E,
typename A>
3083 template <
class Iterator>
3084 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first1, const_iterator last1,
3085 Iterator first2, Iterator last2)
3087 auto iter = erase(first1, last1);
3088 insert(iter, first2, last2);
3093 template <
typename E,
typename A>
3094 template <
typename T,
typename>
3095 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
3096 const T &str, size_type size)
3101 return replace(indexStart, count, CsBasicString::fromUtf8(str, size));
3104 template <
typename E,
typename A>
3106 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const char (&str)[N], size_type size)
3108 #if defined(Q_CC_MSVC)
3109 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
3113 return replace(indexStart, count, CsBasicString::fromUtf8(str, size));
3116 template <
typename E,
typename A>
3117 template <
typename T,
typename>
3118 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3119 const T &str, size_type size)
3123 auto iter = erase(first, last);
3124 insert(iter, str, size);
3129 template <
typename E,
typename A>
3131 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3132 const char (&str)[N], size_type size )
3134 auto iter = erase(first, last);
3135 insert(iter, str, size);
3140 template <
typename E,
typename A>
3141 template <
typename T,
typename>
3142 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const T &str)
3147 return replace(indexStart, count, CsBasicString::fromUtf8(str));
3150 template <
typename E,
typename A>
3152 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const char (&str)[N])
3154 #if defined(Q_CC_MSVC)
3155 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
3159 return replace(indexStart, count, CsBasicString::fromUtf8(str, N-1));
3162 template <
typename E,
typename A>
3163 template <
typename T,
typename>
3164 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
const T &str)
3168 auto iter = erase(first, last);
3174 template <
typename E,
typename A>
3176 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3177 const char (&str)[N])
3179 auto iter = erase(first, last);
3185 template <
typename E,
typename A>
3186 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type size,
3187 size_type count, CsChar c)
3189 const_iterator iter_begin = cbegin();
3190 const_iterator iter_end;
3193 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3197 if (i != indexStart) {
3198 throw std::out_of_range(
"CsString::replace index out of range");
3202 iter_end = iter_begin;
3204 for (size_type j = 0; j < size && iter_end != cend(); ++j) {
3213 auto iter = erase(iter_begin, iter_end);
3214 insert(iter, count, c);
3219 template <
typename E,
typename A>
3220 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3221 size_type count, CsChar c)
3223 auto iter = erase(first, last);
3224 insert(iter, count, c);
3229 template <
typename E,
typename A>
3231 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const T &str,
3232 size_type srcStart, size_type size)
3237 return replace(indexStart, count, CsBasicString::fromUtf8(str + srcStart, size));
3240 template <
typename E,
typename A>
3242 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
const T &str,
3243 size_type srcStart, size_type size)
3245 auto iter = erase(first, last);
3246 insert(iter, str, srcStart, size);
3251 template <
typename E,
typename A>
3252 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::replace(const_iterator iter,
const CsBasicString &str)
3254 auto tmpIter = erase(iter);
3255 return insert(tmpIter, str);
3258 template <
typename E,
typename A>
3259 void CsBasicString<E, A>::resize(size_type size)
3265 size_type stringLen =
this->size();
3266 size_type count = size - stringLen;
3273 }
else if (count < 0) {
3274 auto end =
this->end();
3275 auto begin = end + count;
3281 template <
typename E,
typename A>
3282 void CsBasicString<E, A>::resize(size_type size, CsChar c)
3288 size_type stringLen =
this->size();
3289 size_type count = size - stringLen;
3294 }
else if (count < 0) {
3295 erase(size, -count);
3300 template <
typename E,
typename A>
3301 auto CsBasicString<E, A>::size_storage()
const -> size_type
3304 return m_string.size() - 1;
3307 template <
typename E,
typename A>
3308 auto CsBasicString<E, A>::size_codePoints()
const -> size_type
3313 template <
typename E,
typename A>
3314 auto CsBasicString<E, A>::size()
const -> size_type
3316 return E::distance(m_string.cbegin(), m_string.cend() - 1);
3319 template <
typename E,
typename A>
3320 void CsBasicString<E, A>::shrink_to_fit()
3322 m_string.shrink_to_fit();
3325 template <
typename E,
typename A>
3326 CsBasicString<E, A> CsBasicString<E, A>::substr(size_type indexStart, size_type size)
const
3328 const_iterator iter_begin = cbegin();
3329 const_iterator iter_end;
3331 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
3335 if (iter_begin == cend()) {
3337 return CsBasicString();
3341 iter_end = iter_begin;
3343 for (size_type i = 0; i < size && iter_end != cend(); ++i) {
3352 return CsBasicString(iter_begin, iter_end);
3355 template <
typename E,
typename A>
3356 void CsBasicString<E, A>::swap(CsBasicString &str)
3358 m_string.swap(str.m_string);
3362 template <
typename E,
typename A>
3363 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::begin()
const
3365 return CsStringIterator<E, A> (m_string.begin());
3368 template <
typename E,
typename A>
3369 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::cbegin()
const
3371 return CsStringIterator<E, A> (m_string.cbegin());
3374 template <
typename E,
typename A>
3375 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::end()
const
3378 return CsStringIterator<E, A> (m_string.end() - 1);
3381 template <
typename E,
typename A>
3382 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::cend()
const
3385 return CsStringIterator<E, A> (m_string.cend() - 1);
3388 template <
typename E,
typename A>
3389 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::rbegin()
const
3391 return const_reverse_iterator(end());
3394 template <
typename E,
typename A>
3395 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::crbegin()
const
3397 return const_reverse_iterator(cend());
3400 template <
typename E,
typename A>
3401 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::rend()
const
3403 return const_reverse_iterator(begin());
3406 template <
typename E,
typename A>
3407 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::crend()
const
3409 return const_reverse_iterator(cbegin());
3412 template <
typename E,
typename A>
3413 typename CsBasicString<E, A>::const_storage_iterator CsBasicString<E, A>::storage_begin()
const
3415 return m_string.cbegin();
3418 template <
typename E,
typename A>
3419 typename CsBasicString<E, A>::const_storage_iterator CsBasicString<E, A>::storage_end()
const
3421 return m_string.cend() - 1;
3424 template <
typename E,
typename A>
3425 typename CsBasicString<E, A>::const_storage_reverse_iterator CsBasicString<E, A>::storage_rbegin()
const
3427 return m_string.crbegin() + 1;
3430 template <
typename E,
typename A>
3431 typename CsBasicString<E, A>::const_storage_reverse_iterator CsBasicString<E, A>::storage_rend()
const
3433 return m_string.crend();
3437 template <
typename E_FROM,
typename A_FROM,
typename E_TO,
typename A_TO>
3438 void convert(
const CsBasicString<E_FROM, A_FROM> &str_from, CsBasicString<E_TO, A_TO> &str_to)
3440 str_to.assign(str_from.begin(), str_from.end());
3443 template <
typename E,
typename A>
3444 void swap(CsBasicString<E, A> &str1, CsBasicString<E, A> &str2)
3449 template <
typename E1,
typename A1,
typename E2,
typename A2>
3450 bool operator==(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3454 auto iter1 = str1.begin();
3455 auto iter2 = str2.begin();
3457 auto end1 = str1.end();
3458 auto end2 = str2.end();
3460 while (iter1 != end1 && iter2 != end2) {
3462 if (*iter1 != *iter2) {
3470 if (iter1 == end1 && iter2 == end2) {
3477 template <
typename E,
typename A>
3478 bool operator==(
const CsBasicString<E, A> &str1,
const CsBasicString<E, A> &str2)
3483 return std::equal(str1.storage_begin(), str1.storage_end(), str2.storage_begin(), str2.storage_end());
3486 inline bool operator==(
const CsString_utf8 &str1,
const CsString_utf8 &str2)
3489 return std::equal(str1.storage_begin(), str1.storage_end(), str2.storage_begin(), str2.storage_end());
3492 inline bool operator==(
const CsString_utf16 &str1,
const CsString_utf16 &str2)
3495 return std::equal(str1.storage_begin(), str1.storage_end(), str2.storage_begin(), str2.storage_end());
3499 inline bool operator==(
const CsString_utf8 &str1,
const char (& str2)[N])
3501 return std::equal(str1.storage_begin(), str1.storage_end(), str2, str2+N-1,
3502 [] (
auto a,
auto b) {
return static_cast<uint8_t>(a) ==
static_cast<uint8_t>(b);} );
3506 inline bool operator==(
const char (& str1)[N],
const CsString_utf8 &str2)
3508 return std::equal(str1, str1+N-1, str2.storage_begin(), str2.storage_end(),
3509 [] (
auto a,
auto b) {
return static_cast<uint8_t>(a) ==
static_cast<uint8_t>(b);} );
3513 inline bool operator==(
const CsString_utf16 &str1,
const char16_t (& str2)[N])
3515 return std::equal(str1.storage_begin(), str1.storage_end(), str2, str2+N-1);
3519 inline bool operator==(
const char16_t (& str1)[N],
const CsString_utf16 &str2)
3521 return std::equal(str1, str1+N-1, str2.storage_begin(), str2.storage_end());
3524 template <
typename E1,
typename A1,
typename E2,
typename A2>
3525 bool operator!=(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3527 return ! (str1 == str2);
3530 template <
typename E,
typename A>
3531 bool operator!=(
const CsBasicString<E, A> &str1,
const CsBasicString<E, A> &str2)
3533 return ! (str1 == str2);
3536 inline bool operator!=(
const CsString_utf8 &str1,
const CsString_utf8 &str2)
3538 return ! (str1 == str2);
3541 inline bool operator!=(
const CsString_utf16 &str1,
const CsString_utf16 &str2)
3543 return ! (str1 == str2);
3546 inline CsString_utf8 operator+(CsString_utf8 str1,
const CsString_utf8 &str2)
3553 inline CsString_utf16 operator+(CsString_utf16 str1,
const CsString_utf16 &str2)
3560 template <
typename E,
typename A>
3561 CsBasicString<E, A> operator+(
const CsBasicString<E, A> &str, CsChar c)
3563 CsBasicString<E, A> retval = str;
3569 template <
typename E,
typename A>
3570 CsBasicString<E, A> operator+(CsChar c,
const CsBasicString<E, A> &str)
3572 CsBasicString<E, A> retval = str;
3573 retval.insert(0, 1, c);
3578 template <
typename E,
typename A>
3579 CsBasicString<E, A> operator+(CsBasicString<E, A> &&str, CsChar c)
3585 template <
typename E,
typename A>
3586 CsBasicString<E, A> operator+(CsChar c, CsBasicString<E, A> &&str)
3588 str.insert(0, 1, c);
3592 template <
typename E,
typename A,
typename T,
typename =
typename std::enable_if<std::is_array<T>::value &&
3593 std::is_same<
char,
typename std::remove_extent<T>::type>::value>::type>
3594 CsBasicString<E, A> operator+(
const CsBasicString<E, A> &str1,
const T &str2)
3596 CsBasicString<E, A> retval = str1;
3597 retval.append(str2);
3602 template <
typename E,
typename A,
typename T,
typename =
typename std::enable_if<std::is_array<T>::value &&
3603 std::is_same<
char,
typename std::remove_extent<T>::type>::value>::type>
3604 CsBasicString<E, A> operator+(
const T &str1,
const CsBasicString<E, A> &str2)
3606 CsBasicString<E, A> retval = str1;
3607 retval.append(str2);
3612 template <
typename E1,
typename A1,
typename E2,
typename A2>
3613 bool operator<(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3615 return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end());
3618 template <
typename E1,
typename A1,
typename E2,
typename A2>
3619 bool operator<=(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3621 return ! (str1 > str2);
3624 template <
typename E1,
typename A1,
typename E2,
typename A2>
3625 bool operator>(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3627 return std::lexicographical_compare(str2.begin(), str2.end(), str1.begin(), str1.end());
3630 template <
typename E1,
typename A1,
typename E2,
typename A2>
3631 bool operator>=(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3633 return ! (str1 < str2);
3636 #if defined(__cpp_char8_t
)
3639 template <
typename E,
typename A>
3640 CsBasicString<E, A>::CsBasicString(
const char8_t *str,
const A &a)
3642 *
this = CsBasicString::fromUtf8(str, -1, a);
3645 template <
typename E,
typename A>
3646 CsBasicString<E, A>::CsBasicString(
const char8_t *str, size_type size,
const A &a)
3648 *
this = CsBasicString::fromUtf8(str, size, a);
#define UCHAR(x)
Definition: cs_string.h:37