Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.0
StringView.h
Go to the documentation of this file.
1 #ifndef ZSERIO_STRING_VIEW_H_INC
2 #define ZSERIO_STRING_VIEW_H_INC
3 
4 #include <cstddef>
5 #include <algorithm>
6 #include <utility>
7 #include <memory>
8 #include <limits>
9 
11 #include "zserio/String.h"
13 #include "zserio/RebindAlloc.h"
14 
15 namespace zserio
16 {
17 
22 template <typename CharT, typename Traits = std::char_traits<CharT>>
24 {
25 public:
26  using traits_type = Traits;
27  using value_type = CharT;
28  using pointer = CharT*;
29  using const_pointer = const CharT*;
30  using reference = CharT&;
31  using const_reference = const CharT&;
34  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
36  using size_type = size_t;
37  using difference_type = ptrdiff_t;
38 
42  static constexpr const size_type npos = static_cast<size_type>(-1);
43 
47  constexpr BasicStringView() noexcept = default;
48 
54  BasicStringView(const const_pointer str) noexcept :
55  m_data(str), m_size(Traits::length(str))
56  {}
57 
64  constexpr BasicStringView(const const_pointer str, const size_type count) noexcept :
65  m_data(str), m_size(count)
66  {}
67 
73  template<typename ALLOC>
74  constexpr BasicStringView(const std::basic_string<CharT, Traits, ALLOC>& str) noexcept :
75  m_data(str.data()), m_size(str.size())
76  {}
77 
82  ~BasicStringView() = default;
83 
84  BasicStringView(const BasicStringView&) noexcept = default;
85  BasicStringView& operator=(const BasicStringView&) noexcept = default;
86 
87  BasicStringView(BasicStringView&&) noexcept = default;
88  BasicStringView& operator=(BasicStringView&&) noexcept = default;
98  constexpr const_iterator begin() const noexcept
99  {
100  return m_data;
101  }
102 
108  constexpr const_iterator cbegin() const noexcept
109  {
110  return begin();
111  }
112 
118  constexpr const_iterator end() const noexcept
119  {
120  return m_data + m_size;
121  }
122 
128  constexpr const_iterator cend() const noexcept
129  {
130  return end();
131  }
132 
138  constexpr const_reverse_iterator rbegin() const noexcept
139  {
140  return const_reverse_iterator(end());
141  }
142 
148  constexpr const_reverse_iterator crbegin() const noexcept
149  {
150  return rbegin();
151  }
152 
158  constexpr const_reverse_iterator rend() const noexcept
159  {
160  return const_reverse_iterator(begin());
161  }
162 
168  constexpr const_reverse_iterator crend() const noexcept
169  {
170  return rend();
171  }
172 
179  constexpr const_reference operator[](const size_type pos) const noexcept
180  {
181  return m_data[pos];
182  }
183 
192  const_reference at(const size_type pos) const
193  {
194  if (pos >= size())
195  {
196  throw CppRuntimeException("StringView: Position ") << pos << " out of range for view size "
197  << size() << "!";
198  }
199  return m_data[pos];
200  }
201 
207  constexpr const_reference front() const noexcept
208  {
209  return m_data[0];
210  }
211 
217  constexpr const_reference back() const noexcept
218  {
219  return m_data[m_size - 1];
220  }
221 
227  constexpr const_pointer data() const noexcept
228  {
229  return m_data;
230  }
231 
237  constexpr size_type size() const noexcept
238  {
239  return m_size;
240  }
241 
247  constexpr size_type length() const noexcept
248  {
249  return size();
250  }
251 
257  constexpr size_type max_size() const noexcept
258  {
259  return std::numeric_limits<size_type>::max();
260  }
261 
267  constexpr bool empty() const noexcept
268  {
269  return size() == 0;
270  }
271 
278  {
279  m_data += n;
280  m_size -= n;
281  }
282 
289  {
290  m_size -= n;
291  }
292 
298  void swap(BasicStringView& other) noexcept
299  {
300  std::swap(m_data, other.m_data);
301  std::swap(m_size, other.m_size);
302  }
303 
314  size_type copy(CharT* dest, size_type count, size_type pos = 0) const
315  {
316  if (pos > size())
317  {
318  throw CppRuntimeException("StringView: Position ") << pos << " out of range for view size " <<
319  size() << "!";
320  }
321  const size_t rcount = std::min(count, size() - pos);
322  Traits::copy(dest, data() + pos, rcount);
323  return rcount;
324  }
325 
335  BasicStringView substr(size_type pos = 0, size_type count = npos) const
336  {
337  if (pos > size())
338  {
339  throw CppRuntimeException("StringView: Position ") << pos << " out of range for view size " <<
340  size() << "!";
341  }
342  const size_t rcount = std::min(count, size() - pos);
343  return BasicStringView(m_data + pos, rcount);
344  }
345 
353  int compare(BasicStringView other) const noexcept
354  {
355  const size_type rlen = std::min(size(), other.size());
356  const int cmp = Traits::compare(data(), other.data(), rlen);
357 
358  if (cmp != 0)
359  return cmp;
360 
361  if (size() < other.size())
362  return -1;
363  else if (size() > other.size())
364  return 1;
365  else
366  return 0;
367  }
368 
378  int compare(size_type pos1, size_type count1, BasicStringView other) const
379  {
380  return substr(pos1, count1).compare(other);
381  }
382 
394  int compare(size_type pos1, size_type count1, BasicStringView other, size_type pos2, size_type count2) const
395  {
396  return substr(pos1, count1).compare(other.substr(pos2, count2));
397  }
398 
406  int compare(const CharT* str) const
407  {
408  return compare(BasicStringView(str));
409  }
410 
420  int compare(size_type pos1, size_type count1, const CharT* str) const
421  {
422  return substr(pos1, count1).compare(BasicStringView(str));
423  }
424 
435  int compare(size_type pos1, size_type count1, const CharT* str, size_type count2) const
436  {
437  return substr(pos1, count1).compare(BasicStringView(str, count2));
438  }
439 
447  size_type find(BasicStringView str, size_type pos = 0) const noexcept
448  {
449  if (pos >= size() || str.size() > size() - pos)
450  return npos; // the string cannot be there
451 
452  if (str.size() == 0)
453  return pos; // zero-sized search, this defaults to the match at the beginning
454 
455  const const_pointer startPtr = data() + pos; // where the searching will start
456  const const_pointer endPtr = data() + (size() - str.size()) + 1; // where the searching will end
457 
458  // initial position
459  const_pointer ptr = Traits::find(startPtr, static_cast<size_t>(endPtr - startPtr), str[0]);
460  while (ptr)
461  {
462  // check if the searched string is present
463  if (Traits::compare(ptr, str.data(), str.size()) == 0)
464  {
465  return static_cast<size_t>(ptr - data());
466  }
467 
468  // go to next position
469  ptr = Traits::find(ptr + 1, static_cast<size_t>(endPtr - ptr - 1), str[0]);
470  }
471 
472  return npos;
473  }
474 
482  size_type find(CharT ch, size_type pos = 0) const noexcept
483  {
484  return find(BasicStringView(std::addressof(ch), 1), pos);
485  }
486 
495  size_type find(const CharT* str, size_type pos, size_type count) const
496  {
497  return find(BasicStringView(str, count), pos);
498  }
499 
507  size_type find(const CharT* str, size_type pos = 0) const
508  {
509  return find(BasicStringView(str), pos);
510  }
511 
519  size_type rfind(BasicStringView str, size_type pos = npos) const noexcept
520  {
521  if (str.size() > size())
522  return npos;
523 
524  for (size_t p = std::min(static_cast<size_type>(size() - str.size()), pos) + 1; p > 0; --p)
525  {
526  if (Traits::compare(data() + p - 1, str.data(), str.size()) == 0)
527  return p - 1;
528  }
529 
530  return npos;
531  }
532 
540  size_type rfind(CharT ch, size_type pos = npos) const noexcept
541  {
542  return rfind(BasicStringView(std::addressof(ch), 1), pos);
543  }
544 
552  size_type rfind(const CharT* str, size_type pos, size_type count) const
553  {
554  return rfind(BasicStringView(str, count), pos);
555  }
556 
564  size_type rfind(const CharT* str, size_type pos = npos) const
565  {
566  return rfind(BasicStringView(str), pos);
567  }
568 
576  size_type find_first_of(BasicStringView str, size_type pos = 0) const noexcept
577  {
578  if (str.size() == 0 || pos >= size())
579  return npos;
580 
581  for (size_type idx = pos; idx < size(); ++idx)
582  {
583  if (Traits::find(str.data(), str.size(), data()[idx]) != nullptr)
584  return idx;
585  }
586 
587  return npos;
588  }
589 
597  size_type find_first_of(CharT ch, size_type pos = 0) const noexcept
598  {
599  return find_first_of(BasicStringView(std::addressof(ch), 1), pos);
600  }
601 
610  size_type find_first_of(const CharT* str, size_type pos, size_type count) const
611  {
612  return find_first_of(BasicStringView(str, count), pos);
613  }
614 
622  size_type find_first_of(const CharT* str, size_type pos = 0) const
623  {
624  return find_first_of(BasicStringView(str), pos);
625  }
626 
634  size_type find_last_of(BasicStringView str, size_type pos = npos) const noexcept
635  {
636  if (str.empty() || empty())
637  return npos;
638 
639  for (size_type idx = std::min(pos + 1, size()); idx > 0; --idx)
640  {
641  if (Traits::find(str.data(), str.size(), data()[idx - 1]) != nullptr)
642  return idx - 1;
643  }
644 
645  return npos;
646  }
647 
655  size_type find_last_of(CharT ch, size_type pos = npos) const noexcept
656  {
657  return find_last_of(BasicStringView(std::addressof(ch), 1), pos);
658  }
659 
668  size_type find_last_of(const CharT* str, size_type pos, size_type count) const
669  {
670  return find_last_of(BasicStringView(str, count), pos);
671  }
672 
680  size_type find_last_of(const CharT* str, size_type pos = npos) const
681  {
682  return find_last_of(BasicStringView(str), pos);
683  }
684 
693  {
694  if (str.size() == 0 || pos >= size())
695  return npos;
696 
697  for (size_type idx = pos; idx < size(); ++idx)
698  {
699  if (Traits::find(str.data(), str.size(), data()[idx]) == nullptr)
700  return idx;
701  }
702 
703  return npos;
704  }
705 
713  size_type find_first_not_of(CharT ch, size_type pos = 0) const noexcept
714  {
715  return find_first_not_of(BasicStringView(std::addressof(ch), 1), pos);
716  }
717 
726  size_type find_first_not_of(const CharT* str, size_type pos, size_type count) const
727  {
728  return find_first_not_of(BasicStringView(str, count), pos);
729  }
730 
738  size_type find_first_not_of(const CharT* str, size_type pos = 0) const
739  {
740  return find_first_not_of(BasicStringView(str), pos);
741  }
742 
750  size_type find_last_not_of(BasicStringView str, size_type pos = npos) const noexcept
751  {
752  if (str.empty() || empty())
753  return npos;
754 
755  for (size_type idx = std::min(pos + 1, size()); idx > 0; --idx)
756  {
757  if (Traits::find(str.data(), str.size(), data()[idx - 1]) == nullptr)
758  return idx - 1;
759  }
760 
761  return npos;
762  }
763 
771  size_type find_last_not_of(CharT ch, size_type pos = npos) const noexcept
772  {
773  return find_last_not_of(BasicStringView(std::addressof(ch), 1), pos);
774  }
775 
784  size_type find_last_not_of(const CharT* str, size_type pos, size_type count) const
785  {
786  return find_last_not_of(BasicStringView(str, count), pos);
787  }
788 
796  size_type find_last_not_of(const CharT* str, size_type pos = npos) const
797  {
798  return find_last_not_of(BasicStringView(str), pos);
799  }
800 
801 private:
802  const_pointer m_data = nullptr;
803  size_type m_size = 0;
804 };
805 
806 template<typename CharT, class Traits>
807 constexpr std::size_t const BasicStringView<CharT, Traits>::npos;
808 
816 template<typename CharT, class Traits>
818 {
819  return lhs.compare(rhs) == 0;
820 }
821 
829 template<typename CharT, class Traits>
831 {
832  return lhs.compare(rhs) != 0;
833 }
834 
842 template<typename CharT, class Traits>
843 constexpr bool operator<(BasicStringView<CharT, Traits> lhs, BasicStringView<CharT, Traits> rhs) noexcept
844 {
845  return lhs.compare(rhs) < 0;
846 }
847 
855 template<typename CharT, class Traits>
856 constexpr bool operator<=(BasicStringView<CharT, Traits> lhs, BasicStringView<CharT, Traits> rhs) noexcept
857 {
858  return lhs.compare(rhs) <= 0;
859 }
860 
868 template<typename CharT, class Traits>
870 {
871  return lhs.compare(rhs) > 0;
872 }
873 
881 template<typename CharT, class Traits>
883 {
884  return lhs.compare(rhs) >= 0;
885 }
886 
893 template<typename CharT, size_t N>
894 constexpr BasicStringView<CharT> makeStringView(const CharT(&str)[N])
895 {
896  static_assert(N != 0, "Zero length arrays C++ extension is not supported!");
897  return BasicStringView<CharT>(str, str[N - 1] == CharT() ? (N - 1) : N);
898 }
899 
908 template<typename CharT, typename Traits, typename ALLOC = std::allocator<char>>
909 std::basic_string<CharT, Traits, RebindAlloc<ALLOC, CharT>> stringViewToString(
910  BasicStringView<CharT, Traits> stringView, const ALLOC& allocator = ALLOC())
911 {
912  return std::basic_string<CharT, Traits, RebindAlloc<ALLOC, CharT>>(stringView.data(), stringView.size(),
913  allocator);
914 }
915 
923 template<typename CharT, typename Traits, typename ALLOC = std::allocator<char>>
924 std::basic_string<CharT, Traits, ALLOC>& operator+=(
925  std::basic_string<CharT, Traits, ALLOC>& first, BasicStringView<CharT, Traits> second)
926 {
927  return first.append(second.data(), second.size());
928 }
929 
934 
941 template <typename ALLOC>
942 string<ALLOC> toString(StringView value, const ALLOC& allocator = ALLOC())
943 {
944  return stringViewToString(value, allocator);
945 }
946 
956 {
957  exception.append(view.data(), view.size());
958  return exception;
959 }
960 
961 inline namespace literals
962 {
963 
968 operator"" _sv(const char* str, std::size_t len) noexcept
969 {
970  return ::zserio::StringView(str, len);
971 }
972 
973 } // inline namespace literals
974 
975 } // namespace zserio
976 
977 #endif // ZSERIO_STRING_VIEW_H_INC
constexpr BasicStringView() noexcept=default
constexpr BasicStringView< CharT > makeStringView(const CharT(&str)[N])
Definition: StringView.h:894
void swap(BasicStringView &other) noexcept
Definition: StringView.h:298
constexpr size_type length() const noexcept
Definition: StringView.h:247
constexpr size_type size() const noexcept
Definition: StringView.h:237
size_type find_first_of(CharT ch, size_type pos=0) const noexcept
Definition: StringView.h:597
constexpr const_reverse_iterator rend() const noexcept
Definition: StringView.h:158
BasicStringView & operator=(const BasicStringView &) noexcept=default
constexpr const_iterator cend() const noexcept
Definition: StringView.h:128
void remove_prefix(size_type n)
Definition: StringView.h:277
size_type find_last_of(CharT ch, size_type pos=npos) const noexcept
Definition: StringView.h:655
size_type rfind(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:552
constexpr const_pointer data() const noexcept
Definition: StringView.h:227
constexpr const_reverse_iterator crbegin() const noexcept
Definition: StringView.h:148
std::basic_string< CharT, Traits, RebindAlloc< ALLOC, CharT > > stringViewToString(BasicStringView< CharT, Traits > stringView, const ALLOC &allocator=ALLOC())
Definition: StringView.h:909
const CharT & const_reference
Definition: StringView.h:31
size_type find_last_not_of(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:750
size_type find(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:447
constexpr const_reference back() const noexcept
Definition: StringView.h:217
constexpr BasicStringView(const std::basic_string< CharT, Traits, ALLOC > &str) noexcept
Definition: StringView.h:74
string< ALLOC > toString(T value, const ALLOC &allocator=ALLOC())
size_type find_last_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:668
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: StringView.h:34
ptrdiff_t difference_type
Definition: StringView.h:37
int compare(BasicStringView other) const noexcept
Definition: StringView.h:353
constexpr const_reference operator[](const size_type pos) const noexcept
Definition: StringView.h:179
size_type find_first_of(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:576
size_type find_first_not_of(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:692
size_type find_last_not_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:784
size_type find_first_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:610
size_type find(const CharT *str, size_type pos=0) const
Definition: StringView.h:507
std::basic_string< CharT, Traits, ALLOC > & operator+=(std::basic_string< CharT, Traits, ALLOC > &first, BasicStringView< CharT, Traits > second)
Definition: StringView.h:924
size_type rfind(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:519
constexpr bool operator!=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:830
const_iterator iterator
Definition: StringView.h:33
constexpr const_iterator end() const noexcept
Definition: StringView.h:118
const_pointer const_iterator
Definition: StringView.h:32
size_type rfind(CharT ch, size_type pos=npos) const noexcept
Definition: StringView.h:540
constexpr bool operator>(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:869
int compare(size_type pos1, size_type count1, const CharT *str, size_type count2) const
Definition: StringView.h:435
constexpr bool operator==(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:817
const_reference at(const size_type pos) const
Definition: StringView.h:192
size_type find_last_not_of(CharT ch, size_type pos=npos) const noexcept
Definition: StringView.h:771
size_type rfind(const CharT *str, size_type pos=npos) const
Definition: StringView.h:564
size_type find_first_not_of(CharT ch, size_type pos=0) const noexcept
Definition: StringView.h:713
size_type find_last_of(const CharT *str, size_type pos=npos) const
Definition: StringView.h:680
constexpr bool operator>=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:882
int compare(size_type pos1, size_type count1, BasicStringView other, size_type pos2, size_type count2) const
Definition: StringView.h:394
constexpr BasicStringView(const const_pointer str, const size_type count) noexcept
Definition: StringView.h:64
size_type find_last_not_of(const CharT *str, size_type pos=npos) const
Definition: StringView.h:796
constexpr const_reverse_iterator crend() const noexcept
Definition: StringView.h:168
const CharT * const_pointer
Definition: StringView.h:29
constexpr const_iterator cbegin() const noexcept
Definition: StringView.h:108
BasicStringView< char, std::char_traits< char >> StringView
Definition: StringView.h:933
size_type find_last_of(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:634
BasicStringView substr(size_type pos=0, size_type count=npos) const
Definition: StringView.h:335
void append(const char *message)
static constexpr const size_type npos
Definition: StringView.h:42
constexpr const_iterator begin() const noexcept
Definition: StringView.h:98
const_reverse_iterator reverse_iterator
Definition: StringView.h:35
int compare(const CharT *str) const
Definition: StringView.h:406
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char >> string
Definition: String.h:16
constexpr const_reverse_iterator rbegin() const noexcept
Definition: StringView.h:138
void remove_suffix(size_type n)
Definition: StringView.h:288
constexpr const_reference front() const noexcept
Definition: StringView.h:207
constexpr bool empty() const noexcept
Definition: StringView.h:267
size_type find_first_not_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:726
size_type copy(CharT *dest, size_type count, size_type pos=0) const
Definition: StringView.h:314
size_type find(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:495
size_type find(CharT ch, size_type pos=0) const noexcept
Definition: StringView.h:482
size_type find_first_of(const CharT *str, size_type pos=0) const
Definition: StringView.h:622
int compare(size_type pos1, size_type count1, BasicStringView other) const
Definition: StringView.h:378
constexpr size_type max_size() const noexcept
Definition: StringView.h:257
size_type find_first_not_of(const CharT *str, size_type pos=0) const
Definition: StringView.h:738
CppRuntimeException & operator<<(CppRuntimeException &exception, const BasicBitBuffer< ALLOC > &bitBuffer)
Definition: BitBuffer.h:432
int compare(size_type pos1, size_type count1, const CharT *str) const
Definition: StringView.h:420