19 #ifndef LIB_CS_STRING_VIEW_H
20 #define LIB_CS_STRING_VIEW_H
22 #include <cs_string.h>
27 class CsBasicStringView;
29 using CsStringView = CsBasicStringView<CsBasicString<utf8>>;
30 using CsStringView_utf8 = CsBasicStringView<CsBasicString<utf8>>;
31 using CsStringView_utf16 = CsBasicStringView<CsBasicString<utf16>>;
34 class CsBasicStringView
37 using difference_type =
typename S::difference_type;
38 using size_type =
typename S::difference_type;
39 using value_type =
typename S::value_type;
41 using const_iterator =
typename S::const_iterator;
42 using iterator =
typename S::const_iterator;
43 using const_reverse_iterator =
typename S::const_reverse_iterator;
44 using reverse_iterator =
typename S::const_reverse_iterator;
46 using const_storage_iterator =
typename S::const_storage_iterator;
47 using const_storage_reverse_iterator =
typename S::const_storage_reverse_iterator;
49 static constexpr const size_type npos = -1;
51 CsBasicStringView() =
default;
53 CsBasicStringView(
const CsBasicStringView &str) =
default;
54 CsBasicStringView(CsBasicStringView &&str) =
default;
56 CsBasicStringView(
const S &str)
57 : m_begin(str.cbegin()), m_end(str.cend())
61 CsBasicStringView(S &&str) =
delete;
64 CsBasicStringView(const_iterator begin, const_iterator end)
65 : m_begin(begin), m_end(end)
70 CsBasicStringView<S> &operator=(
const CsBasicStringView &str) =
default;
71 CsBasicStringView<S> &operator=(CsBasicStringView &&str) =
default;
73 value_type operator[](size_type index)
const;
76 value_type at(size_type index)
const;
77 value_type back()
const;
79 int compare(CsBasicStringView str)
const;
82 bool endsWith(CsBasicStringView str)
const;
85 const_iterator find_fast(value_type c)
const;
86 const_iterator find_fast(value_type c, const_iterator iter_begin)
const;
88 const_iterator find_fast(CsBasicStringView str)
const;
89 const_iterator find_fast(CsBasicStringView str, const_iterator iter_begin)
const;
92 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
93 std::is_same<T,
char *>::value>::type>
94 const_iterator find_fast(
const T &str, const_iterator iter_begin, size_type size)
const;
98 const_iterator find_fast(
const char (&str)[N], const_iterator iter_begin, size_type size)
const;
101 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
102 std::is_same<T,
char *>::value>::type>
103 const_iterator find_fast(
const T &str)
const;
106 template <
typename T,
typename =
typename std::enable_if<std::is_same<T,
const char *>::value ||
107 std::is_same<T,
char *>::value>::type>
108 const_iterator find_fast(
const T &str, const_iterator iter_begin)
const;
112 const_iterator find_fast(
const char (&str)[N])
const;
116 const_iterator find_fast(
const char (&str)[N], const_iterator iter_begin)
const;
119 const_iterator rfind_fast(value_type c)
const;
120 const_iterator rfind_fast(value_type c, const_iterator iter_end)
const;
122 const_iterator rfind_fast(CsBasicStringView str)
const;
123 const_iterator rfind_fast(CsBasicStringView str, const_iterator iter_end)
const;
125 value_type front()
const;
126 size_type length()
const;
128 size_type size()
const;
129 bool startsWith(CsBasicStringView str)
const;
131 CsBasicStringView<S> remove_prefix(size_type size)
const;
132 CsBasicStringView<S> remove_suffix(size_type size)
const;
134 CsBasicStringView<S> substr(size_type indexStart = 0, size_type size = npos)
const;
135 void swap(CsBasicStringView &str);
142 const_iterator begin()
const {
146 const_iterator cbegin()
const {
150 const_iterator constBegin()
const {
158 const_iterator end()
const {
162 const_iterator cend()
const {
166 const_iterator constEnd()
const {
170 reverse_iterator rbegin() {
174 const_reverse_iterator rbegin()
const {
178 reverse_iterator rend() {
182 const_reverse_iterator rend()
const {
186 const_reverse_iterator crbegin()
const {
190 const_reverse_iterator crend()
const {
196 const_storage_iterator storage_begin()
const{
197 return m_begin.codePointBegin();
200 const_storage_iterator storage_end()
const {
201 return m_end.codePointBegin();
204 const_storage_reverse_iterator storage_rbegin()
const {
205 return std::make_reverse_iterator(m_end.codePointBegin());
208 const_storage_reverse_iterator storage_rend()
const {
209 return std::make_reverse_iterator(m_begin.codePointBegin());
213 const_iterator m_begin;
214 const_iterator m_end;
218 template <
typename S>
219 inline bool operator==(CsBasicStringView<S> &str1, CsBasicStringView<S> &str2)
221 return str1.compare(str2) == 0;
224 template <
typename S>
225 inline bool operator!=(CsBasicStringView<S> &str1, CsBasicStringView<S> &str2)
227 return str1.compare(str2) != 0;
230 template <
typename S>
231 inline bool operator<(CsBasicStringView<S> &str1, CsBasicStringView<S> &str2)
233 return str1.compare(str2) < 0;
236 template <
typename S>
237 inline bool operator>(CsBasicStringView<S> &str1, CsBasicStringView<S> &str2)
239 return str1.compare(str2) > 0;
242 template <
typename S>
243 inline bool operator<=(CsBasicStringView<S> &str1, CsBasicStringView<S> &str2)
245 return str1.compare(str2) <= 0;
248 template <
typename S>
249 inline bool operator>=(CsBasicStringView<S> &str1, CsBasicStringView<S> &str2)
251 return str1.compare(str2) >= 0;
255 template <
typename S>
256 typename CsBasicStringView<S>::value_type CsBasicStringView<S>::operator[](size_type index)
const
258 const_iterator iter = cbegin();
259 std::advance(iter, index);
265 template <
typename S>
266 typename CsBasicStringView<S>::value_type CsBasicStringView<S>::at(size_type index)
const
268 const_iterator iter = cbegin();
269 std::advance(iter, index);
274 template <
typename S>
275 typename CsBasicStringView<S>::value_type CsBasicStringView<S>::back()
const
280 template <
typename S>
281 int CsBasicStringView<S>::compare(CsBasicStringView str)
const
283 auto iter_a = cbegin();
284 auto iter_b = str.cbegin();
286 while (iter_a != cend() && iter_b != str.cend()) {
288 auto value_a = *iter_a;
289 auto value_b = *iter_b;
291 if (value_a < value_b) {
294 }
else if (value_a > value_b) {
303 if (iter_b != str.cend()) {
306 }
else if (iter_a != cend()) {
314 template <
typename S>
315 bool CsBasicStringView<S>::empty()
const
317 return (m_begin == m_end);
320 template <
typename S>
321 bool CsBasicStringView<S>::endsWith(CsBasicStringView<S> str)
const
326 }
else if (empty()) {
330 auto iter = crbegin();
332 for (
auto iter_other = str.crbegin(); iter_other != str.crend(); ++iter_other) {
334 if (iter == crend()) {
338 if (*iter != *iter_other) {
348 template <
typename S>
349 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(CsBasicStringView str)
const
351 return find_fast(str, cbegin());
354 template <
typename S>
355 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(CsBasicStringView str,
356 const_iterator iter_begin)
const
358 const_iterator iter_end = cend();
360 if (iter_begin == iter_end) {
368 auto iter = iter_begin;
370 while (iter != iter_end) {
372 if (*iter == str[0]) {
373 auto text_iter = iter + 1;
374 auto pattern_iter = str.cbegin() + 1;
376 while (text_iter != iter_end && pattern_iter != str.cend()) {
378 if (*text_iter == *pattern_iter) {
388 if (pattern_iter == str.cend()) {
401 template <
typename S>
402 template <
typename T,
typename>
403 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(
const T &str, const_iterator iter_begin,
404 size_type size)
const
406 #ifndef CS_STRING_ALLOW_UNSAFE
407 static_assert(! std::is_same<T, T>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
410 const_iterator iter_end = cend();
412 if (iter_begin == iter_end) {
416 if (str ==
nullptr || str[0] == 0) {
420 auto iter = iter_begin;
422 while (iter != iter_end) {
424 if (*iter == str[0]) {
425 auto text_iter = iter + 1;
426 auto pattern_iter = str + 1;
430 while (text_iter != iter_end && *pattern_iter != 0 && count < size) {
432 if (*text_iter == *pattern_iter) {
444 if (*pattern_iter == 0) {
457 template <
typename S>
459 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(
const char (&str)[N],
460 const_iterator iter_begin, size_type size)
const
463 return find_fast(S::fromUtf8(str, size), iter_begin);
467 template <
typename S>
468 template <
typename T,
typename>
469 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(
const T &str)
const
471 return find_fast(str, cbegin());
475 template <
typename S>
476 template <
typename T,
typename>
477 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(
const T &str, const_iterator iter_begin)
const
479 #ifndef CS_STRING_ALLOW_UNSAFE
480 static_assert(! std::is_same<T, T>::value,
"Unsafe operations not allowed, unknown encoding for this operation");
483 const_iterator iter_end = cend();
485 if (iter_begin == iter_end) {
489 if (str ==
nullptr || str[0] == 0) {
493 auto iter = iter_begin;
495 while (iter != iter_end) {
497 if (*iter == str[0]) {
498 auto text_iter = iter + 1;
499 auto pattern_iter = str + 1;
501 while (text_iter != iter_end && *pattern_iter != 0) {
503 if (*text_iter == *pattern_iter) {
513 if (*pattern_iter == 0) {
526 template <
typename S>
528 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(
const char (&str)[N])
const
530 return find_fast(str, cbegin());
534 template <
typename S>
536 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(
const char (&str)[N],
537 const_iterator iter_begin)
const
540 return find_fast(S::fromUtf8(str, N - 1), iter_begin);
543 template <
typename S>
544 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(value_type c)
const
546 return find_fast(c, cbegin());
549 template <
typename S>
550 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::find_fast(value_type c, const_iterator iter_begin)
const
552 const_iterator iter_end = cend();
554 if (iter_begin == iter_end) {
558 auto iter = iter_begin;
560 while (iter != iter_end) {
572 template <
typename S>
573 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::rfind_fast(value_type c)
const
575 return rfind_fast(c, cend());
578 template <
typename S>
579 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::rfind_fast(value_type c, const_iterator iter_end)
const
581 const_iterator iter_begin = cbegin();
583 if (iter_begin == iter_end) {
587 auto iter = iter_end;
589 while (iter != cbegin()) {
601 template <
typename S>
602 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::rfind_fast(CsBasicStringView str)
const
604 return rfind_fast(str, cend());
607 template <
typename S>
608 typename CsBasicStringView<S>::const_iterator CsBasicStringView<S>::rfind_fast(CsBasicStringView str, const_iterator iter_end)
const
610 const_iterator iter_begin = cbegin();
612 if (iter_begin == iter_end) {
620 auto iter = iter_end;
621 auto str_end = str.cend();
623 while (iter != cbegin()) {
626 if (*iter == str[0]) {
628 auto text_iter = iter + 1;
629 auto pattern_iter = str.cbegin() + 1;
631 while (text_iter != cend() && pattern_iter != str_end) {
633 if (*text_iter == *pattern_iter) {
643 if (pattern_iter == str_end) {
654 template <
typename S>
655 typename CsBasicStringView<S>::value_type CsBasicStringView<S>::front()
const
660 template <
typename S>
661 auto CsBasicStringView<S>::length()
const -> size_type
666 template <
typename S>
667 bool CsBasicStringView<S>::startsWith(CsBasicStringView<S> str)
const
672 }
else if (empty()) {
677 auto iter = cbegin();
679 for (
auto uc : str) {
681 if (iter == cend()) {
695 template <
typename S>
696 auto CsBasicStringView<S>::size()
const -> size_type
698 size_type retval = 0;
700 for (
auto item = cbegin(); item != cend(); ++item) {
707 template <
typename S>
708 CsBasicStringView<S> CsBasicStringView<S>::remove_prefix(size_type size)
const
710 const_iterator iter_begin = cbegin();
712 for (size_type i = 0; i < size && iter_begin != cend(); ++i) {
716 if (iter_begin == cend()) {
718 return CsBasicStringView();
721 return CsBasicStringView(iter_begin, cend());
724 template <
typename S>
725 CsBasicStringView<S> CsBasicStringView<S>::remove_suffix(size_type size)
const
727 const_iterator iter_end = cend();
729 for (size_type i = 0; i < size && iter_end != cbegin(); ++i) {
733 return CsBasicStringView(cbegin(), iter_end);
736 template <
typename S>
737 CsBasicStringView<S> CsBasicStringView<S>::substr(size_type indexStart, size_type size)
const
739 const_iterator iter_begin = cbegin();
740 const_iterator iter_end;
742 for (size_type i = 0; i < indexStart && iter_begin != cend(); ++i) {
746 if (iter_begin == cend()) {
748 return CsBasicStringView();
752 iter_end = iter_begin;
754 for (size_type i = 0; i < size && iter_end != cend(); ++i) {
763 return CsBasicStringView(iter_begin, iter_end);
766 template <
typename S>
767 void CsBasicStringView<S>::swap(CsBasicStringView &str)
769 swap(m_begin, str.m_begin);
770 swap(m_end, str.m_end);