Zserio C++ runtime library  1.1.0
Built for Zserio 2.15.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  {
363  return cmp;
364  }
365 
366  if (size() < other.size())
367  {
368  return -1;
369  }
370  else if (size() > other.size())
371  {
372  return 1;
373  }
374  else
375  {
376  return 0;
377  }
378  }
379 
389  int compare(size_type pos1, size_type count1, BasicStringView other) const
390  {
391  return substr(pos1, count1).compare(other);
392  }
393 
405  int compare(size_type pos1, size_type count1, BasicStringView other, size_type pos2, size_type count2) const
406  {
407  return substr(pos1, count1).compare(other.substr(pos2, count2));
408  }
409 
417  int compare(const CharT* str) const
418  {
419  return compare(BasicStringView(str));
420  }
421 
431  int compare(size_type pos1, size_type count1, const CharT* str) const
432  {
433  return substr(pos1, count1).compare(BasicStringView(str));
434  }
435 
446  int compare(size_type pos1, size_type count1, const CharT* str, size_type count2) const
447  {
448  return substr(pos1, count1).compare(BasicStringView(str, count2));
449  }
450 
458  size_type find(BasicStringView str, size_type pos = 0) const noexcept
459  {
460  if (pos >= size() || str.size() > size() - pos)
461  {
462  return npos; // the string cannot be there
463  }
464 
465  if (str.size() == 0)
466  {
467  return pos; // zero-sized search, this defaults to the match at the beginning
468  }
469 
470  const const_pointer startPtr = data() + pos; // where the searching will start
471  const const_pointer endPtr = data() + (size() - str.size()) + 1; // where the searching will end
472 
473  // initial position
474  const_pointer ptr = Traits::find(startPtr, static_cast<size_t>(endPtr - startPtr), str[0]);
475  while (ptr)
476  {
477  // check if the searched string is present
478  if (Traits::compare(ptr, str.data(), str.size()) == 0)
479  {
480  return static_cast<size_t>(ptr - data());
481  }
482 
483  // go to next position
484  ptr = Traits::find(ptr + 1, static_cast<size_t>(endPtr - ptr - 1), str[0]);
485  }
486 
487  return npos;
488  }
489 
497  size_type find(CharT character, size_type pos = 0) const noexcept
498  {
499  return find(BasicStringView(std::addressof(character), 1), pos);
500  }
501 
510  size_type find(const CharT* str, size_type pos, size_type count) const
511  {
512  return find(BasicStringView(str, count), pos);
513  }
514 
522  size_type find(const CharT* str, size_type pos = 0) const
523  {
524  return find(BasicStringView(str), pos);
525  }
526 
534  size_type rfind(BasicStringView str, size_type pos = npos) const noexcept
535  {
536  if (str.size() > size())
537  {
538  return npos;
539  }
540 
541  for (size_t p = std::min(static_cast<size_type>(size() - str.size()), pos) + 1; p > 0; --p)
542  {
543  if (Traits::compare(data() + p - 1, str.data(), str.size()) == 0)
544  {
545  return p - 1;
546  }
547  }
548 
549  return npos;
550  }
551 
559  size_type rfind(CharT character, size_type pos = npos) const noexcept
560  {
561  return rfind(BasicStringView(std::addressof(character), 1), pos);
562  }
563 
571  size_type rfind(const CharT* str, size_type pos, size_type count) const
572  {
573  return rfind(BasicStringView(str, count), pos);
574  }
575 
583  size_type rfind(const CharT* str, size_type pos = npos) const
584  {
585  return rfind(BasicStringView(str), pos);
586  }
587 
595  size_type find_first_of(BasicStringView str, size_type pos = 0) const noexcept
596  {
597  if (str.size() == 0 || pos >= size())
598  {
599  return npos;
600  }
601 
602  for (size_type idx = pos; idx < size(); ++idx)
603  {
604  if (Traits::find(str.data(), str.size(), data()[idx]) != nullptr)
605  {
606  return idx;
607  }
608  }
609 
610  return npos;
611  }
612 
620  size_type find_first_of(CharT character, size_type pos = 0) const noexcept
621  {
622  return find_first_of(BasicStringView(std::addressof(character), 1), pos);
623  }
624 
633  size_type find_first_of(const CharT* str, size_type pos, size_type count) const
634  {
635  return find_first_of(BasicStringView(str, count), pos);
636  }
637 
645  size_type find_first_of(const CharT* str, size_type pos = 0) const
646  {
647  return find_first_of(BasicStringView(str), pos);
648  }
649 
658  {
659  if (str.empty() || empty())
660  {
661  return npos;
662  }
663 
664  for (size_type idx = std::min(pos + 1, size()); idx > 0; --idx)
665  {
666  if (Traits::find(str.data(), str.size(), data()[idx - 1]) != nullptr)
667  {
668  return idx - 1;
669  }
670  }
671 
672  return npos;
673  }
674 
682  size_type find_last_of(CharT character, size_type pos = npos) const noexcept
683  {
684  return find_last_of(BasicStringView(std::addressof(character), 1), pos);
685  }
686 
695  size_type find_last_of(const CharT* str, size_type pos, size_type count) const
696  {
697  return find_last_of(BasicStringView(str, count), pos);
698  }
699 
707  size_type find_last_of(const CharT* str, size_type pos = npos) const
708  {
709  return find_last_of(BasicStringView(str), pos);
710  }
711 
720  {
721  if (str.size() == 0 || pos >= size())
722  {
723  return npos;
724  }
725 
726  for (size_type idx = pos; idx < size(); ++idx)
727  {
728  if (Traits::find(str.data(), str.size(), data()[idx]) == nullptr)
729  {
730  return idx;
731  }
732  }
733 
734  return npos;
735  }
736 
744  size_type find_first_not_of(CharT character, size_type pos = 0) const noexcept
745  {
746  return find_first_not_of(BasicStringView(std::addressof(character), 1), pos);
747  }
748 
757  size_type find_first_not_of(const CharT* str, size_type pos, size_type count) const
758  {
759  return find_first_not_of(BasicStringView(str, count), pos);
760  }
761 
769  size_type find_first_not_of(const CharT* str, size_type pos = 0) const
770  {
771  return find_first_not_of(BasicStringView(str), pos);
772  }
773 
782  {
783  if (str.empty() || empty())
784  {
785  return npos;
786  }
787 
788  for (size_type idx = std::min(pos + 1, size()); idx > 0; --idx)
789  {
790  if (Traits::find(str.data(), str.size(), data()[idx - 1]) == nullptr)
791  {
792  return idx - 1;
793  }
794  }
795 
796  return npos;
797  }
798 
806  size_type find_last_not_of(CharT character, size_type pos = npos) const noexcept
807  {
808  return find_last_not_of(BasicStringView(std::addressof(character), 1), pos);
809  }
810 
819  size_type find_last_not_of(const CharT* str, size_type pos, size_type count) const
820  {
821  return find_last_not_of(BasicStringView(str, count), pos);
822  }
823 
831  size_type find_last_not_of(const CharT* str, size_type pos = npos) const
832  {
833  return find_last_not_of(BasicStringView(str), pos);
834  }
835 
836 private:
837  const_pointer m_data = nullptr;
838  size_type m_size = 0;
839 };
840 
841 template <typename CharT, class Traits>
842 constexpr std::size_t const BasicStringView<CharT, Traits>::npos;
843 
851 template <typename CharT, class Traits>
853 {
854  return lhs.compare(rhs) == 0;
855 }
856 
864 template <typename CharT, class Traits>
866 {
867  return lhs.compare(rhs) != 0;
868 }
869 
877 template <typename CharT, class Traits>
879 {
880  return lhs.compare(rhs) < 0;
881 }
882 
890 template <typename CharT, class Traits>
892 {
893  return lhs.compare(rhs) <= 0;
894 }
895 
903 template <typename CharT, class Traits>
905 {
906  return lhs.compare(rhs) > 0;
907 }
908 
916 template <typename CharT, class Traits>
918 {
919  return lhs.compare(rhs) >= 0;
920 }
921 
928 template <typename CharT, size_t N>
929 constexpr BasicStringView<CharT> makeStringView(const CharT (&str)[N])
930 {
931  static_assert(N != 0, "Zero length arrays C++ extension is not supported!");
932  return BasicStringView<CharT>(str, str[N - 1] == CharT() ? (N - 1) : N);
933 }
934 
943 template <typename CharT, typename Traits, typename ALLOC = std::allocator<char>>
944 std::basic_string<CharT, Traits, RebindAlloc<ALLOC, CharT>> stringViewToString(
945  BasicStringView<CharT, Traits> stringView, const ALLOC& allocator = ALLOC())
946 {
947  return std::basic_string<CharT, Traits, RebindAlloc<ALLOC, CharT>>(
948  stringView.data(), stringView.size(), allocator);
949 }
950 
958 template <typename CharT, typename Traits, typename ALLOC = std::allocator<char>>
959 std::basic_string<CharT, Traits, ALLOC>& operator+=(
960  std::basic_string<CharT, Traits, ALLOC>& first, BasicStringView<CharT, Traits> second)
961 {
962  return first.append(second.data(), second.size());
963 }
964 
969 
976 template <typename ALLOC>
977 string<ALLOC> toString(StringView value, const ALLOC& allocator = ALLOC())
978 {
979  return stringViewToString(value, allocator);
980 }
981 
991 {
992  exception.append(view.data(), view.size());
993  return exception;
994 }
995 
996 inline namespace literals
997 {
998 
1002 constexpr ::zserio::StringView operator""_sv(const char* str, std::size_t len) noexcept
1003 {
1004  return ::zserio::StringView(str, len);
1005 }
1006 
1007 } // namespace literals
1008 
1009 } // namespace zserio
1010 
1011 #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:583
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:657
size_type rfind(BasicStringView str, size_type pos=npos) const noexcept
Definition: StringView.h:534
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:695
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:571
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:559
int compare(const CharT *str) const
Definition: StringView.h:417
size_type find(const CharT *str, size_type pos=0) const
Definition: StringView.h:522
size_type find(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:458
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:405
size_type find(CharT character, size_type pos=0) const noexcept
Definition: StringView.h:497
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:769
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:682
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:707
size_type find_first_of(const CharT *str, size_type pos=0) const
Definition: StringView.h:645
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:781
constexpr size_type length() const noexcept
Definition: StringView.h:250
int compare(size_type pos1, size_type count1, BasicStringView other) const
Definition: StringView.h:389
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:633
size_type find_first_not_of(BasicStringView str, size_type pos=0) const noexcept
Definition: StringView.h:719
size_type find(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:510
size_type find_last_not_of(const CharT *str, size_type pos=npos) const
Definition: StringView.h:831
int compare(size_type pos1, size_type count1, const CharT *str, size_type count2) const
Definition: StringView.h:446
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:744
int compare(size_type pos1, size_type count1, const CharT *str) const
Definition: StringView.h:431
size_type find_last_not_of(CharT character, size_type pos=npos) const noexcept
Definition: StringView.h:806
size_type find_first_not_of(const CharT *str, size_type pos, size_type count) const
Definition: StringView.h:757
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:819
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:595
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:620
void append(const char *message)
constexpr bool operator!=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:865
constexpr bool operator>=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:917
constexpr bool operator>(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:904
std::basic_string< CharT, Traits, ALLOC > & operator+=(std::basic_string< CharT, Traits, ALLOC > &first, BasicStringView< CharT, Traits > second)
Definition: StringView.h:959
constexpr bool operator<(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:878
BasicStringView< char, std::char_traits< char > > StringView
Definition: StringView.h:968
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:455
constexpr BasicStringView< CharT > makeStringView(const CharT(&str)[N])
Definition: StringView.h:929
constexpr bool operator==(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:852
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:944
constexpr bool operator<=(BasicStringView< CharT, Traits > lhs, BasicStringView< CharT, Traits > rhs) noexcept
Definition: StringView.h:891