19 #ifndef LIB_CS_STRING_H
20 #define LIB_CS_STRING_H
23 #include <cs_encoding.h>
24 #include <cs_string_iterator.h>
34 #include <type_traits>
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;
59 using const_iterator = CsStringIterator<E, A>;
60 using iterator = CsStringIterator<E, A>;
61 using const_reverse_iterator = CsStringReverseIterator<const_iterator>;
62 using reverse_iterator = CsStringReverseIterator<iterator>;
64 using const_storage_iterator =
typename std::vector<
typename E::storage_unit, A>::const_iterator;
65 using const_storage_reverse_iterator =
typename std::vector<
typename E::storage_unit, A>::const_reverse_iterator;
67 static constexpr const size_type npos = -1;
74 explicit CsBasicString(
const A &a)
80 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
81 std::is_same<T,
char *>::value>::type>
82 CsBasicString(
const T &str,
const A &a = A());
86 CsBasicString(
const char (&str)[N],
const A &a = A());
89 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
90 std::is_same<T,
char *>::value>::type>
91 CsBasicString(
const T &str, size_type size,
const A &a = A());
95 CsBasicString(
const char (&str)[N], size_type size,
const A &a = A());
98 CsBasicString(
const char8_t *str,
const A &a = A());
99 CsBasicString(
const char8_t *str, size_type size,
const A &a = A());
101 CsBasicString(
const char16_t *str,
const A &a = A());
102 CsBasicString(
const char16_t *str, size_type size,
const A &a = A());
104 CsBasicString(
const char32_t *str,
const A &a = A());
105 CsBasicString(
const char32_t *str, size_type size,
const A &a = A());
109 CsBasicString(
const CsBasicString &str, size_type indexStart,
const A &a = A());
110 CsBasicString(
const CsBasicString &str, size_type indexStart, size_type size,
const A &a = A());
113 CsBasicString(size_type count, CsChar c,
const A &a = A());
118 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
119 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
120 CsBasicString(CsBasicStringView<U> str,
const A &a = A());
122 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
123 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
124 CsBasicString(CsBasicStringView<U> str, size_type indexStart, size_type size,
const A &a = A());
127 template <
typename Iterator>
128 CsBasicString(Iterator begin, Iterator end,
const A &a = A());
130 CsBasicString(const_iterator begin, const_iterator end,
const A &a = A());
133 CsBasicString(
const CsBasicString &str) =
default;
134 CsBasicString(
const CsBasicString &str,
const A &a);
137 CsBasicString(CsBasicString && str) =
default;
138 CsBasicString(CsBasicString && str,
const A &a);
141 CsBasicString &operator=(
const CsBasicString &str) =
default;
142 CsBasicString &operator=(CsBasicString &&str) =
default;
147 CsBasicString &operator=(CsChar c);
150 template <
typename T>
151 CsBasicString &operator=(
const T &str);
156 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
157 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
158 CsBasicString &operator=(CsBasicStringView<U> str);
160 CsBasicString &operator+=(
const CsBasicString &str);
165 CsBasicString &operator+=(CsChar c);
168 template <
typename T>
169 CsBasicString &operator+=(
const T &str);
174 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
175 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
176 CsBasicString &operator+=(CsBasicStringView<U> str);
178 CsChar operator[](size_type index)
const;
180 template <
typename E2,
typename A2>
181 bool operator==(
const CsBasicString<E2, A2> &str2)
const noexcept {
184 auto iter1 =
this->begin();
185 auto iter2 = str2.begin();
187 auto end1 =
this->end();
188 auto end2 = str2.end();
190 while (iter1 != end1 && iter2 != end2) {
192 if (*iter1 != *iter2) {
200 if (iter1 == end1 && iter2 == end2) {
207 bool operator==(
const CsBasicString<E, A> &str)
const noexcept {
211 return std::equal(
this->storage_begin(),
this->storage_end(), str.storage_begin(), str.storage_end());
214 const_iterator advance(const_iterator begin, size_type count)
const;
215 iterator advance(iterator begin, size_type count);
218 CsBasicString &append(
const CsBasicString &str);
219 CsBasicString &append(
const CsBasicString &str, size_type indexStart, size_type size = npos);
221 CsBasicString &append(CsChar c);
222 CsBasicString &append(size_type count, CsChar c);
224 template <
typename Iterator>
225 CsBasicString &append(Iterator begin, Iterator end);
227 CsBasicString &append(const_iterator begin, const_iterator end);
231 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
232 std::is_same<T,
char *>::value>::type>
233 CsBasicString &append(
const T &str, size_type size);
237 CsBasicString &append(
const char (&str)[N], size_type size);
241 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
242 std::is_same<T,
char *>::value>::type>
243 CsBasicString &append(
const T &str);
248 CsBasicString &append(
const char (&str)[N]);
253 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
254 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
255 CsBasicString &append(CsBasicStringView<U> str);
257 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
258 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
259 CsBasicString &append(CsBasicStringView<U> str, size_type indexStart, size_type size);
261 CsBasicString &assign(size_type count, CsChar c);
262 CsBasicString &assign(
const CsBasicString &str);
263 CsBasicString &assign(
const CsBasicString &str, size_type indexStart, size_type size = npos);
264 CsBasicString &assign(CsBasicString &&str);
267 template <
typename T>
268 CsBasicString &assign(
const T &str, size_type size);
271 template <
typename T>
272 CsBasicString &assign(
const T &str);
274 template <
typename Iterator>
275 CsBasicString &assign(Iterator begin, Iterator end);
280 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
281 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
282 CsBasicString &assign(CsBasicStringView<U> str);
284 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
285 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
286 CsBasicString &assign(CsBasicStringView<U> str, size_type indexStart, size_type size);
288 CsChar at(size_type index)
const;
294 CsBasicString &erase(size_type indexStart = 0, size_type size = npos);
295 iterator erase(const_iterator iter);
296 iterator erase(const_iterator iter_begin, const_iterator iter_end);
299 const_iterator find_fast(CsChar c)
const;
300 const_iterator find_fast(CsChar c, const_iterator iter_begin)
const;
302 const_iterator find_fast(
const CsBasicString &str)
const;
303 const_iterator find_fast(
const CsBasicString &str, const_iterator iter_begin)
const;
306 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
307 std::is_same<T,
char *>::value>::type>
308 const_iterator find_fast(
const T &str, const_iterator iter_begin, size_type size)
const;
312 const_iterator find_fast(
const char (&str)[N], const_iterator iter_begin, size_type size)
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 const_iterator find_fast(
const T &str)
const;
320 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
321 std::is_same<T,
char *>::value>::type>
322 const_iterator find_fast(
const T &str, const_iterator iter_begin)
const;
326 const_iterator find_fast(
const char (&str)[N])
const;
330 const_iterator find_fast(
const char (&str)[N], const_iterator iter_begin)
const;
333 const_iterator rfind_fast(CsChar c)
const;
334 const_iterator rfind_fast(CsChar c, const_iterator iter_end)
const;
336 const_iterator rfind_fast(
const CsBasicString &str)
const;
337 const_iterator rfind_fast(
const CsBasicString &str, const_iterator iter_end)
const;
340 size_type find(
const CsBasicString &str, size_type indexStart = 0)
const;
343 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
344 std::is_same<T,
char *>::value>::type>
345 size_type find(
const T &str, size_type indexStart, size_type size)
const;
349 size_type find(
const char (&str)[N], size_type indexStart, size_type size)
const;
352 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
353 std::is_same<T,
char *>::value>::type>
354 size_type find(
const T &str, size_type indexStart = 0)
const;
358 size_type find(
const char (&str)[N], size_type indexStart = 0)
const;
360 size_type find(CsChar c, size_type indexStart = 0)
const;
367 size_type find_first_of(
const CsBasicString &str, size_type indexStart = 0)
const;
370 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
371 std::is_same<T,
char *>::value>::type>
372 size_type find_first_of(
const T &str, size_type indexStart, size_type size)
const;
376 size_type find_first_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
379 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
380 std::is_same<T,
char *>::value>::type>
381 size_type find_first_of(
const T &str, size_type indexStart = 0)
const;
385 size_type find_first_of(
const char (&str)[N], size_type indexStart = 0)
const;
387 size_type find_first_of(CsChar c, size_type indexStart = 0)
const;
394 size_type find_last_of(
const CsBasicString &str, size_type indexStart = npos)
const;
397 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
398 std::is_same<T,
char *>::value>::type>
399 size_type find_last_of(
const T &str, size_type indexStart, size_type size)
const;
403 size_type find_last_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
406 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
407 std::is_same<T,
char *>::value>::type>
408 size_type find_last_of(
const T &str, size_type indexStart = npos)
const;
412 size_type find_last_of(
const char (&str)[N], size_type indexStart = npos)
const;
414 size_type find_last_of(CsChar c, size_type indexStart = npos)
const;
421 size_type find_first_not_of(
const CsBasicString &str, size_type indexStart = 0)
const;
424 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
425 std::is_same<T,
char *>::value>::type>
426 size_type find_first_not_of(
const T &str, size_type indexStart, size_type size)
const;
430 size_type find_first_not_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
433 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
434 std::is_same<T,
char *>::value>::type>
435 size_type find_first_not_of(
const T &strc, size_type indexStart = 0)
const;
439 size_type find_first_not_of(
const char (&str)[N], size_type indexStart = 0)
const;
441 size_type find_first_not_of(CsChar c, size_type indexStart= 0)
const;
448 size_type find_last_not_of(
const CsBasicString &str, size_type indexStart = npos)
const;
451 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
452 std::is_same<T,
char *>::value>::type>
453 size_type find_last_not_of(
const T &str, size_type indexStart, size_type size)
const;
457 size_type find_last_not_of(
const char (&str)[N], size_type indexStart, size_type size)
const;
460 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
461 std::is_same<T,
char *>::value>::type>
462 size_type find_last_not_of(
const T &str, size_type indexStart = npos)
const;
466 size_type find_last_not_of(
const char (&str)[N], size_type indexStart = npos)
const;
468 size_type find_last_not_of(CsChar c, size_type indexStart = npos)
const;
475 size_type rfind(
const CsBasicString &str, size_type indexStart = npos)
const;
478 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
479 std::is_same<T,
char *>::value>::type>
480 size_type rfind(
const T &str, size_type indexStart, size_type size)
const;
484 size_type rfind(
const char (&str)[N], size_type indexStart, size_type size)
const;
487 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
488 std::is_same<T,
char *>::value>::type>
489 size_type rfind(
const T &str, size_type indexStart = npos)
const;
493 size_type rfind(
const char (&str)[N], size_type indexStart = npos)
const;
495 size_type rfind(CsChar c, size_type indexStart = npos)
const;
501 CsChar front()
const;
503 static CsBasicString fromUtf8(
const char8_t *str, size_type numOfChars = -1,
const A &a = A());
504 static CsBasicString fromUtf8(
const char *str, size_type numOfChars = -1,
const A &a = A());
506 static CsBasicString fromUtf16(
const char16_t *str, size_type numOfChars = -1,
const A &a = A());
508 A getAllocator()
const;
510 CsBasicString &insert(size_type indexStart, size_type count, CsChar c);
513 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
514 std::is_same<T,
char *>::value>::type>
515 CsBasicString &insert(size_type indexStart,
const T &str);
519 CsBasicString &insert(size_type indexStart,
const char (&str)[N]);
522 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
523 std::is_same<T,
char *>::value>::type>
524 CsBasicString &insert(size_type indexStart,
const T &str, size_type size);
528 CsBasicString &insert(size_type indexStart,
const char (&str)[N], size_type size);
530 CsBasicString &insert(size_type indexStart,
const CsBasicString &str);
532 CsBasicString &insert(size_type indexStart,
const CsBasicString &str,
533 size_type srcStart, size_type size = npos);
535 iterator insert(const_iterator posStart, CsChar c);
536 iterator insert(const_iterator posStart, size_type count, CsChar c);
537 iterator insert(const_iterator posStart,
const CsBasicString &str);
540 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
541 std::is_same<T,
char *>::value>::type>
542 iterator insert(const_iterator posStart,
const T &str, size_type size);
546 iterator insert(const_iterator posStart,
const char (&str)[N], size_type size);
548 template <
typename Iterator>
549 iterator insert(const_iterator posStart, Iterator begin, Iterator end);
554 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
555 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
556 iterator insert(size_type indexStart, CsBasicStringView<U> str);
558 template <
typename U,
typename =
typename std::enable_if< std::is_convertible<
559 decltype(*(std::declval<
typename U::const_iterator>())), CsChar>::value>::type>
560 iterator insert(size_type indexStart, CsBasicStringView<U> str, size_type srcStart, size_type size = npos);
563 void push_back(CsChar c);
565 CsBasicString &replace(size_type indexStart, size_type size,
const CsBasicString &str);
566 CsBasicString &replace(const_iterator first, const_iterator last,
const CsBasicString &str);
568 CsBasicString &replace(size_type indexStart, size_type count,
const CsBasicString &str,
569 size_type srcStart, size_type size = npos);
571 template <
class Iterator>
572 CsBasicString &replace(const_iterator first1, const_iterator last1, Iterator first2, Iterator last2);
575 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
576 std::is_same<T,
char *>::value>::type>
577 CsBasicString &replace(size_type indexStart, size_type count,
const T &str, size_type size);
581 CsBasicString &replace(size_type indexStart, size_type count,
const char (&str)[N], size_type size);
584 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
585 std::is_same<T,
char *>::value>::type>
586 CsBasicString &replace(const_iterator first, const_iterator last,
const T &str, size_type size);
590 CsBasicString &replace(const_iterator first, const_iterator last,
const char (&str)[N], size_type size);
593 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
594 std::is_same<T,
char *>::value>::type>
595 CsBasicString &replace(size_type indexStart, size_type size,
const T &str);
599 CsBasicString &replace(size_type indexStart, size_type size,
const char (&str)[N]);
602 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
603 std::is_same<T,
char *>::value>::type>
604 CsBasicString &replace(const_iterator first, const_iterator last,
const T &str);
608 CsBasicString &replace(const_iterator first, const_iterator last,
const char (&str)[N]);
610 CsBasicString &replace(size_type indexStart, size_type size, size_type count, CsChar c);
611 CsBasicString &replace(const_iterator first, const_iterator last, size_type count, CsChar c);
625 CsBasicString &replace(size_type indexStart, size_type count,
const T &str,
626 size_type srcStart, size_type size = npos);
629 CsBasicString &replace(const_iterator first, const_iterator last,
const T &str,
630 size_type srcStart, size_type size = npos);
632 iterator replace(const_iterator iter,
const CsBasicString &str);
634 void resize(size_type size);
635 void resize(size_type size, CsChar c);
637 void shrink_to_fit();
639 size_type size_storage()
const;
642 size_type size_codePoints()
const;
643 size_type size()
const;
644 size_type length()
const;
646 CsBasicString substr(size_type indexStart = 0, size_type size = npos)
const;
647 void swap(CsBasicString &str);
650 const_iterator begin()
const;
651 const_iterator cbegin()
const;
653 const_iterator end()
const;
654 const_iterator cend()
const;
656 const_reverse_iterator rbegin()
const;
657 const_reverse_iterator crbegin()
const;
659 const_reverse_iterator rend()
const;
660 const_reverse_iterator crend()
const;
663 const_storage_iterator storage_begin()
const;
664 const_storage_iterator storage_end()
const;
666 const_storage_reverse_iterator storage_rbegin()
const;
667 const_storage_reverse_iterator storage_rend()
const;
670 const typename E::storage_unit *constData()
const
676 using str_type =
typename std::vector<
typename E::storage_unit, A>;
677 using str_iter =
typename std::vector<
typename E::storage_unit, A>::const_iterator;
683 template <
typename E,
typename A>
684 CsBasicString<E, A>::CsBasicString(
const CsBasicString &str,
const A &a)
685 : m_string(str.m_string, a)
689 template <
typename E,
typename A>
690 CsBasicString<E, A>::CsBasicString(CsBasicString &&str,
const A &a)
691 : m_string(std::move(str.m_string), a)
695 template <
typename E,
typename A>
696 template <
typename T,
typename>
697 CsBasicString<E, A>::CsBasicString(
const T &str,
const A &a)
699 #ifndef CS_STRING_ALLOW_UNSAFE
700 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
704 *
this = CsBasicString::fromUtf8(str, -1, a);
707 template <
typename E,
typename A>
709 CsBasicString<E, A>::CsBasicString(
const char (&str)[N],
const A &a)
711 #if defined(Q_CC_MSVC)
712 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
716 *
this = CsBasicString::fromUtf8(str, N-1, a);
719 template <
typename E,
typename A>
720 template <
typename T,
typename>
721 CsBasicString<E, A>::CsBasicString(
const T &str, size_type size,
const A &a)
723 #ifndef CS_STRING_ALLOW_UNSAFE
724 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
728 *
this = CsBasicString::fromUtf8(str, size, a);
731 template <
typename E,
typename A>
733 CsBasicString<E, A>::CsBasicString(
const char (&str)[N], size_type size,
const A &a)
735 #if defined(Q_CC_MSVC)
736 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
740 *
this = CsBasicString::fromUtf8(str, size, a);
743 template <
typename E,
typename A>
744 CsBasicString<E, A>::CsBasicString(
const char8_t *str,
const A &a)
746 *
this = CsBasicString::fromUtf8(str, -1, a);
749 template <
typename E,
typename A>
750 CsBasicString<E, A>::CsBasicString(
const char8_t *str, size_type size,
const A &a)
752 *
this = CsBasicString::fromUtf8(str, size, a);
755 template <
typename E,
typename A>
756 CsBasicString<E, A>::CsBasicString(
const char16_t *str,
const A &a)
758 *
this = CsBasicString::fromUtf16(str, -1, a);
761 template <
typename E,
typename A>
762 CsBasicString<E, A>::CsBasicString(
const char16_t *str, size_type size,
const A &a)
764 *
this = CsBasicString::fromUtf16(str, size, a);
767 template <
typename E,
typename A>
768 CsBasicString<E, A>::CsBasicString(
const char32_t *str,
const A &a)
771 const char32_t *c = str;
774 E::insert(m_string, m_string.end() - 1, *c);
779 template <
typename E,
typename A>
780 CsBasicString<E, A>::CsBasicString(
const char32_t *str, size_type size,
const A &a)
783 const char32_t *c = str;
797 E::insert(m_string, m_string.end() - 1, *c);
802 template <
typename E,
typename A>
803 CsBasicString<E, A>::CsBasicString(
const CsBasicString &str, size_type indexStart,
const A &a)
806 const_iterator iter_begin = str.cbegin();
807 const_iterator iter_end = str.cend();
809 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
813 if (iter_begin == str.cend()) {
818 append(iter_begin, iter_end);
821 template <
typename E,
typename A>
822 CsBasicString<E, A>::CsBasicString(
const CsBasicString &str, size_type indexStart, size_type size,
const A &a)
825 const_iterator iter_begin = str.cbegin();
826 const_iterator iter_end;
828 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
832 if (iter_begin == str.cend()) {
838 iter_end = iter_begin;
840 for (size_type i = 0; i < size && iter_end != str.cend(); ++i) {
845 iter_end = str.cend();
849 append(iter_begin, iter_end);
852 template <
typename E,
typename A>
853 CsBasicString<E, A>::CsBasicString(size_type count, CsChar c,
const A &a)
856 E::insert(m_string, m_string.end() - 1, c, count);
859 template <
typename E,
typename A>
860 template <
typename U,
typename>
861 CsBasicString<E, A>::CsBasicString(CsBasicStringView<U> str,
const A &a)
862 : CsBasicString(str.begin(), str.end(), a)
864 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
865 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
866 "incompatible with the encoding for U");
869 template <
typename E,
typename A>
870 template <
typename U,
typename>
871 CsBasicString<E, A>::CsBasicString(CsBasicStringView<U> str, size_type indexStart, size_type size,
const A &a)
874 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
875 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
876 "incompatible with the encoding for U");
878 typename U::const_iterator iter_begin = str.cbegin();
879 typename U::const_iterator iter_end;
881 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
885 if (iter_begin == str.cend()) {
891 iter_end = iter_begin;
893 for (size_type i = 0; i < size && iter_end != str.cend(); ++i) {
898 iter_end = str.cend();
902 append(iter_begin, iter_end);
905 template <
typename E,
typename A>
906 template <
typename Iterator>
907 CsBasicString<E, A>::CsBasicString(Iterator begin, Iterator end,
const A &a)
910 for (Iterator item = begin; item != end; ++item) {
911 E::insert(m_string, m_string.end() - 1, *item);
915 template <
typename E,
typename A>
916 CsBasicString<E, A>::CsBasicString(const_iterator begin, const_iterator end,
const A &a)
917 : m_string(begin.codePointBegin(), end.codePointBegin(), a)
919 m_string.push_back(0);
923 template <
typename E,
typename A>
924 CsBasicString<E, A> &CsBasicString<E, A>::operator=(CsChar c)
927 m_string.push_back(0);
933 template <
typename E,
typename A>
934 template <
typename T>
935 CsBasicString<E, A> &CsBasicString<E, A>::operator=(
const T &str)
940 m_string.push_back(0);
946 template <
typename E,
typename A>
947 template <
typename U,
typename>
948 CsBasicString<E, A> &CsBasicString<E,A>::operator=(CsBasicStringView<U> str)
950 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
951 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
952 "incompatible with the encoding for U");
955 m_string.push_back(0);
961 template <
typename E,
typename A>
962 CsBasicString<E, A> &CsBasicString<E, A>::operator+=(
const CsBasicString &str)
968 template <
typename E,
typename A>
969 CsBasicString<E, A> &CsBasicString<E, A>::operator+=(CsChar c)
975 template <
typename E,
typename A>
976 template <
typename T>
977 CsBasicString<E, A> &CsBasicString<E, A>::operator+=(
const T &str)
985 template <
typename E,
typename A>
986 template <
typename U,
typename>
987 CsBasicString<E, A> &CsBasicString<E,A>::operator+=(CsBasicStringView<U> str)
989 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
990 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
991 "incompatible with the encoding for U");
997 template <
typename E,
typename A>
998 CsChar CsBasicString<E, A>::operator[](size_type index)
const
1000 const_iterator iter = begin();
1001 std::advance(iter, index);
1008 template <
typename E,
typename A>
1009 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::advance(const_iterator begin, size_type count)
const
1011 return const_iterator(E::advance(begin.codePointBegin(), cend().codePointBegin(), count));
1014 template <
typename E,
typename A>
1015 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::advance(iterator begin, size_type count)
1017 return iterator(E::advance(begin.codePointBegin(), end().codePointBegin(), count));
1020 template <
typename E,
typename A>
1021 CsBasicString<E, A> &CsBasicString<E, A>::append(
const CsBasicString &str)
1027 template <
typename E,
typename A>
1028 CsBasicString<E, A> &CsBasicString<E, A>::append(
const CsBasicString &str, size_type indexStart, size_type size)
1030 size_type stringLen =
this->size();
1031 insert(stringLen, str, indexStart, size);
1036 template <
typename E,
typename A>
1037 CsBasicString<E, A> &CsBasicString<E, A>::append(CsChar c)
1039 E::insert(m_string, m_string.end() - 1, c);
1043 template <
typename E,
typename A>
1044 CsBasicString<E, A> &CsBasicString<E, A>::append(size_type count, CsChar c)
1046 E::insert(m_string, m_string.end() - 1, c, count);
1050 template <
typename E,
typename A>
1051 template <
typename Iterator>
1052 CsBasicString<E, A> &CsBasicString<E, A>::append(Iterator begin, Iterator end)
1054 for (Iterator item = begin; item != end; ++item) {
1055 E::insert(m_string, m_string.end() - 1, *item);
1061 template <
typename E,
typename A>
1062 CsBasicString<E, A> &CsBasicString<E, A>::append(const_iterator begin, const_iterator end)
1064 m_string.insert(m_string.end() - 1, begin.codePointBegin(), end.codePointBegin());
1069 template <
typename E,
typename A>
1070 template <
typename T,
typename>
1071 CsBasicString<E, A> &CsBasicString<E, A>::append(
const T &str, size_type size)
1073 #ifndef CS_STRING_ALLOW_UNSAFE
1074 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1078 if (str ==
nullptr) {
1083 this->append(CsBasicString::fromUtf8(str, size));
1088 template <
typename E,
typename A>
1090 CsBasicString<E, A> &CsBasicString<E, A>::append(
const char (&str)[N], size_type size)
1092 #if defined(Q_CC_MSVC)
1093 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1097 this->append(CsBasicString::fromUtf8(str, size));
1102 template <
typename E,
typename A>
1103 template <
typename T,
typename>
1104 CsBasicString<E, A> &CsBasicString<E, A>::append(
const T &str)
1106 #ifndef CS_STRING_ALLOW_UNSAFE
1107 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1111 if (str ==
nullptr) {
1116 this->append(CsBasicString::fromUtf8(str));
1121 template <
typename E,
typename A>
1123 CsBasicString<E, A> &CsBasicString<E, A>::append(
const char (&str)[N])
1125 #if defined(Q_CC_MSVC)
1126 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1130 this->append(CsBasicString::fromUtf8(str, N-1));
1135 template <
typename E,
typename A>
1136 template <
typename U,
typename>
1137 CsBasicString<E, A> &CsBasicString<E, A>::append(CsBasicStringView<U> str)
1139 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1140 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1141 "incompatible with the encoding for U");
1143 append(str.cbegin(), str.cend());
1147 template <
typename E,
typename A>
1148 template <
typename U,
typename>
1149 CsBasicString<E, A> &CsBasicString<E, A>::append(CsBasicStringView<U> str, size_type indexStart, size_type size)
1151 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1152 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1153 "incompatible with the encoding for U");
1155 typename U::const_iterator iter_begin = str.cbegin();
1156 typename U::const_iterator iter_end;
1158 for (size_type i = 0; i < indexStart && iter_begin != str.cend(); ++i) {
1162 if (iter_begin == str.cend()) {
1167 iter_end = iter_begin;
1169 for (size_type i = 0; i < size && iter_end != str.cend(); ++i) {
1174 iter_end = str.cend();
1178 append(iter_begin, iter_end);
1182 template <
typename E,
typename A>
1183 CsBasicString<E, A> &CsBasicString<E, A>::assign(size_type count, CsChar c)
1191 template <
typename E,
typename A>
1192 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const CsBasicString &str)
1200 template <
typename E,
typename A>
1201 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const CsBasicString &str, size_type indexStart, size_type size)
1204 append(str, indexStart, size);
1209 template <
typename E,
typename A>
1210 CsBasicString<E, A> &CsBasicString<E, A>::assign(CsBasicString &&str)
1213 append(std::move(str));
1218 template <
typename E,
typename A>
1219 template <
typename T>
1220 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const T &str, size_type size)
1230 template <
typename E,
typename A>
1231 template <
typename T>
1232 CsBasicString<E, A> &CsBasicString<E, A>::assign(
const T &str)
1242 template <
typename E,
typename A>
1243 template <
typename Iterator>
1244 CsBasicString<E, A> &CsBasicString<E, A>::assign(Iterator begin, Iterator end)
1252 template <
typename E,
typename A>
1253 template <
typename U,
typename>
1254 CsBasicString<E, A> &CsBasicString<E, A>::assign(CsBasicStringView<U> str)
1256 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1257 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1258 "incompatible with the encoding for U");
1261 append(str.cbegin(), str.cend());
1266 template <
typename E,
typename A>
1267 template <
typename U,
typename>
1268 CsBasicString<E, A> &CsBasicString<E, A>::assign(CsBasicStringView<U> str, size_type indexStart, size_type size)
1270 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
1271 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
1272 "incompatible with the encoding for U");
1275 append(str, indexStart, size);
1280 template <
typename E,
typename A>
1281 CsChar CsBasicString<E, A>::at(size_type index)
const
1283 const_iterator iter = begin();
1284 std::advance(iter, index);
1289 template <
typename E,
typename A>
1290 CsChar CsBasicString<E, A>::back()
const
1295 template <
typename E,
typename A>
1296 void CsBasicString<E, A>::clear()
1299 m_string.push_back(0);
1302 template <
typename E,
typename A>
1303 bool CsBasicString<E, A>::empty()
const
1305 return (m_string.size() == 1);
1308 template <
typename E,
typename A>
1309 CsBasicString<E, A> &CsBasicString<E, A>::erase(size_type indexStart, size_type size)
1311 const_iterator iter_begin = cbegin();
1312 const_iterator iter_end;
1314 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
1318 if (iter_begin == cend()) {
1323 iter_end = iter_begin;
1325 for (size_type i = 0; i < size && iter_end != cend(); ++i) {
1334 erase(iter_begin, iter_end);
1339 template <
typename E,
typename A>
1340 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::erase(const_iterator iter)
1342 auto [vbegin, vend] = iter.codePointRange();
1343 auto retval = m_string.erase(vbegin, vend);
1345 return const_iterator(retval);
1348 template <
typename E,
typename A>
1349 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::erase(const_iterator iter_begin, const_iterator iter_end)
1351 auto retval = m_string.erase(iter_begin.codePointBegin(), iter_end.codePointBegin());
1352 return const_iterator(retval);
1355 template <
typename E,
typename A>
1356 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const CsBasicString &str)
const
1358 return find_fast(str, begin());
1361 template <
typename E,
typename A>
1362 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const CsBasicString &str,
1363 const_iterator iter_begin)
const
1365 const_iterator iter_end = end();
1367 if (iter_begin == iter_end) {
1375 auto iter = iter_begin;
1378 while (iter != iter_end) {
1381 auto text_iter = iter + 1;
1382 auto pattern_iter = str.begin() + 1;
1384 while (text_iter != iter_end && pattern_iter != str.end()) {
1386 if (*text_iter == *pattern_iter) {
1396 if (pattern_iter == str.end()) {
1409 template <
typename E,
typename A>
1410 template <
typename T,
typename>
1411 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const T &str, const_iterator iter_begin,
1412 size_type size)
const
1414 #ifndef CS_STRING_ALLOW_UNSAFE
1415 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1418 const_iterator iter_end = cend();
1420 if (iter_begin == iter_end) {
1424 if (str ==
nullptr || str[0] ==
'\0') {
1429 return find_fast(CsBasicString::fromUtf8(str, size), iter_begin);
1433 template <
typename E,
typename A>
1435 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const char (&str)[N], const_iterator iter_begin,
1436 size_type size)
const
1438 #if defined(Q_CC_MSVC)
1439 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1443 return find_fast(CsBasicString::fromUtf8(str, size), iter_begin);
1447 template <
typename E,
typename A>
1448 template <
typename T,
typename>
1449 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const T &str)
const
1451 return find_fast(str, cbegin());
1455 template <
typename E,
typename A>
1456 template <
typename T,
typename>
1457 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const T &str, const_iterator iter_begin)
const
1459 #ifndef CS_STRING_ALLOW_UNSAFE
1460 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1463 const_iterator iter_end = cend();
1465 if (iter_begin == iter_end) {
1469 if (str ==
nullptr || str[0] ==
'\0') {
1474 return find_fast(CsBasicString::fromUtf8(str), iter_begin);
1478 template <
typename E,
typename A>
1480 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const char (&str)[N])
const
1482 return find_fast(str, cbegin());
1486 template <
typename E,
typename A>
1488 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(
const char (&str)[N],
1489 const_iterator iter_begin)
const
1491 #if defined(Q_CC_MSVC)
1492 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1496 return find_fast(CsBasicString::fromUtf8(str, N-1), iter_begin);
1499 template <
typename E,
typename A>
1500 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(CsChar c)
const
1502 return find_fast(c, begin());
1505 template <
typename E,
typename A>
1506 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::find_fast(CsChar c, const_iterator iter_begin)
const
1508 const_iterator iter_end = end();
1510 if (iter_begin == iter_end) {
1514 auto iter = iter_begin;
1516 while (iter != iter_end) {
1528 template <
typename E,
typename A>
1529 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(CsChar c)
const
1531 return rfind_fast(c, end());
1534 template <
typename E,
typename A>
1535 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(CsChar c, const_iterator iter_end)
const
1537 const_iterator iter_begin = begin();
1539 if (iter_begin == iter_end) {
1543 auto iter = iter_end;
1545 while (iter != begin()) {
1557 template <
typename E,
typename A>
1558 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(
const CsBasicString &str)
const
1560 return rfind_fast(str, end());
1563 template <
typename E,
typename A>
1564 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::rfind_fast(
const CsBasicString &str,
1565 const_iterator iter_end)
const
1567 const_iterator iter_begin = begin();
1569 if (iter_begin == iter_end) {
1577 auto iter = iter_end;
1578 auto str_end = str.end();
1581 while (iter != begin()) {
1586 auto text_iter = iter + 1;
1587 auto pattern_iter = str.begin() + 1;
1589 while (text_iter != end() && pattern_iter != str_end) {
1591 if (*text_iter == *pattern_iter) {
1601 if (pattern_iter == str_end) {
1612 template <
typename E,
typename A>
1613 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(CsChar c, size_type indexStart)
const
1615 const_iterator iter_begin = cbegin();
1617 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
1621 if (iter_begin == cend()) {
1626 size_type retval = indexStart;
1628 while (iter_begin != end()) {
1630 if (*iter_begin == c) {
1641 template <
typename E,
typename A>
1642 template <
typename T,
typename>
1643 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const T &str, size_type indexStart,
1644 size_type size)
const
1646 #ifndef CS_STRING_ALLOW_UNSAFE
1647 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1651 return find(CsBasicString::fromUtf8(str, size), indexStart);
1654 template <
typename E,
typename A>
1656 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const char (&str)[N], size_type indexStart,
1657 size_type size)
const
1659 #if defined(Q_CC_MSVC)
1660 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1664 return find(CsBasicString::fromUtf8(str, size), indexStart);
1667 template <
typename E,
typename A>
1668 template <
typename T,
typename>
1669 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const T &str, size_type indexStart)
const
1671 #ifndef CS_STRING_ALLOW_UNSAFE
1672 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1676 size_type stringLen =
this->size();
1678 if (str ==
nullptr || *str ==
'\0') {
1680 if (indexStart > stringLen) {
1687 if (indexStart >= stringLen) {
1692 return find(CsBasicString::fromUtf8(str), indexStart);
1695 template <
typename E,
typename A>
1697 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const char (&str)[N], size_type indexStart)
const
1699 #if defined(Q_CC_MSVC)
1700 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1704 return find(CsBasicString::fromUtf8(str, N-1), indexStart);
1707 template <
typename E,
typename A>
1708 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find(
const CsBasicString &str, size_type indexStart)
const
1710 size_type stringLen =
this->size();
1714 if (indexStart > stringLen) {
1721 if (indexStart >= stringLen) {
1725 size_type retval = indexStart;
1726 auto iter = begin() + indexStart;
1729 while (iter != end()) {
1732 auto text_iter = iter + 1;
1733 auto pattern_iter = str.begin() + 1;
1735 while (text_iter != end() && pattern_iter != str.end()) {
1737 if (*text_iter == *pattern_iter) {
1747 if (pattern_iter == str.end()) {
1760 template <
typename E,
typename A>
1761 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(CsChar c, size_type indexStart)
const
1763 return find(c, indexStart);
1766 template <
typename E,
typename A>
1767 template <
typename T,
typename>
1768 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const T &str, size_type indexStart,
1769 size_type size)
const
1771 #ifndef CS_STRING_ALLOW_UNSAFE
1772 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1776 if (str ==
nullptr || *str ==
'\0' || indexStart >=
this->size()) {
1781 return find_first_of(CsBasicString::fromUtf8(str, size), indexStart);
1784 template <
typename E,
typename A>
1786 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const char (&str)[N], size_type indexStart,
1787 size_type size)
const
1789 #if defined(Q_CC_MSVC)
1790 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1794 return find_first_of(CsBasicString::fromUtf8(str, size), indexStart);
1797 template <
typename E,
typename A>
1798 template <
typename T,
typename>
1799 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const T &str, size_type indexStart)
const
1801 #ifndef CS_STRING_ALLOW_UNSAFE
1802 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1806 if (str ==
nullptr || *str ==
'\0' || indexStart >=
this->size()) {
1811 return find_first_of(CsBasicString::fromUtf8(str), indexStart);
1814 template <
typename E,
typename A>
1816 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const char (&str)[N],
1817 size_type indexStart)
const
1819 #if defined(Q_CC_MSVC)
1820 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1824 return find_first_of(CsBasicString::fromUtf8(str, N-1), indexStart);
1827 template <
typename E,
typename A>
1828 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_of(
const CsBasicString &str,
1829 size_type indexStart)
const
1831 if (str.empty() || indexStart >=
this->size()) {
1835 size_type retval = indexStart;
1836 auto iter = begin() + indexStart;
1838 while (iter != end()) {
1839 for (
auto c : str) {
1854 template <
typename E,
typename A>
1855 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(CsChar c, size_type indexStart)
const
1857 return rfind(c, indexStart);
1860 template <
typename E,
typename A>
1861 template <
typename T,
typename>
1862 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const T &str, size_type indexStart,
1863 size_type size)
const
1865 #ifndef CS_STRING_ALLOW_UNSAFE
1866 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1870 size_type stringLen =
this->size();
1872 if (str ==
nullptr || *str ==
'\0' || indexStart >= stringLen) {
1877 return find_last_of(CsBasicString::fromUtf8(str, size), indexStart);
1880 template <
typename E,
typename A>
1882 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const char (&str)[N],
1883 size_type indexStart, size_type size)
const
1885 #if defined(Q_CC_MSVC)
1886 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1890 return find_last_of(CsBasicString::fromUtf8(str, size), indexStart);
1893 template <
typename E,
typename A>
1894 template <
typename T,
typename>
1895 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const T &str, size_type indexStart)
const
1897 #ifndef CS_STRING_ALLOW_UNSAFE
1898 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1902 size_type stringLen =
this->size();
1904 if (str ==
nullptr || *str ==
'\0' || indexStart >= stringLen) {
1909 return find_last_of(CsBasicString::fromUtf8(str), indexStart);
1912 template <
typename E,
typename A>
1914 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const char (&str)[N],
1915 size_type indexStart)
const
1917 #if defined(Q_CC_MSVC)
1918 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
1922 return find_last_of(CsBasicString::fromUtf8(str, N-1), indexStart);
1925 template <
typename E,
typename A>
1926 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_of(
const CsBasicString &str,
1927 size_type indexStart)
const
1929 size_type stringLen =
this->size();
1931 if (str.empty() || indexStart >= stringLen) {
1936 const_iterator iter;
1938 if (indexStart >= 0 && indexStart < stringLen) {
1939 retval = indexStart + 1;
1940 iter = begin() + indexStart + 1;
1948 while (iter != begin()) {
1952 for (CsChar c : str) {
1964 template <
typename E,
typename A>
1965 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(CsChar c, size_type indexStart)
const
1967 if (indexStart >=
this->size()) {
1971 size_type retval = indexStart;
1972 auto iter = begin() + indexStart;
1974 while (iter != end()) {
1987 template <
typename E,
typename A>
1988 template <
typename T,
typename>
1989 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const T &str,
1990 size_type indexStart, size_type size)
const
1992 #ifndef CS_STRING_ALLOW_UNSAFE
1993 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
1997 size_type stringLen =
this->size();
1999 if (str ==
nullptr || *str ==
'\0') {
2001 if (indexStart >= stringLen) {
2008 if (indexStart >= stringLen) {
2013 return find_first_not_of(CsBasicString::fromUtf8(str, size), indexStart);
2016 template <
typename E,
typename A>
2018 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const char (&str)[N],
2019 size_type indexStart, size_type size)
const
2021 #if defined(Q_CC_MSVC)
2022 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2026 return find_first_not_of(CsBasicString::fromUtf8(str, size), indexStart);
2029 template <
typename E,
typename A>
2030 template <
typename T,
typename>
2031 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const T &str,
2032 size_type indexStart)
const
2034 #ifndef CS_STRING_ALLOW_UNSAFE
2035 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2039 size_type stringLen =
this->size();
2041 if (str ==
nullptr || *str ==
'\0') {
2043 if (indexStart >= stringLen) {
2050 if (indexStart >= stringLen) {
2055 return find_first_not_of(CsBasicString::fromUtf8(str), indexStart);
2058 template <
typename E,
typename A>
2060 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const char (&str)[N],
2061 size_type indexStart)
const
2063 #if defined(Q_CC_MSVC)
2064 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2068 return find_first_not_of(CsBasicString::fromUtf8(str, N-1), indexStart);
2071 template <
typename E,
typename A>
2072 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_first_not_of(
const CsBasicString &str,
2073 size_type indexStart)
const
2075 size_type stringLen =
this->size();
2079 if (indexStart >= stringLen) {
2086 if (indexStart >= stringLen) {
2090 size_type retval = indexStart;
2091 auto iter = begin() + indexStart;
2093 auto str_end = str.end();
2095 while (iter != end()) {
2096 const_iterator pattern_iter = str.begin();
2098 while (pattern_iter != str_end) {
2100 if (*iter == *pattern_iter) {
2108 if (pattern_iter == str_end) {
2120 template <
typename E,
typename A>
2121 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(CsChar c, size_type indexStart)
const
2123 size_type stringLen =
this->size();
2125 if (indexStart >= stringLen) {
2130 const_iterator iter;
2132 if (indexStart >= 0 && indexStart < stringLen) {
2133 retval = indexStart + 1;
2134 iter = begin() + indexStart + 1;
2142 while (iter != begin()) {
2154 template <
typename E,
typename A>
2155 template <
typename T,
typename>
2156 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const T &str, size_type indexStart,
2157 size_type size)
const
2159 #ifndef CS_STRING_ALLOW_UNSAFE
2160 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2164 size_type stringLen =
this->size();
2166 if (str ==
nullptr || *str ==
'\0') {
2168 if (indexStart > stringLen || indexStart == -1) {
2169 return stringLen - 1;
2176 return find_last_not_of(CsBasicString::fromUtf8(str, size), indexStart);
2179 template <
typename E,
typename A>
2181 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const char (&str)[N],
2182 size_type indexStart, size_type size)
const
2184 #if defined(Q_CC_MSVC)
2185 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2189 return find_last_not_of(CsBasicString::fromUtf8(str, size), indexStart);
2192 template <
typename E,
typename A>
2193 template <
typename T,
typename>
2194 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const T &str, size_type indexStart)
const
2196 #ifndef CS_STRING_ALLOW_UNSAFE
2197 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2201 size_type stringLen =
this->size();
2203 if (str ==
nullptr || *str ==
'\0') {
2205 if (indexStart > stringLen || indexStart == -1) {
2206 return stringLen - 1;
2213 return find_last_not_of(CsBasicString::fromUtf8(str), indexStart);
2216 template <
typename E,
typename A>
2218 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const char (&str)[N],
2219 size_type indexStart)
const
2221 #if defined(Q_CC_MSVC)
2222 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2226 return find_last_not_of(CsBasicString::fromUtf8(str, N-1), indexStart);
2229 template <
typename E,
typename A>
2230 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::find_last_not_of(
const CsBasicString &str,
2231 size_type indexStart)
const
2233 size_type stringLen =
this->size();
2237 if (indexStart > stringLen || indexStart == -1) {
2238 return stringLen - 1;
2245 const_iterator iter;
2247 if (indexStart >= 0 && indexStart < stringLen) {
2248 retval = indexStart + 1;
2249 iter = begin() + indexStart + 1;
2257 const_iterator str_end = str.end();
2259 while (iter != begin()) {
2263 const_iterator pattern_iter = str.begin();
2265 while (pattern_iter != str_end) {
2267 if (*iter == *pattern_iter) {
2275 if (pattern_iter == str_end) {
2284 template <
typename E,
typename A>
2285 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(CsChar c, size_type indexStart)
const
2287 size_type stringLen =
this->size();
2290 const_iterator iter;
2292 if (indexStart >= 0 && indexStart < stringLen) {
2293 retval = indexStart + 1;
2294 iter = begin() + indexStart + 1;
2302 while (iter != begin()) {
2314 template <
typename E,
typename A>
2315 template <
typename T,
typename>
2316 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const T &str, size_type indexStart,
2317 size_type size)
const
2319 #ifndef CS_STRING_ALLOW_UNSAFE
2320 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2324 size_type stringLen =
this->size();
2326 if (str ==
nullptr || *str ==
'\0') {
2328 if (indexStart > stringLen || indexStart == -1) {
2336 return rfind(CsBasicString::fromUtf8(str, size), indexStart);
2339 template <
typename E,
typename A>
2341 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const char (&str)[N],
2342 size_type indexStart, size_type size)
const
2344 #if defined(Q_CC_MSVC)
2345 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2349 return rfind(CsBasicString::fromUtf8(str, size), indexStart);
2352 template <
typename E,
typename A>
2353 template <
typename T,
typename>
2354 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const T &str, size_type indexStart)
const
2356 #ifndef CS_STRING_ALLOW_UNSAFE
2357 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2361 size_type stringLen =
this->size();
2363 if (str ==
nullptr || *str ==
'\0') {
2365 if (indexStart > stringLen || indexStart == -1) {
2373 return rfind(CsBasicString::fromUtf8(str), indexStart);
2376 template <
typename E,
typename A>
2378 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const char (&str)[N], size_type indexStart)
const
2380 #if defined(Q_CC_MSVC)
2381 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2385 return rfind(CsBasicString::fromUtf8(str, N-1), indexStart);
2388 template <
typename E,
typename A>
2389 typename CsBasicString<E, A>::size_type CsBasicString<E, A>::rfind(
const CsBasicString &str, size_type indexStart)
const
2391 size_type stringLen =
this->size();
2395 if (indexStart > stringLen || indexStart == -1) {
2403 const_iterator iter;
2405 if (indexStart >= 0 && indexStart < stringLen) {
2406 retval = indexStart + 1;
2407 iter = begin() + indexStart + 1;
2415 const_iterator str_end = str.end();
2418 while (iter != begin()) {
2424 auto text_iter = iter + 1;
2425 auto pattern_iter = str.begin() + 1;
2427 while (text_iter != end() && pattern_iter != str_end) {
2429 if (*text_iter == *pattern_iter) {
2439 if (pattern_iter == str_end) {
2450 template <
typename E,
typename A>
2451 CsChar CsBasicString<E, A>::front()
const
2456 template <
typename E,
typename A>
2457 CsBasicString<E,A> CsBasicString<E, A>::fromUtf8(
const char *str, size_type numOfChars,
const A &a)
2459 CsBasicString retval(a);
2461 if (str ==
nullptr) {
2465 if (numOfChars < 0) {
2466 numOfChars = std::strlen(str);
2472 for (
int i = 0; i < numOfChars; ++i) {
2474 if ((str[i] & 0x80) == 0) {
2476 if (multi_size != 0) {
2479 retval.append(
UCHAR(
'\uFFFD'));
2482 retval.append(
static_cast<
char32_t>(str[i]));
2484 }
else if ((str[i] & 0xC0) == 0x80) {
2487 data = (data << 6) | (
static_cast<
char32_t>(str[i]) & 0x3F);
2489 if (multi_size == 2 && data >= 0x80 && data <= 0x7FF) {
2491 retval.append(data);
2493 }
else if (multi_size == 3 && data >= 0x800 && data <= 0xFFFF) {
2495 retval.append(data);
2497 }
else if (multi_size == 4 && data >= 0x10000 && data <= 0x10FFFF) {
2499 retval.append(data);
2503 }
else if ((str[i] & 0xE0) == 0xC0) {
2506 if (multi_size != 0) {
2508 retval.append(
UCHAR(
'\uFFFD'));
2512 data =
static_cast<
char32_t>(str[i]) & 0x1F;
2514 }
else if ((str[i] & 0xF0) == 0xE0) {
2517 if (multi_size != 0) {
2519 retval.append(
UCHAR(
'\uFFFD'));
2523 data =
static_cast<
char32_t>(str[i]) & 0x0F;
2525 }
else if ((str[i] & 0xF8) == 0xF0) {
2528 if (multi_size != 0) {
2530 retval.append(
UCHAR(
'\uFFFD'));
2534 data =
static_cast<
char32_t>(str[i]) & 0x07;
2539 if (multi_size != 0) {
2542 retval.append(
UCHAR(
'\uFFFD'));
2545 retval.append(
UCHAR(
'\uFFFD'));
2549 if (multi_size != 0) {
2551 retval.append(
UCHAR(
'\uFFFD'));
2557 template <
typename E,
typename A>
2558 CsBasicString<E,A> CsBasicString<E, A>::fromUtf8(
const char8_t *str, size_type numOfChars,
const A &a)
2560 CsBasicString retval(a);
2562 if (str ==
nullptr) {
2566 if (numOfChars < 0) {
2567 numOfChars = std::char_traits<
char8_t>::length(str);
2573 for (
int i = 0; i < numOfChars; ++i) {
2575 if ((str[i] & 0x80) == 0) {
2577 if (multi_size != 0) {
2580 retval.append(
UCHAR(
'\uFFFD'));
2583 retval.append(
static_cast<
char32_t>(str[i]));
2585 }
else if ((str[i] & 0xC0) == 0x80) {
2588 data = (data << 6) | (
static_cast<
char32_t>(str[i]) & 0x3F);
2590 if (multi_size == 2 && data >= 0x80 && data <= 0x7FF) {
2592 retval.append(data);
2594 }
else if (multi_size == 3 && data >= 0x800 && data <= 0xFFFF) {
2596 retval.append(data);
2598 }
else if (multi_size == 4 && data >= 0x10000 && data <= 0x10FFFF) {
2600 retval.append(data);
2604 }
else if ((str[i] & 0xE0) == 0xC0) {
2607 if (multi_size != 0) {
2609 retval.append(
UCHAR(
'\uFFFD'));
2613 data =
static_cast<
char32_t>(str[i]) & 0x1F;
2615 }
else if ((str[i] & 0xF0) == 0xE0) {
2618 if (multi_size != 0) {
2620 retval.append(
UCHAR(
'\uFFFD'));
2624 data =
static_cast<
char32_t>(str[i]) & 0x0F;
2626 }
else if ((str[i] & 0xF8) == 0xF0) {
2629 if (multi_size != 0) {
2631 retval.append(
UCHAR(
'\uFFFD'));
2635 data =
static_cast<
char32_t>(str[i]) & 0x07;
2640 if (multi_size != 0) {
2643 retval.append(
UCHAR(
'\uFFFD'));
2646 retval.append(
UCHAR(
'\uFFFD'));
2650 if (multi_size != 0) {
2652 retval.append(
UCHAR(
'\uFFFD'));
2658 template <
typename E,
typename A>
2659 CsBasicString<E,A> CsBasicString<E, A>::fromUtf16(
const char16_t *str, size_type numOfChars,
const A &a)
2661 CsBasicString retval(a);
2663 if (str ==
nullptr) {
2667 if (numOfChars < 0) {
2668 numOfChars = std::char_traits<
char16_t>::length(str);
2673 for (
int i = 0; i < numOfChars; ++i) {
2675 char16_t value = str[i];
2677 if (value < 0xD800 || value > 0xDFFF) {
2685 retval.append(
UCHAR(
'\uFFFD'));
2689 retval.append(
static_cast<
char32_t>(str[i]));
2691 }
else if (value >= 0xD800 && value <= 0xDBFF) {
2699 retval.append(
UCHAR(
'\uFFFD'));
2703 data =
static_cast<
char32_t>(value) & 0x3FF;
2705 }
else if (value >= 0xDC00 && value <= 0xDFFF) {
2710 retval.append(
UCHAR(
'\uFFFD'));
2713 data = (data << 10) | (
static_cast<
char32_t>(value) & 0x3FF);
2716 retval.append(data);
2723 retval.append(
UCHAR(
'\uFFFD'));
2729 retval.append(
UCHAR(
'\uFFFD'));
2735 template <
typename E,
typename A>
2736 A CsBasicString<E, A>::getAllocator()
const
2738 return m_string.get_allocator();
2741 template <
typename E,
typename A>
2742 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart, size_type count, CsChar c)
2744 const_iterator iter_begin = cbegin();
2747 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2751 if (i != indexStart) {
2752 throw std::out_of_range(
"CsString::insert index out of range");
2755 E::insert(m_string, iter_begin.codePointBegin(), c, count);
2760 template <
typename E,
typename A>
2761 template <
typename T,
typename>
2762 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const T &str)
2764 #ifndef CS_STRING_ALLOW_UNSAFE
2765 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2769 if (str ==
nullptr || *str ==
'\0') {
2774 return insert(indexStart, CsBasicString::fromUtf8(str));
2777 template <
typename E,
typename A>
2779 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const char (&str)[N])
2781 #if defined(Q_CC_MSVC)
2782 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2786 return insert(indexStart, CsBasicString::fromUtf8(str, N -1));
2789 template <
typename E,
typename A>
2790 template <
typename T,
typename>
2791 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const T &str, size_type size)
2793 #ifndef CS_STRING_ALLOW_UNSAFE
2794 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2798 if (str ==
nullptr || *str ==
'\0') {
2803 return insert(indexStart, CsBasicString::fromUtf8(str, size));
2806 template <
typename E,
typename A>
2808 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const char (&str)[N], size_type size)
2810 #if defined(Q_CC_MSVC)
2811 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2815 return insert(indexStart, CsBasicString::fromUtf8(str, size));
2818 template <
typename E,
typename A>
2819 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const CsBasicString &str)
2821 const_iterator iter_begin = cbegin();
2824 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2828 if (i != indexStart) {
2829 throw std::out_of_range(
"CsString::insert index out of range");
2832 for (CsChar c : str) {
2833 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), c);
2835 iter_begin = CsStringIterator<E, A>(iter_tmp);
2842 template <
typename E,
typename A>
2843 CsBasicString<E, A> &CsBasicString<E, A>::insert(size_type indexStart,
const CsBasicString &str,
2844 size_type srcStart, size_type size)
2846 const_iterator iter_begin = cbegin();
2849 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2853 if (i != indexStart) {
2854 throw std::out_of_range(
"CsString::insert index out of range");
2857 const_iterator srcIter_begin = str.begin() + srcStart;
2858 const_iterator srcIter_end = srcIter_begin + size;
2860 for (
auto srcIter = srcIter_begin; srcIter != srcIter_end; ++srcIter) {
2862 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), *srcIter);
2864 iter_begin = CsStringIterator<E, A>(iter_tmp);
2871 template <
typename E,
typename A>
2872 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart, CsChar c)
2874 str_iter iter_tmp = E::insert(m_string, posStart.codePointBegin(), c);
2875 return CsStringIterator<E, A>(iter_tmp);
2878 template <
typename E,
typename A>
2879 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart, size_type count, CsChar c)
2881 str_iter iter_tmp = E::insert(m_string, posStart.codePointBegin(), c, count);
2882 return CsStringIterator<E, A>(iter_tmp);
2885 template <
typename E,
typename A>
2886 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
const CsBasicString &str)
2888 const_iterator iter = posStart;
2889 size_type count = 0;
2891 for (
auto c : str) {
2892 str_iter iter_tmp = E::insert(m_string, iter.codePointBegin(), c);
2894 iter = CsStringIterator<E, A>(iter_tmp);
2900 return (iter - count);
2903 template <
typename E,
typename A>
2904 template <
typename T,
typename>
2905 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
const T &str,
2908 #ifndef CS_STRING_ALLOW_UNSAFE
2909 static_assert(! std::is_same<E, E>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
2913 if (str ==
nullptr || *str ==
'\0') {
2918 return insert(posStart, CsBasicString::fromUtf8(str, size));
2921 template <
typename E,
typename A>
2923 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
const char (&str)[N],
2926 #if defined(Q_CC_MSVC)
2927 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
2931 return insert(posStart, CsBasicString::fromUtf8(str, size));
2934 template <
typename E,
typename A>
2935 template <
typename Iterator>
2936 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(const_iterator posStart,
2937 Iterator begin, Iterator end)
2939 const_iterator iter = posStart;
2940 size_type count = 0;
2942 for (
auto item = begin; item != end; ++item) {
2945 str_iter iter_tmp = E::insert(m_string, iter.codePointBegin(), c);
2947 iter = CsStringIterator<E, A>(iter_tmp);
2953 return (iter - count);
2956 template <
typename E,
typename A>
2957 template <
typename U,
typename>
2958 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(size_type indexStart, CsBasicStringView<U> str)
2960 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
2961 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
2962 "incompatible with the encoding for U");
2964 const_iterator iter_begin = cbegin();
2967 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
2971 if (i != indexStart) {
2972 throw std::out_of_range(
"CsString::insert index out of range");
2975 for (CsChar c : str) {
2976 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), c);
2978 iter_begin = CsStringIterator<E, A>(iter_tmp);
2985 template <
typename E,
typename A>
2986 template <
typename U,
typename>
2987 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::insert(size_type indexStart, CsBasicStringView<U> str,
2988 size_type srcStart, size_type size)
2990 static_assert(std::is_base_of<CsBasicString<E,A>, U>::value,
2991 "Unable to construct a CsBasicString using a CsBasicStringView, encoding E is "
2992 "incompatible with the encoding for U");
2994 const_iterator iter_begin = cbegin();
2997 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3001 if (i != indexStart) {
3002 throw std::out_of_range(
"CsString::insert index out of range");
3005 typename U::const_iterator srcIter_begin = str.begin() + srcStart;
3006 typename U::const_iterator srcIter_end = srcIter_begin + size;
3008 for (
auto srcIter = srcIter_begin; srcIter != srcIter_end; ++srcIter) {
3010 str_iter iter_tmp = E::insert(m_string, iter_begin.codePointBegin(), *srcIter);
3012 iter_begin = CsStringIterator<E, A>(iter_tmp);
3019 template <
typename E,
typename A>
3020 auto CsBasicString<E, A>::length()
const -> size_type
3025 template <
typename E,
typename A>
3026 void CsBasicString<E, A>::pop_back()
3032 const_iterator iter = --end();
3036 template <
typename E,
typename A>
3037 void CsBasicString<E, A>::push_back(CsChar c)
3042 template <
typename E,
typename A>
3043 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type size,
const CsBasicString &str)
3045 const_iterator iter_begin = cbegin();
3046 const_iterator iter_end;
3049 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3053 if (i != indexStart) {
3054 throw std::out_of_range(
"CsString::replace index out of range");
3058 iter_end = iter_begin;
3060 for (size_type j = 0; j < size && iter_end != cend(); ++j) {
3069 auto iter = erase(iter_begin, iter_end);
3075 template <
typename E,
typename A>
3076 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
const CsBasicString &str)
3078 auto iter = erase(first, last);
3084 template <
typename E,
typename A>
3085 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const CsBasicString &str,
3086 size_type srcStart, size_type size)
3088 const_iterator iter_begin = cbegin();
3089 const_iterator iter_end;
3092 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3096 if (i != indexStart) {
3097 throw std::out_of_range(
"CsString::replace index out of range");
3101 iter_end = iter_begin;
3103 for (size_type j = 0; j < count && iter_end != cend(); ++j) {
3112 const_iterator srcIter_begin = str.begin() + srcStart;
3113 const_iterator srcIter_end = srcIter_begin + size;
3115 auto iter = erase(iter_begin, iter_end);
3116 insert(iter, srcIter_begin, srcIter_end);
3121 template <
typename E,
typename A>
3122 template <
class Iterator>
3123 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first1, const_iterator last1,
3124 Iterator first2, Iterator last2)
3126 auto iter = erase(first1, last1);
3127 insert(iter, first2, last2);
3132 template <
typename E,
typename A>
3133 template <
typename T,
typename>
3134 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
3135 const T &str, size_type size)
3140 return replace(indexStart, count, CsBasicString::fromUtf8(str, size));
3143 template <
typename E,
typename A>
3145 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const char (&str)[N],
3148 #if defined(Q_CC_MSVC)
3149 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
3153 return replace(indexStart, count, CsBasicString::fromUtf8(str, size));
3156 template <
typename E,
typename A>
3157 template <
typename T,
typename>
3158 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3159 const T &str, size_type size)
3163 auto iter = erase(first, last);
3164 insert(iter, str, size);
3169 template <
typename E,
typename A>
3171 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3172 const char (&str)[N], size_type size )
3174 auto iter = erase(first, last);
3175 insert(iter, str, size);
3180 template <
typename E,
typename A>
3181 template <
typename T,
typename>
3182 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const T &str)
3187 return replace(indexStart, count, CsBasicString::fromUtf8(str));
3190 template <
typename E,
typename A>
3192 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const char (&str)[N])
3194 #if defined(Q_CC_MSVC)
3195 static_assert(
"¿"[0] ==
static_cast<
char>(0xC2),
"Compiler runtime encoding was not set to UTF-8");
3199 return replace(indexStart, count, CsBasicString::fromUtf8(str, N-1));
3202 template <
typename E,
typename A>
3203 template <
typename T,
typename>
3204 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
const T &str)
3208 auto iter = erase(first, last);
3214 template <
typename E,
typename A>
3216 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3217 const char (&str)[N])
3219 auto iter = erase(first, last);
3225 template <
typename E,
typename A>
3226 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type size,
3227 size_type count, CsChar c)
3229 const_iterator iter_begin = cbegin();
3230 const_iterator iter_end;
3233 for (i = 0; i < indexStart && iter_begin != cend(); ++i) {
3237 if (i != indexStart) {
3238 throw std::out_of_range(
"CsString::replace index out of range");
3242 iter_end = iter_begin;
3244 for (size_type j = 0; j < size && iter_end != cend(); ++j) {
3253 auto iter = erase(iter_begin, iter_end);
3254 insert(iter, count, c);
3259 template <
typename E,
typename A>
3260 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
3261 size_type count, CsChar c)
3263 auto iter = erase(first, last);
3264 insert(iter, count, c);
3269 template <
typename E,
typename A>
3271 CsBasicString<E, A> &CsBasicString<E, A>::replace(size_type indexStart, size_type count,
const T &str,
3272 size_type srcStart, size_type size)
3277 return replace(indexStart, count, CsBasicString::fromUtf8(str + srcStart, size));
3280 template <
typename E,
typename A>
3282 CsBasicString<E, A> &CsBasicString<E, A>::replace(const_iterator first, const_iterator last,
const T &str,
3283 size_type srcStart, size_type size)
3285 auto iter = erase(first, last);
3286 insert(iter, str, srcStart, size);
3291 template <
typename E,
typename A>
3292 typename CsBasicString<E, A>::iterator CsBasicString<E, A>::replace(const_iterator iter,
const CsBasicString &str)
3294 auto tmpIter = erase(iter);
3295 return insert(tmpIter, str);
3298 template <
typename E,
typename A>
3299 void CsBasicString<E, A>::resize(size_type size)
3305 size_type stringLen =
this->size();
3306 size_type count = size - stringLen;
3313 }
else if (count < 0) {
3314 auto end =
this->end();
3315 auto begin = end + count;
3321 template <
typename E,
typename A>
3322 void CsBasicString<E, A>::resize(size_type size, CsChar c)
3328 size_type stringLen =
this->size();
3329 size_type count = size - stringLen;
3334 }
else if (count < 0) {
3335 erase(size, -count);
3340 template <
typename E,
typename A>
3341 auto CsBasicString<E, A>::size_storage()
const -> size_type
3344 return m_string.size() - 1;
3347 template <
typename E,
typename A>
3348 auto CsBasicString<E, A>::size_codePoints()
const -> size_type
3353 template <
typename E,
typename A>
3354 auto CsBasicString<E, A>::size()
const -> size_type
3356 return E::distance(m_string.cbegin(), m_string.cend() - 1);
3359 template <
typename E,
typename A>
3360 void CsBasicString<E, A>::shrink_to_fit()
3362 m_string.shrink_to_fit();
3365 template <
typename E,
typename A>
3366 CsBasicString<E, A> CsBasicString<E, A>::substr(size_type indexStart, size_type size)
const
3368 const_iterator iter_begin = cbegin();
3369 const_iterator iter_end;
3371 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
3375 if (iter_begin == cend()) {
3377 return CsBasicString();
3381 iter_end = iter_begin;
3383 for (size_type i = 0; i < size && iter_end != cend(); ++i) {
3392 return CsBasicString(iter_begin, iter_end);
3395 template <
typename E,
typename A>
3396 void CsBasicString<E, A>::swap(CsBasicString &str)
3398 m_string.swap(str.m_string);
3402 template <
typename E,
typename A>
3403 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::begin()
const
3405 return CsStringIterator<E, A> (m_string.begin());
3408 template <
typename E,
typename A>
3409 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::cbegin()
const
3411 return CsStringIterator<E, A> (m_string.cbegin());
3414 template <
typename E,
typename A>
3415 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::end()
const
3417 return CsStringIterator<E, A> (m_string.end() - 1);
3420 template <
typename E,
typename A>
3421 typename CsBasicString<E, A>::const_iterator CsBasicString<E, A>::cend()
const
3423 return CsStringIterator<E, A> (m_string.cend() - 1);
3426 template <
typename E,
typename A>
3427 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::rbegin()
const
3429 return const_reverse_iterator(end());
3432 template <
typename E,
typename A>
3433 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::crbegin()
const
3435 return const_reverse_iterator(cend());
3438 template <
typename E,
typename A>
3439 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::rend()
const
3441 return const_reverse_iterator(begin());
3444 template <
typename E,
typename A>
3445 typename CsBasicString<E, A>::const_reverse_iterator CsBasicString<E, A>::crend()
const
3447 return const_reverse_iterator(cbegin());
3450 template <
typename E,
typename A>
3451 typename CsBasicString<E, A>::const_storage_iterator CsBasicString<E, A>::storage_begin()
const
3453 return m_string.cbegin();
3456 template <
typename E,
typename A>
3457 typename CsBasicString<E, A>::const_storage_iterator CsBasicString<E, A>::storage_end()
const
3459 return m_string.cend() - 1;
3462 template <
typename E,
typename A>
3463 typename CsBasicString<E, A>::const_storage_reverse_iterator CsBasicString<E, A>::storage_rbegin()
const
3465 return m_string.crbegin() + 1;
3468 template <
typename E,
typename A>
3469 typename CsBasicString<E, A>::const_storage_reverse_iterator CsBasicString<E, A>::storage_rend()
const
3471 return m_string.crend();
3475 template <
typename E_FROM,
typename A_FROM,
typename E_TO,
typename A_TO>
3476 void convert(
const CsBasicString<E_FROM, A_FROM> &str_from, CsBasicString<E_TO, A_TO> &str_to)
3478 str_to.assign(str_from.begin(), str_from.end());
3481 template <
typename E,
typename A>
3482 void swap(CsBasicString<E, A> &str1, CsBasicString<E, A> &str2)
3488 inline bool operator==(
const CsString_utf8 &str1,
const char (& str2)[N])
3490 return std::equal(str1.storage_begin(), str1.storage_end(), str2, str2+N-1,
3491 [] (
auto a,
auto b) {
return static_cast<uint8_t>(a) ==
static_cast<uint8_t>(b);} );
3495 inline bool operator==(
const char (& str1)[N],
const CsString_utf8 &str2)
3497 return std::equal(str1, str1+N-1, str2.storage_begin(), str2.storage_end(),
3498 [] (
auto a,
auto b) {
return static_cast<uint8_t>(a) ==
static_cast<uint8_t>(b);} );
3502 inline bool operator==(
const CsString_utf16 &str1,
const char16_t (& str2)[N])
3504 return std::equal(str1.storage_begin(), str1.storage_end(), str2, str2+N-1);
3508 inline bool operator==(
const char16_t (& str1)[N],
const CsString_utf16 &str2)
3510 return std::equal(str1, str1+N-1, str2.storage_begin(), str2.storage_end());
3513 inline CsString_utf8 operator+(CsString_utf8 str1,
const CsString_utf8 &str2)
3520 inline CsString_utf16 operator+(CsString_utf16 str1,
const CsString_utf16 &str2)
3527 template <
typename E,
typename A>
3528 CsBasicString<E, A> operator+(
const CsBasicString<E, A> &str, CsChar c)
3530 CsBasicString<E, A> retval = str;
3536 template <
typename E,
typename A>
3537 CsBasicString<E, A> operator+(CsChar c,
const CsBasicString<E, A> &str)
3539 CsBasicString<E, A> retval = str;
3540 retval.insert(0, 1, c);
3545 template <
typename E,
typename A>
3546 CsBasicString<E, A> operator+(CsBasicString<E, A> &&str, CsChar c)
3552 template <
typename E,
typename A>
3553 CsBasicString<E, A> operator+(CsChar c, CsBasicString<E, A> &&str)
3555 str.insert(0, 1, c);
3559 template <
typename E,
typename A,
typename T,
typename =
typename std::enable_if<std::is_array<T>::value &&
3560 std::is_same<
char,
typename std::remove_extent<T>::type>::value>::type>
3561 CsBasicString<E, A> operator+(
const CsBasicString<E, A> &str1,
const T &str2)
3563 CsBasicString<E, A> retval = str1;
3564 retval.append(str2);
3569 template <
typename E,
typename A,
typename T,
typename =
typename std::enable_if<std::is_array<T>::value &&
3570 std::is_same<
char,
typename std::remove_extent<T>::type>::value>::type>
3571 CsBasicString<E, A> operator+(
const T &str1,
const CsBasicString<E, A> &str2)
3573 CsBasicString<E, A> retval = str1;
3574 retval.append(str2);
3579 template <
typename E1,
typename A1,
typename E2,
typename A2>
3580 bool operator<(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3582 return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end());
3585 template <
typename E1,
typename A1,
typename E2,
typename A2>
3586 bool operator<=(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3588 return ! (str1 > str2);
3591 template <
typename E1,
typename A1,
typename E2,
typename A2>
3592 bool operator>(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3594 return std::lexicographical_compare(str2.begin(), str2.end(), str1.begin(), str1.end());
3597 template <
typename E1,
typename A1,
typename E2,
typename A2>
3598 bool operator>=(
const CsBasicString<E1, A1> &str1,
const CsBasicString<E2, A2> &str2)
3600 return ! (str1 < str2);
#define UCHAR(x)
Definition: cs_string.h:37