Zserio C++ runtime library  1.0.1
Built for Zserio 2.14.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 <algorithm>
5 #include <cstddef>
6 #include <limits>
7 #include <memory>
8 #include <utility>
9 
11 #include "zserio/RebindAlloc.h"
12 #include "zserio/String.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),
56  m_size(Traits::length(str))
57  {}
58 
65  constexpr BasicStringView(const const_pointer str, const size_type count) noexcept :
66  m_data(str),
67  m_size(count)
68  {}
69 
75  template <typename ALLOC>
76  constexpr BasicStringView(const std::basic_string<CharT, Traits, ALLOC>& str) noexcept :
77  m_data(str.data()),
78  m_size(str.size())
79  {}
80 
85  ~BasicStringView() = default;
86 
87  BasicStringView(const BasicStringView&) noexcept = default;
88  BasicStringView& operator=(const BasicStringView&) noexcept = default;
89 
90  BasicStringView(BasicStringView&&) noexcept = default;
91  BasicStringView& operator=(BasicStringView&&) noexcept = default;
101  constexpr const_iterator begin() const noexcept
102  {
103  return m_data;
104  }
105 
111  constexpr const_iterator cbegin() const noexcept
112  {
113  return begin();
114  }
115 
121  constexpr const_iterator end() const noexcept
122  {
123  return m_data + m_size;
124  }
125 
131  constexpr const_iterator cend() const noexcept
132  {
133  return end();
134  }
135 
141  constexpr const_reverse_iterator rbegin() const noexcept
142  {
143  return const_reverse_iterator(end());
144  }
145 
151  constexpr const_reverse_iterator crbegin() const noexcept
152  {
153  return rbegin();
154  }
155 
161  constexpr const_reverse_iterator rend() const noexcept
162  {
163  return const_reverse_iterator(begin());
164  }
165 
171  constexpr const_reverse_iterator crend() const noexcept
172  {
173  return rend();
174  }
175 
182  constexpr const_reference operator[](const size_type pos) const noexcept
183  {
184  return m_data[pos];
185  }
186 
195  const_reference at(const size_type pos) const
196  {
197  if (pos >= size())
198  {
199  throw CppRuntimeException("StringView: Position ")
200  << pos << " out of range for view size " << size() << "!";
201  }
202  return m_data[pos];
203  }
204 
210  constexpr const_reference front() const noexcept
211  {
212  return m_data[0];
213  }
214 
220  constexpr const_reference back() const noexcept
221  {
222  return m_data[m_size - 1];
223  }
224 
230  constexpr const_pointer data() const noexcept
231  {
232  return m_data;
233  }
234 
240  constexpr size_type size() const noexcept
241  {
242  return m_size;
243  }
244 
250  constexpr size_type length() const noexcept
251  {
252  return size();
253  }
254 
260  constexpr size_type max_size() const noexcept
261  {
262  return std::numeric_limits<size_type>::max();
263  }
264 
270  constexpr bool empty() const noexcept
271  {
272  return size() == 0;
273  }
274 
281  {
282  m_data += n;
283  m_size -= n;
284  }
285 
292  {
293  m_size -= n;
294  }
295 
301  void swap(BasicStringView& other) noexcept
302  {
303  std::swap(m_data, other.m_data);
304  std::swap(m_size, other.m_size);
305  }
306 
317  size_type copy(CharT* dest, size_type count, size_type pos = 0) const
318  {
319  if (pos > size())
320  {
321  throw CppRuntimeException("StringView: Position ")
322  << pos << " out of range for view size " << size() << "!";
323  }
324  const size_t rcount = std::min(count, size() - pos);
325  Traits::copy(dest, data() + pos, rcount);
326  return rcount;
327  }
328 
339  {
340  if (pos > size())
341  {
342  throw CppRuntimeException("StringView: Position ")
343  << pos << " out of range for view size " << size() << "!";
344  }
345  const size_t rcount = std::min(count, size() - pos);
346  return BasicStringView(m_data + pos, rcount);
347  }
348 
356  int compare(BasicStringView other) const noexcept
357  {
358  const size_type rlen = std::min(size(), other.size());
359  const int cmp = Traits::compare(data(), other.data(), rlen);
360 
361  if (cmp != 0)
362  return cmp;
363 
364  if (size() < other.size())
365  return -1;
366  else if (size() > other.size())
367  return 1;
368  else
369  return 0;
370  }
371 
381  int compare(size_type pos1, size_type count1, BasicStringView other) const
382  {
383  return substr(pos1, count1).compare(other);
384  }
385 
397  int compare(size_type pos1, size_type count1, BasicStringView other, size_type pos2, size_type count2) const
398  {
399  return substr(pos1, count1).compare(other.substr(pos2, count2));
400  }
401 
409  int compare(const CharT* str) const
410  {
411  return compare(BasicStringView(str));
412  }
413 
423  int compare(size_type pos1, size_type count1, const CharT* str) const
424  {
425  return substr(pos1, count1).compare(BasicStringView(str));
426  }
427 
438  int compare(size_type pos1, size_type count1, const CharT* str, size_type count2) const
439  {
440  return substr(pos1, count1).compare(BasicStringView(str, count2));
441  }
442 
450  size_type find(BasicStringView str, size_type pos = 0) const noexcept
451  {
452  if (pos >= size() || str.size() > size() - pos)
453  return npos; // the string cannot be there
454 
455  if (str.size() == 0)
456  return pos; // zero-sized search, this defaults to the match at the beginning
457 
458  const const_pointer startPtr = data() + pos; // where the searching will start
459  const const_pointer endPtr = data() + (size() - str.size()) + 1; // where the searching will end
460 
461  // initial position
462  const_pointer ptr = Traits::find(startPtr, static_cast<size_t>(endPtr - startPtr), str[0]);
463  while (ptr)
464  {
465  // check if the searched string is present
466  if (Traits::compare(ptr, str.data(), str.size()) == 0)
467  {
468  return static_cast<size_t>(ptr - data());
469  }
470 
471  // go to next position
472  ptr = Traits::find(ptr + 1, static_cast<size_t>(endPtr - ptr - 1), str[0]);
473  }
474 
475  return npos;
476  }
477 
485  size_type find(CharT character, size_type pos = 0) const noexcept
486  {
487  return find(BasicStringView(std::addressof(character), 1), pos);
488  }
489 
498  size_type find(const CharT* str, size_type pos, size_type count) const
499  {
500  return find(BasicStringView(str, count), pos);
501  }
502 
510  size_type find(const CharT* str, size_type pos = 0) const
511  {
512  return find(BasicStringView(str), pos);
513  }
514 
522  size_type rfind(BasicStringView str, size_type pos = npos) const noexcept
523  {
524  if (str.size() > size())
525  return npos;
526 
527  for (size_t p = std::min(static_cast<size_type>(size() - str.size()), pos) + 1; p > 0; --p)
528  {
529  if (Traits::compare(data() + p - 1, str.data(), str.size()) == 0)
530  return p - 1;
531  }
532 
533  return npos;
534  }
535 
543  size_type rfind(CharT character, size_type pos = npos) const noexcept
544  {
545  return rfind(BasicStringView(std::addressof(character), 1), pos);
546  }
547 
555  size_type rfind(const CharT* str, size_type pos, size_type count) const
556  {
557  return rfind(BasicStringView(str, count), pos);
558  }
559 
567  size_type rfind(const CharT* str, size_type pos = npos) const
568  {
569  return rfind(BasicStringView(str), pos);
570  }
571 
579  size_type find_first_of(BasicStringView str, size_type pos = 0) const noexcept
580  {
581  if (str.size() == 0 || pos >= size())
582  return npos;
583 
584  for (size_type idx = pos; idx < size(); ++idx)
585  {
586  if (Traits::find(str.data(), str.size(), data()[idx]) != nullptr)
587  return idx;
588  }
589 
590  return npos;
591  }
592 
600  size_type find_first_of(CharT character, size_type pos = 0) const noexcept
601  {
602  return find_first_of(BasicStringView(std::addressof(character), 1), pos);
603  }
604 
613  size_type find_first_of(const CharT* str, size_type pos, size_type count) const
614  {
615  return find_first_of(BasicStringView(str, count), pos);
616  }
617 
625  size_type find_first_of(const CharT* str, size_type pos = 0) const
626  {
627  return find_first_of(BasicStringView(str), pos);
628  }
629 
638  {
639  if (str.empty() || empty())
640  return npos;
641 
642  for (size_type idx = std::min(pos + 1, size()); idx > 0; --idx)
643  {
644  if (Traits::find(str.data(), str.size(), data()[idx - 1]) != nullptr)
645  return idx - 1;
646  }
647 
648  return npos;
649  }
650 
658  size_type find_last_of(CharT character, size_type pos = npos) const noexcept
659  {
660  return find_last_of(BasicStringView(std::addressof(character), 1), pos);
661  }
662 
671  size_type find_last_of(const CharT* str, size_type pos, size_type count) const
672  {
673  return find_last_of(BasicStringView(str, count), pos);
674  }
675 
683  size_type find_last_of(const CharT* str, size_type pos = npos) const
684  {
685  return find_last_of(BasicStringView(str), pos);
686  }
687 
696  {
697  if (str.size() == 0 || pos >= size())
698  return npos;
699 
700  for (size_type idx = pos; idx < size(); ++idx)
701  {
702  if (Traits::find(str.data(), str.size(), data()[idx]) == nullptr)
703  return idx;
704  }
705 
706  return npos;
707  }
708 
716  size_type find_first_not_of(CharT character, size_type pos = 0) const noexcept
717  {
718  return find_first_not_of(BasicStringView(std::addressof(character), 1), pos);
719  }
720 
729  size_type find_first_not_of(const CharT* str, size_type pos, size_type count) const
730  {
731  return find_first_not_of(BasicStringView(str, count), pos);
732  }
733 
741  size_type find_first_not_of(const CharT* str, size_type pos = 0) const
742  {
743  return find_first_not_of(BasicStringView(str), pos);
744  }
745 
754  {
755  if (str.empty() || empty())
756  return npos;
757 
758  for (size_type idx = std::min(pos + 1, size()); idx > 0; --idx)
759  {
760  if (Traits::find(str.data(), str.size(), data()[idx - 1]) == nullptr)
761  return idx - 1;
762  }
763 
764  return npos;
765  }
766 
774  size_type find_last_not_of(CharT character, size_type pos = npos) const noexcept
775  {
776  return find_last_not_of(BasicStringView(std::addressof(character), 1), pos);
777  }
778 
787  size_type find_last_not_of(const CharT* str, size_type pos, size_type count) const
788  {
789  return find_last_not_of(BasicStringView(str, count), pos);
790  }
791 
799  size_type find_last_not_of(const CharT* str, size_type pos = npos) const
800  {
801  return find_last_not_of(BasicStringView(str), pos);
802  }
803 
804 private:
805  const_pointer m_data = nullptr;
806  size_type m_size = 0;
807 };
808 
809 template <typename CharT, class Traits>
810 constexpr std::size_t const BasicStringView<CharT, Traits>::npos;
811 
819 template <typename CharT, class Traits>
821 {
822  return lhs.compare(rhs) == 0;
823 }
824 
832 template <typename CharT, class Traits>
834 {
835  return lhs.compare(rhs) != 0;
836 }
837 
845 template <typename CharT, class Traits>
847 {
848  return lhs.compare(rhs) < 0;
849 }
850 
858 template <typename CharT, class Traits>
860 {
861  return lhs.compare(rhs) <= 0;
862 }
863 
871 template <typename CharT, class Traits>
873 {
874  return lhs.compare(rhs) > 0;
875 }
876 
884 template <typename CharT, class Traits>
886 {
887  return lhs.compare(rhs) >= 0;
888 }
889 
896 template <typename CharT, size_t N>
897 constexpr BasicStringView<CharT> makeStringView(const CharT (&str)[N])
898 {
899  static_assert(N != 0, "Zero length arrays C++ extension is not supported!");
900  return BasicStringView<CharT>(str, str[N - 1] == CharT() ? (N - 1) : N);
901 }
902 
911 template <typename CharT, typename Traits, typename ALLOC = std::allocator<char>>
912 std::basic_string<CharT, Traits, RebindAlloc<ALLOC, CharT>> stringViewToString(
913  BasicStringView<CharT, Traits> stringView, const ALLOC& allocator = ALLOC())
914 {
915  return std::basic_string<CharT, Traits, RebindAlloc<ALLOC, CharT>>(
916  stringView.data(), stringView.size(), allocator);
917 }
918 
926 template <typename CharT, typename Traits, typename ALLOC = std::allocator<char>>
927 std::basic_string<CharT, Traits, ALLOC>& operator+=(
928  std::basic_string<CharT, Traits, ALLOC>& first, BasicStringView<CharT, Traits> second)
929 {
930  return first.append(second.data(), second.size());
931 }
932 
937 
944 template <typename ALLOC>
945 string<ALLOC> toString(StringView value, const ALLOC& allocator = ALLOC())
946 {
947  return stringViewToString(value, allocator);
948 }
949 
959 {
960  exception.append(view.data(), view.size());
961  return exception;
962 }
963 
964 inline namespace literals
965 {
966 
970 constexpr ::zserio::StringView operator"" _sv(const char* str, std::size_t len) noexcept
971 {
972  return ::zserio::StringView(str, len);
973 }
974 
975 } // namespace literals
976 
977 } // namespace zserio
978 
979 #endif // ZSERIO_STRING_VIEW_H_INC
ptrdiff_t difference_type
Definition: StringView.h:37
size_type rfind(const CharT *str, size_type pos=npos) const
Definition: StringView.h:567
static constexpr const size_type npos
Definition: StringView.h:42
size_type find_last_of(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:637
size_type rfind(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:522
constexpr const_reverse_iterator rend() const noexcept
Definition: StringView.h:161
constexpr BasicStringView(const const_pointer str, const size_type count) noexcept
Definition: StringView.h:65
constexpr const_reverse_iterator crbegin() const noexcept
Definition: StringView.h:151
size_type find_last_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:671
constexpr const_reference front() const noexcept
Definition: StringView.h:210
constexpr size_type max_size() const noexcept
Definition: StringView.h:260
constexpr const_iterator cbegin() const noexcept
Definition: StringView.h:111
const CharT & const_reference
Definition: StringView.h:31
void remove_suffix(size_type n)
Definition: StringView.h:291
size_type rfind(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:555
BasicStringView(BasicStringView &&) noexcept=default
const CharT * const_pointer
Definition: StringView.h:29
constexpr const_reverse_iterator crend() const noexcept
Definition: StringView.h:171
size_type rfind(CharT character, size_type pos=npos) const noexcept
Definition: StringView.h:543
int compare(const CharT *str) const
Definition: StringView.h:409
size_type find(const CharT *str, size_type pos=0) const
Definition: StringView.h:510
size_type find(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:450
const_iterator iterator
Definition: StringView.h:33
int compare(size_type pos1, size_type count1, BasicStringView other, size_type pos2, size_type count2) const
Definition: StringView.h:397
size_type find(CharT character, size_type pos=0) const noexcept
Definition: StringView.h:485
constexpr BasicStringView(const std::basic_string< CharT, Traits, ALLOC > &str) noexcept
Definition: StringView.h:76
constexpr BasicStringView() noexcept=default
size_type find_first_not_of(const CharT *str, size_type pos=0) const
Definition: StringView.h:741
constexpr const_iterator cend() const noexcept
Definition: StringView.h:131
const_pointer const_iterator
Definition: StringView.h:32
BasicStringView substr(size_type pos=0, size_type count=npos) const
Definition: StringView.h:338
constexpr const_reference operator[](const size_type pos) const noexcept
Definition: StringView.h:182
const_reverse_iterator reverse_iterator
Definition: StringView.h:35
BasicStringView(const BasicStringView &) noexcept=default
size_type find_last_of(CharT character, size_type pos=npos) const noexcept
Definition: StringView.h:658
constexpr const_iterator end() const noexcept
Definition: StringView.h:121
int compare(BasicStringView other) const noexcept
Definition: StringView.h:356
void swap(BasicStringView &other) noexcept
Definition: StringView.h:301
size_type find_last_of(const CharT *str, size_type pos=npos) const
Definition: StringView.h:683
size_type find_first_of(const CharT *str, size_type pos=0) const
Definition: StringView.h:625
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: StringView.h:34
constexpr size_type size() const noexcept
Definition: StringView.h:240
size_type find_last_not_of(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:753
constexpr size_type length() const noexcept
Definition: StringView.h:250
int compare(size_type pos1, size_type count1, BasicStringView other) const
Definition: StringView.h:381
size_type copy(CharT *dest, size_type count, size_type pos=0) const
Definition: StringView.h:317
constexpr const_iterator begin() const noexcept
Definition: StringView.h:101
constexpr bool empty() const noexcept
Definition: StringView.h:270
constexpr const_reference back() const noexcept
Definition: StringView.h:220
size_type find_first_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:613
size_type find_first_not_of(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:695
size_type find(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:498
size_type find_last_not_of(const CharT *str, size_type pos=npos) const
Definition: StringView.h:799
int compare(size_type pos1, size_type count1, const CharT *str, size_type count2) const
Definition: StringView.h:438
constexpr const_pointer data() const noexcept
Definition: StringView.h:230
size_type find_first_not_of(CharT character, size_type pos=0) const noexcept
Definition: StringView.h:716
int compare(size_type pos1, size_type count1, const CharT *str) const
Definition: StringView.h:423
size_type find_last_not_of(CharT character, size_type pos=npos) const noexcept
Definition: StringView.h:774
size_type find_first_not_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:729
BasicStringView & operator=(const BasicStringView &) noexcept=default
size_type find_last_not_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:787
constexpr const_reverse_iterator rbegin() const noexcept
Definition: StringView.h:141
void remove_prefix(size_type n)
Definition: StringView.h:280
size_type find_first_of(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:579
const_reference at(const size_type pos) const
Definition: StringView.h:195
size_type find_first_of(CharT character, size_type pos=0) const noexcept
Definition: StringView.h:600
void append(const char *message)
constexpr bool operator!=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:833
constexpr bool operator>=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:885
constexpr bool operator>(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:872
std::basic_string< CharT, Traits, ALLOC > & operator+=(std::basic_string< CharT, Traits, ALLOC > &first, BasicStringView< CharT, Traits > second)
Definition: StringView.h:927
constexpr bool operator<(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:846
BasicStringView< char, std::char_traits< char > > StringView
Definition: StringView.h:936
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char > > string
Definition: String.h:17
CppRuntimeException & operator<<(CppRuntimeException &exception, const BasicBitBuffer< ALLOC > &bitBuffer)
Definition: BitBuffer.h:435
constexpr BasicStringView< CharT > makeStringView(const CharT(&str)[N])
Definition: StringView.h:897
constexpr bool operator==(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:820
string< ALLOC > toString(T value, const ALLOC &allocator=ALLOC())
std::basic_string< CharT, Traits, RebindAlloc< ALLOC, CharT > > stringViewToString(BasicStringView< CharT, Traits > stringView, const ALLOC &allocator=ALLOC())
Definition: StringView.h:912
constexpr bool operator<=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:859