VCCC  2024.05
VisualCamp Common C++ library
string_view.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 11/27/23.
3 //
4 
5 #ifndef VCCC_STRING_VIEW_HPP_
6 #define VCCC_STRING_VIEW_HPP_
7 
8 #include <algorithm>
9 #include <cstddef>
10 #include <cstdint>
11 #include <exception>
12 #include <functional>
13 #include <iterator>
14 #include <memory>
15 #include <stdexcept>
16 #include <string>
17 #include <ostream>
18 
19 #if __cplusplus >= 201703L
20 #include <string_view>
21 #endif
22 
23 #include "vccc/__config.h"
32 #include "vccc/__ranges/data.hpp"
35 #include "vccc/__ranges/size.hpp"
42 
48 namespace vccc {
49 
50 namespace detail {
51 
52 template<
53  typename It,
54  typename End,
55  typename CharT,
56  typename SizeType,
57  bool = conjunction<
58  contiguous_iterator<It>,
59  sized_sentinel_for<End, It>,
60  has_typename_type<iter_value<It>>,
61  negation<std::is_convertible<It, SizeType>>
62  >::value /* true */
63 >
64 struct string_view_iter_ctor : std::is_same<iter_value_t<It>, CharT> {};
65 
66 template<typename It, typename End, typename CharT, typename SizeType>
67 struct string_view_iter_ctor<It, End, CharT, SizeType, false> : std::false_type {};
68 
69 template<typename D, typename SV, typename = void>
70 struct has_operator_string_view
71 #if __cplusplus < 202002L
72  : std::is_same<D, std::string> {};
73 #else
74  : std::false_type {};
75 #endif
76 template<typename D, typename SV>
77 struct has_operator_string_view<D, SV, void_t<decltype( std::declval<D&>().operator SV() )>> : std::true_type {};
78 
79 template<
80  typename R,
81  typename SV,
82  bool = conjunction<
83  negation< std::is_same<remove_cvref_t<R>, SV> >,
84  ranges::contiguous_range<R>,
85  ranges::sized_range<R>,
86  has_typename_type<ranges::range_value<R>>
87  >::value /* true */
88 >
89 struct string_view_range_ctor
90  : conjunction<
91  std::is_same<ranges::range_value_t<R>, typename SV::value_type>,
92  negation< std::is_convertible<R, typename SV::const_pointer> >,
93  negation< has_operator_string_view<remove_cvref_t<R>, SV> >
94  >{};
95 template<typename R, typename SV>
96 struct string_view_range_ctor<R, SV, false> : std::false_type {};
97 
98 } // namespace detail
99 
102 
117 template<
118  typename CharT,
119  typename Traits = std::char_traits<CharT>>
121  public:
122  using traits_type = Traits;
123  using value_type = CharT;
124  using pointer = CharT*;
125  using const_pointer = const CharT*;
126  using reference = CharT&;
127  using const_reference = const CharT&;
130  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
132  using size_type = std::size_t;
133  using difference_type = std::ptrdiff_t;
134 
135  static constexpr size_type npos = size_type(-1);
136 
142  constexpr basic_string_view() noexcept
143  : data_(nullptr), size_(0) {}
144 
145  constexpr basic_string_view( const basic_string_view& other ) noexcept = default;
146 
147  constexpr basic_string_view( const CharT* s, size_type count )
148  : data_(s), size_(count) {}
149 
150  constexpr basic_string_view( const CharT* s )
151  : data_(s), size_(traits_type::length(s)) {}
152 
153  template<typename It, typename End, std::enable_if_t<
155  constexpr basic_string_view(It first, End last)
156  : data_(vccc::to_address(first)), size_(last - first) {}
157 
159  constexpr explicit basic_string_view(R&& r)
160  : data_(ranges::data(r)), size_(ranges::size(r)) {}
161 
162 
163  // basic_string_view does not have a constructor that accepts std::basic_string.
164  // Rather, std::basic_string defines a operator string_view.
165  // Add two custom constructors since std::basic_string cannot be modified
166  // It is the programmer's responsibility to ensure that the resulting string view does not outlive the string.
167  constexpr basic_string_view(const std::basic_string<CharT, Traits>& s)
168  : data_(s.data()), size_(s.size()) {}
169 
170  constexpr basic_string_view(std::basic_string<CharT, Traits>&& s)
171  : data_(s.data()), size_(s.size()) {}
172 
173 #if __cplusplus < 201703L
174  // Substitutaion for std::basic_string::basic_string(StringViewLike, ...)
175  explicit operator std::basic_string<CharT, Traits>() const {
176  return std::basic_string<CharT, Traits>(data(), size());
177  }
178 #else
179  operator std::basic_string_view<CharT, Traits>() const {
180  return std::basic_string_view<CharT, Traits>(data(), size());
181  }
182 #endif
183 
184  constexpr basic_string_view(std::nullptr_t) = delete;
186 
192  constexpr basic_string_view& operator=(const basic_string_view& other) noexcept = default;
194 
200  constexpr const_iterator begin() const noexcept { return data_; }
201 
202  constexpr const_iterator cbegin() const noexcept { return data_; }
204 
210  constexpr const_iterator end() const noexcept { return data_ + size_; }
211 
212  constexpr const_iterator cend() const noexcept { return data_ + size_; }
214 
220  constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(cend()); }
221 
222  constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
224 
230  constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(cbegin()); }
231 
232  constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
234 
247  constexpr const_reference operator[](size_type pos) const {
248  return data_[pos];
249  }
250 
255  constexpr const_reference at(size_type pos) const {
256  if (pos >= size()) {
257  throw std::out_of_range("vccc::string_view::at : out of range");
258  }
259  return (*this)[pos];
260  }
261 
266  constexpr const_reference front() const { return (*this)[0]; }
267 
272  constexpr const_reference back() const { return (*this)[size() - 1]; }
273 
278  constexpr const_pointer data() const noexcept { return data_; }
279 
285  constexpr size_type size() const noexcept { return size_; }
286 
287  constexpr size_type length() const noexcept { return size_; }
289 
294  constexpr size_type max_size() const noexcept { return static_cast<size_type>(-1) / sizeof(value_type); }
295 
300  constexpr bool empty() const noexcept { return size() == 0; }
301 
306  constexpr void remove_prefix(size_type n) {
307  data_ += n;
308  size_ -= n;
309  }
310 
315  constexpr void remove_suffix(size_type n) {
316  size_ -= n;
317  }
318 
324  constexpr void swap(basic_string_view& other) noexcept {
325  const_pointer p = data_;
326  data_ = other.data_;
327  other.data_ = p;
328 
329  size_type s = size_;
330  size_ = other.size_;
331  other.size_ = s;
332  }
334 
340  constexpr size_type copy(value_type* dest, size_type count, size_type pos = 0) const {
341  if (pos > size()) {
342  throw std::out_of_range("vccc::string_view::copy : out of range");
343  }
344  return traits_type::copy(dest, data() + pos, (std::min)(count, size() - pos));
345  }
347 
353  constexpr basic_string_view substr(size_type pos = 0, size_type count = npos) const {
354  if (pos > size()) {
355  throw std::out_of_range("vccc::string_view::substr : out of range");
356  }
357  return basic_string_view(data() + pos, (std::min)(count, size() - pos));
358  }
360 
366  constexpr int compare(basic_string_view other) const noexcept {
367  int r = traits_type::compare(data(), other.data(), (std::min)(size(), other.size()));
368  if (r == 0) {
369  return size() < other.size() ? -1 :
370  size() > other.size() ? 1 :
371  0;
372  }
373  return r;
374  }
375 
376  constexpr int compare(size_type pos1, size_type count1, basic_string_view other) const {
377  return substr(pos1, count1).compare(other);
378  }
379 
380  constexpr int compare(size_type pos1, size_type count1, basic_string_view other, size_type pos2, size_type count2) const {
381  return substr(pos1, count1).compare(other.substr(pos2, count2));
382  }
383 
384  constexpr int compare(const CharT* s) const {
385  return compare(basic_string_view(s));
386  }
387 
388  constexpr int compare(size_type pos1, size_type count1, const value_type* s) const {
389  return substr(pos1, count1).compare(basic_string_view(s));
390  }
391 
392  constexpr int compare(size_type pos1, size_type count1, const value_type* s, size_type count2) const {
393  return substr(pos1, count1).compare(basic_string_view(s, count2));
394  }
396 
402  constexpr bool starts_with(basic_string_view prefix) const noexcept {
403  return basic_string_view(data(), (std::min)(size(), prefix.size())) == prefix;
404  }
405 
406  constexpr bool starts_with(value_type c) const noexcept {
407  return !empty() && traits_type::eq(front(), c);
408  }
409 
410  constexpr bool starts_with(const value_type* s) const {
411  return starts_with(basic_string_view(s));
412  }
414 
420  constexpr bool ends_with(basic_string_view sv) const noexcept {
421  return size() >= sv.size() && compare(size() - sv.size(), npos, sv) == 0;
422  }
423 
424  constexpr bool ends_with(value_type c) const noexcept {
425  return !empty() && traits_type::eq(back(), c);
426  }
427 
428  constexpr bool ends_with(const value_type* s) const {
429  return ends_with(basic_string_view(s));
430  }
432 
433 
439  constexpr bool contains(basic_string_view sv) const noexcept {
440  return find(sv) != npos;
441  }
442 
443  constexpr bool contains(value_type c) const noexcept {
444  return find(c) != npos;
445  }
446 
447  constexpr bool contains(const value_type* str) const {
448  return find(str) != npos;
449  }
451 
457  constexpr size_type find(basic_string_view sv, size_type pos = 0) const noexcept {
458  while (pos <= size() - sv.size()) {
459  if (traits_type::compare(data() + pos, sv.data(), sv.size()) == 0)
460  return pos;
461  ++pos;
462  }
463  return npos;
464  }
465 
466  constexpr size_type find(value_type c, size_type pos = 0) const noexcept {
467  return find(basic_string_view(vccc::addressof(c), 1), pos);
468  }
469 
470  constexpr size_type find(const value_type* str, size_type pos, size_type count) const {
471  return find(basic_string_view(str, count), pos);
472  }
473 
474  constexpr size_type find(const value_type* str, size_type pos = 0) const {
475  return find(basic_string_view(str), pos);
476  }
478 
484  constexpr size_type rfind(basic_string_view sv, size_type pos = npos) const noexcept {
485  pos = (std::min)(size() - sv.size(), pos);
486  while (pos <= size() - sv.size()) {
487  if (traits_type::compare(data() + pos, sv.data(), sv.size()) == 0)
488  return pos;
489  --pos;
490  }
491  return npos;
492  }
493 
494  constexpr size_type rfind(value_type c, size_type pos = npos) const noexcept {
495  return rfind(basic_string_view(vccc::addressof(c), 1), pos);
496  }
497 
498  constexpr size_type rfind(const value_type* str, size_type pos, size_type count) const {
499  return rfind(basic_string_view(str, count), pos);
500  }
501 
502  constexpr size_type rfind(const value_type* str, size_type pos = npos) const {
503  return rfind(basic_string_view(str), pos);
504  }
506 
512  constexpr size_type find_first_of(basic_string_view sv, size_type pos = 0) const noexcept {
513  while (pos < size()) {
514  if (traits_type::find(sv.data(), sv.size(), (*this)[pos])) {
515  return pos;
516  }
517  ++pos;
518  }
519  return npos;
520  }
521 
522  constexpr size_type find_first_of(value_type c, size_type pos = 0) const noexcept {
523  return find_first_of(basic_string_view(vccc::addressof(c), 1), pos);
524  }
525 
526  constexpr size_type find_first_of(const value_type* s, size_type pos, size_type count) const {
527  return find_first_of(basic_string_view(s, count), pos);
528  }
529 
530  constexpr size_type find_first_of(const value_type* s, size_type pos = 0) const {
531  return find_first_of(basic_string_view(s), pos);
532  }
534 
540  constexpr size_type find_last_of(basic_string_view sv, size_type pos = npos) const noexcept {
541  pos = (std::min)(size() - 1, pos);
542  while (pos < size()) {
543  if (traits_type::find(sv.data(), sv.size(), (*this)[pos])) {
544  return pos;
545  }
546  --pos;
547  }
548  return npos;
549  }
550 
551  constexpr size_type find_last_of(value_type c, size_type pos = npos) const noexcept {
552  return find_last_of(basic_string_view(vccc::addressof(c), 1), pos);
553  }
554 
555  constexpr size_type find_last_of(const value_type* s, size_type pos, size_type count) const {
556  return find_last_of(basic_string_view(s, count), pos);
557  }
558 
559  constexpr size_type find_last_of(const value_type* s, size_type pos = npos) const {
560  return find_last_of(basic_string_view(s), pos);
561  }
563 
569  constexpr size_type find_first_not_of(basic_string_view sv, size_type pos = 0) const noexcept {
570  while (pos < size()) {
571  if (!traits_type::find(sv.data(), sv.size(), (*this)[pos])) {
572  return pos;
573  }
574  ++pos;
575  }
576  return npos;
577  }
578 
579  constexpr size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept {
581  }
582 
583  constexpr size_type find_first_not_of(const value_type* s, size_type pos, size_type count) const {
584  return find_first_not_of(basic_string_view(s, count), pos);
585  }
586 
587  constexpr size_type find_first_not_of(const value_type* s, size_type pos = 0) const {
588  return find_first_not_of(basic_string_view(s), pos);
589  }
591 
597  constexpr size_type find_last_not_of(basic_string_view sv, size_type pos = npos) const noexcept {
598  pos = (std::min)(size() - 1, pos);
599  while (pos < size()) {
600  if (!traits_type::find(sv.data(), sv.size(), (*this)[pos])) {
601  return pos;
602  }
603  --pos;
604  }
605  return npos;
606  }
607 
608  constexpr size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept {
610  }
611 
612  constexpr size_type find_last_not_of(const value_type* s, size_type pos, size_type count) const {
613  return find_last_not_of(basic_string_view(s, count), pos);
614  }
615 
616  constexpr size_type find_last_not_of(const value_type* s, size_type pos = npos) const {
617  return find_last_not_of(basic_string_view(s), pos);
618  }
620 
621  private:
622  const_pointer data_;
623  size_type size_;
624 };
625 
626 // Extra template parameters are used to workaround a issue in MSVC's ABI (name decoration) (VSO-409326)
627 
628 // operator==
629 template<typename CharT, typename Traits>
631  return (lhs.size() == rhs.size()) && (lhs.compare(rhs) == 0);
632 }
633 
635 template<typename CharT, typename Traits, int = 1>
636 constexpr bool operator==(basic_string_view<CharT, Traits> lhs, type_identity_t<basic_string_view<CharT, Traits>> rhs) noexcept {
637  return (lhs.size() == rhs.size()) && (lhs.compare(rhs) == 0);
638 }
639 
640 template<typename CharT, typename Traits, int = 2>
641 constexpr bool operator==(type_identity_t<basic_string_view<CharT, Traits>> lhs, basic_string_view<CharT, Traits> rhs) noexcept {
642  return (lhs.size() == rhs.size()) && (lhs.compare(rhs) == 0);
643 }
645 
646 // operator!=
647 template<typename CharT, typename Traits>
649  return !(lhs == rhs);
650 }
651 
653 template<typename CharT, typename Traits, int = 1>
654 constexpr bool operator!=(type_identity_t<basic_string_view<CharT, Traits>> lhs, basic_string_view<CharT, Traits> rhs) noexcept {
655  return !(lhs == rhs);
656 }
657 
658 template<typename CharT, typename Traits, int = 2>
659 constexpr bool operator!=(basic_string_view<CharT, Traits> lhs, type_identity_t<basic_string_view<CharT, Traits>> rhs) noexcept {
660  return !(lhs == rhs);
661 }
663 
664 // operator<
665 template<typename CharT, typename Traits>
667  return lhs.compare(rhs) < 0;
668 }
669 
671 template<typename CharT, typename Traits, int = 1>
672 constexpr bool operator<(type_identity_t<basic_string_view<CharT, Traits>> lhs, basic_string_view<CharT, Traits> rhs) noexcept {
673  return lhs.compare(rhs) < 0;
674 }
675 
676 template<typename CharT, typename Traits, int = 2>
677 constexpr bool operator<(basic_string_view<CharT, Traits> lhs, type_identity_t<basic_string_view<CharT, Traits>> rhs) noexcept {
678  return lhs.compare(rhs) < 0;
679 }
681 
682 // operator<=
683 template<typename CharT, typename Traits>
685  return lhs.compare(rhs) <= 0;
686 }
687 
689 template<typename CharT, typename Traits, int = 1>
690 constexpr bool operator<=(type_identity_t<basic_string_view<CharT, Traits>> lhs, basic_string_view<CharT, Traits> rhs) noexcept {
691  return lhs.compare(rhs) <= 0;
692 }
693 
694 template<typename CharT, typename Traits, int = 2>
695 constexpr bool operator<=(basic_string_view<CharT, Traits> lhs, type_identity_t<basic_string_view<CharT, Traits>> rhs) noexcept {
696  return lhs.compare(rhs) <= 0;
697 }
699 
700 // operator>
701 template<typename CharT, typename Traits>
703  return lhs.compare(rhs) > 0;
704 }
705 
707 template<typename CharT, typename Traits, int = 1>
708 constexpr bool operator>(type_identity_t<basic_string_view<CharT, Traits>> lhs, basic_string_view<CharT, Traits> rhs) noexcept {
709  return lhs.compare(rhs) > 0;
710 }
711 
712 template<typename CharT, typename Traits, int = 2>
713 constexpr bool operator>(basic_string_view<CharT, Traits> lhs, type_identity_t<basic_string_view<CharT, Traits>> rhs) noexcept {
714  return lhs.compare(rhs) > 0;
715 }
717 
718 // operator>=
719 template<typename CharT, typename Traits>
721  return lhs.compare(rhs) >= 0;
722 }
723 
725 template<typename CharT, typename Traits, int = 1>
726 constexpr bool operator>=(type_identity_t<basic_string_view<CharT, Traits>> lhs, basic_string_view<CharT, Traits> rhs) noexcept {
727  return lhs.compare(rhs) >= 0;
728 }
729 
730 template<typename CharT, typename Traits, int = 2>
731 constexpr bool operator>=(basic_string_view<CharT, Traits> lhs, type_identity_t<basic_string_view<CharT, Traits>> rhs) noexcept {
732  return lhs.compare(rhs) >= 0;
733 }
735 
736 template<typename CharT, typename Traits>
737 std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, basic_string_view<CharT, Traits> sv) {
738  using ostream_type = std::basic_ostream<CharT, Traits>;
739  using iostate_type = typename ostream_type::iostate;
740  using sentry_type = typename ostream_type::sentry;
741  using size_type = std::size_t;
742 
743  iostate_type state = ostream_type::goodbit;
744  sentry_type sentry(os);
745 
746  if (!sentry) {
747  state |= ostream_type::badbit;
748  } else {
749  size_type pad;
750  if (os.width() <= 0 || static_cast<size_type>(os.width()) <= sv.size()) {
751  pad = 0;
752  } else {
753  pad = static_cast<size_type>(os.width()) - sv.size();
754  }
755 
756  try {
757  // pad on left
758  if ((os.flags() & ostream_type::adjustfield) != ostream_type::left) {
759  for (; 0 < pad; --pad) {
760  if (Traits::eq_int_type(Traits::eof(), os.rdbuf()->sputc(os.fill()))) {
761  state |= ostream_type::badbit; // insertion failed, quit
762  break;
763  }
764  }
765  }
766 
767  std::streamsize n = (std::max)(os.width(), static_cast<std::streamsize>(sv.size()));
768  if (state == ostream_type::goodbit && os.rdbuf()->sputn(sv.data(), n) != n) {
769  state |= ostream_type::badbit;
770  }
771 
772  // pad on right
773  if (state == ostream_type::goodbit) {
774  for (; 0 < pad; --pad) {
775  if (Traits::eq_int_type(Traits::eof(), os.rdbuf()->sputc(os.fill()))) {
776  state |= ostream_type::badbit; // insertion failed, quit
777  break;
778  }
779  }
780  }
781 
782  os.width(0);
783  } catch (...) {
784  if ((os.exceptions() & ostream_type::badbit) != 0) {
785  std::rethrow_exception(std::current_exception());
786  }
787  }
788  }
789 
790  os.setstate(state);
791  return os;
792 }
793 
796 #if __cplusplus >= 202002L && VCCC_HAS_TYPE_CHAR8_T_CXX20
797 using u8string_view = basic_string_view<char8_t>;
798 #endif
801 
802 inline namespace literals {
803 inline namespace string_view_literals {
804 
805 constexpr string_view operator ""_sv(const char* str, std::size_t len) noexcept {
806  return string_view{str, len};
807 }
808 
809 #if __cplusplus >= 202002L && VCCC_HAS_TYPE_CHAR8_T_CXX20
810 constexpr u8string_view operator ""_sv(const char8_t* str, std::size_t len) noexcept {
811  return u8string_view{str, len};
812 }
813 #endif
814 
815 constexpr u16string_view operator ""_sv(const char16_t* str, std::size_t len) noexcept {
816  return u16string_view{str, len};
817 }
818 
819 constexpr u32string_view operator ""_sv(const char32_t* str, std::size_t len) noexcept {
820  return u32string_view{str, len};
821 }
822 
823 constexpr wstring_view operator ""_sv(const wchar_t* str, std::size_t len) noexcept {
824  return wstring_view{str, len};
825 }
826 
827 } // namespace string_view_literals
828 } // namespace literals
829 
830 template<typename CharT, typename Traits>
832  : std::true_type {};
833 
834 template<typename CharT, typename Traits >
835 struct ranges::enable_view<basic_string_view<CharT, Traits>> : std::true_type {};
836 
837 #if __cplusplus >= 201703L
838 template<typename It, typename End>
840 
841 template<typename R>
843 
844 #endif
845 
847 
848 } // namespace vccc
849 
850 
851 namespace std {
852 
855 
856 template<>
857 struct hash<vccc::string_view> {
858  std::size_t operator()(const vccc::string_view& sv) const noexcept {
859  return vccc::hash_array(sv.data(), sv.size());
860  }
861 };
862 
863 template<>
864 struct hash<vccc::wstring_view> {
865  std::size_t operator()(const vccc::wstring_view& sv) const noexcept {
866  return vccc::hash_array(sv.data(), sv.size());
867  }
868 };
869 
870 #if __cplusplus >= 202002L && VCCC_HAS_TYPE_CHAR8_T_CXX20
871 template<>
872 struct hash<vccc::u8string_view> {
873  std::size_t operator()(const vccc::u8string_view& sv) const noexcept {
874  return vccc::hash_array(sv.data(), sv.size());
875  }
876 };
877 #endif
878 
879 template<>
880 struct hash<vccc::u16string_view> {
881  std::size_t operator()(const vccc::u16string_view& sv) const noexcept {
882  return vccc::hash_array(sv.data(), sv.size());
883  }
884 };
885 
886 template<>
887 struct hash<vccc::u32string_view> {
888  std::size_t operator()(const vccc::u32string_view& sv) const noexcept {
889  return vccc::hash_array(sv.data(), sv.size());
890  }
891 };
892 
894 
895 } // namespace std
896 
897 #endif // VCCC_STRING_VIEW_HPP_
The templated class vccc::basic_string_view provides a lightweight object that offers read-only acces...
Definition: string_view.hpp:120
constexpr const_iterator begin() const noexcept
Definition: string_view.hpp:200
constexpr size_type find_first_of(const value_type *s, size_type pos=0) const
Definition: string_view.hpp:530
constexpr const_reference front() const
Definition: string_view.hpp:266
constexpr bool contains(basic_string_view sv) const noexcept
Definition: string_view.hpp:439
constexpr size_type find_last_not_of(basic_string_view sv, size_type pos=npos) const noexcept
Definition: string_view.hpp:597
const_reverse_iterator reverse_iterator
Definition: string_view.hpp:131
constexpr size_type find_first_not_of(basic_string_view sv, size_type pos=0) const noexcept
Definition: string_view.hpp:569
constexpr size_type find_last_of(basic_string_view sv, size_type pos=npos) const noexcept
Definition: string_view.hpp:540
constexpr size_type find_last_of(value_type c, size_type pos=npos) const noexcept
Definition: string_view.hpp:551
constexpr const_reference back() const
Definition: string_view.hpp:272
constexpr size_type find_first_not_of(const value_type *s, size_type pos=0) const
Definition: string_view.hpp:587
constexpr size_type find_first_not_of(value_type c, size_type pos=0) const noexcept
Definition: string_view.hpp:579
static constexpr size_type npos
Definition: string_view.hpp:135
constexpr const_iterator end() const noexcept
Definition: string_view.hpp:210
constexpr basic_string_view(const basic_string_view &other) noexcept=default
constexpr size_type rfind(basic_string_view sv, size_type pos=npos) const noexcept
Definition: string_view.hpp:484
constexpr bool contains(const value_type *str) const
Definition: string_view.hpp:447
constexpr bool starts_with(basic_string_view prefix) const noexcept
Definition: string_view.hpp:402
constexpr size_type rfind(const value_type *str, size_type pos=npos) const
Definition: string_view.hpp:502
constexpr size_type size() const noexcept
Definition: string_view.hpp:285
constexpr const_reverse_iterator rbegin() const noexcept
Definition: string_view.hpp:220
constexpr basic_string_view substr(size_type pos=0, size_type count=npos) const
Definition: string_view.hpp:353
constexpr const_reverse_iterator crend() const noexcept
Definition: string_view.hpp:232
constexpr void remove_prefix(size_type n)
Definition: string_view.hpp:306
constexpr size_type find_last_not_of(const value_type *s, size_type pos, size_type count) const
Definition: string_view.hpp:612
constexpr int compare(size_type pos1, size_type count1, const value_type *s, size_type count2) const
Definition: string_view.hpp:392
constexpr int compare(size_type pos1, size_type count1, basic_string_view other) const
Definition: string_view.hpp:376
const CharT & const_reference
Definition: string_view.hpp:127
constexpr bool starts_with(value_type c) const noexcept
Definition: string_view.hpp:406
constexpr size_type find_last_not_of(value_type c, size_type pos=npos) const noexcept
Definition: string_view.hpp:608
constexpr basic_string_view(const CharT *s)
Definition: string_view.hpp:150
const CharT * const_pointer
Definition: string_view.hpp:125
constexpr basic_string_view(std::basic_string< CharT, Traits > &&s)
Definition: string_view.hpp:170
constexpr size_type find_last_of(const value_type *s, size_type pos, size_type count) const
Definition: string_view.hpp:555
constexpr size_type find_first_of(const value_type *s, size_type pos, size_type count) const
Definition: string_view.hpp:526
constexpr int compare(size_type pos1, size_type count1, basic_string_view other, size_type pos2, size_type count2) const
Definition: string_view.hpp:380
constexpr basic_string_view(std::nullptr_t)=delete
Traits traits_type
Definition: string_view.hpp:122
constexpr size_type find(const value_type *str, size_type pos=0) const
Definition: string_view.hpp:474
constexpr size_type rfind(value_type c, size_type pos=npos) const noexcept
Definition: string_view.hpp:494
constexpr size_type copy(value_type *dest, size_type count, size_type pos=0) const
Definition: string_view.hpp:340
constexpr size_type find_first_not_of(const value_type *s, size_type pos, size_type count) const
Definition: string_view.hpp:583
const_pointer const_iterator
Definition: string_view.hpp:128
constexpr basic_string_view(R &&r)
Definition: string_view.hpp:159
constexpr basic_string_view(It first, End last)
Definition: string_view.hpp:155
constexpr const_iterator cbegin() const noexcept
Definition: string_view.hpp:202
constexpr bool ends_with(value_type c) const noexcept
Definition: string_view.hpp:424
constexpr basic_string_view(const CharT *s, size_type count)
Definition: string_view.hpp:147
constexpr bool ends_with(basic_string_view sv) const noexcept
Definition: string_view.hpp:420
constexpr const_reverse_iterator rend() const noexcept
Definition: string_view.hpp:230
constexpr const_reference operator[](size_type pos) const
Definition: string_view.hpp:247
constexpr const_iterator cend() const noexcept
Definition: string_view.hpp:212
constexpr int compare(const CharT *s) const
Definition: string_view.hpp:384
constexpr const_reverse_iterator crbegin() const noexcept
Definition: string_view.hpp:222
constexpr int compare(basic_string_view other) const noexcept
Definition: string_view.hpp:366
constexpr basic_string_view() noexcept
Definition: string_view.hpp:142
constexpr size_type max_size() const noexcept
Definition: string_view.hpp:294
constexpr bool contains(value_type c) const noexcept
Definition: string_view.hpp:443
constexpr basic_string_view & operator=(const basic_string_view &other) noexcept=default
constexpr int compare(size_type pos1, size_type count1, const value_type *s) const
Definition: string_view.hpp:388
const_iterator iterator
Definition: string_view.hpp:129
constexpr size_type find(const value_type *str, size_type pos, size_type count) const
Definition: string_view.hpp:470
constexpr size_type find(basic_string_view sv, size_type pos=0) const noexcept
Definition: string_view.hpp:457
constexpr size_type length() const noexcept
Definition: string_view.hpp:287
constexpr size_type find_first_of(value_type c, size_type pos=0) const noexcept
Definition: string_view.hpp:522
std::ptrdiff_t difference_type
Definition: string_view.hpp:133
constexpr size_type find_last_not_of(const value_type *s, size_type pos=npos) const
Definition: string_view.hpp:616
constexpr void remove_suffix(size_type n)
Definition: string_view.hpp:315
constexpr void swap(basic_string_view &other) noexcept
Definition: string_view.hpp:324
constexpr bool ends_with(const value_type *s) const
Definition: string_view.hpp:428
constexpr size_type find(value_type c, size_type pos=0) const noexcept
Definition: string_view.hpp:466
constexpr size_type find_last_of(const value_type *s, size_type pos=npos) const
Definition: string_view.hpp:559
constexpr bool starts_with(const value_type *s) const
Definition: string_view.hpp:410
constexpr basic_string_view(const std::basic_string< CharT, Traits > &s)
Definition: string_view.hpp:167
constexpr const_pointer data() const noexcept
Definition: string_view.hpp:278
constexpr size_type rfind(const value_type *str, size_type pos, size_type count) const
Definition: string_view.hpp:498
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: string_view.hpp:130
constexpr size_type find_first_of(basic_string_view sv, size_type pos=0) const noexcept
Definition: string_view.hpp:512
CharT & reference
Definition: string_view.hpp:126
constexpr bool empty() const noexcept
Definition: string_view.hpp:300
std::size_t size_type
Definition: string_view.hpp:132
CharT value_type
Definition: string_view.hpp:123
CharT * pointer
Definition: string_view.hpp:124
constexpr const_reference at(size_type pos) const
Definition: string_view.hpp:255
constexpr VCCC_INLINE_OR_STATIC detail::max_niebloid max
Definition: max.hpp:95
constexpr VCCC_INLINE_OR_STATIC detail::find_niebloid find
Definition: find.hpp:54
constexpr VCCC_INLINE_OR_STATIC detail::min_niebloid min
Definition: min.hpp:90
constexpr VCCC_INLINE_OR_STATIC detail::copy_niebloid copy
Definition: copy.hpp:69
constexpr VCCC_INLINE_OR_STATIC detail::count_niebloid count
Definition: count.hpp:58
std::size_t hash_array(const T *bytes, std::size_t size)
Definition: hash_array.hpp:91
constexpr T * to_address(T *p) noexcept
Definition: to_address.hpp:37
std::ostream & operator<<(std::ostream &os, const MatrixBase< E > &mat_expr)
Definition: matrix_ostream.hpp:17
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
constexpr bool operator>(const optional< T > &lhs, const optional< U > &rhs)
Definition: optional.h:522
constexpr bool operator<(const optional< T > &lhs, const optional< U > &rhs)
Definition: optional.h:504
constexpr bool operator<=(const optional< T > &lhs, const optional< U > &rhs)
Definition: optional.h:513
constexpr bool operator>=(const optional< T > &lhs, const optional< U > &rhs)
Definition: optional.h:531
basic_string_view< char > string_view
Definition: string_view.hpp:794
basic_string_view< wchar_t > wstring_view
Definition: string_view.hpp:795
basic_string_view< char16_t > u16string_view
Definition: string_view.hpp:799
basic_string_view< char32_t > u32string_view
Definition: string_view.hpp:800
typename type_identity< T >::type type_identity_t
Definition: type_identity.hpp:22
void void_t
Definition: void_t.hpp:19
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr bool operator!=(const MatrixBase< E1 > &lhs, const MatrixBase< E2 > &rhs)
Definition: mat_expr_operations.hpp:23
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 0 > first
Definition: key_value.hpp:34
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
constexpr bool operator==(const MatrixBase< E1 > &lhs, const MatrixBase< E2 > &rhs)
Definition: mat_expr_operations.hpp:15
std::size_t operator()(const vccc::string_view &sv) const noexcept
Definition: string_view.hpp:858
std::size_t operator()(const vccc::u16string_view &sv) const noexcept
Definition: string_view.hpp:881
std::size_t operator()(const vccc::u32string_view &sv) const noexcept
Definition: string_view.hpp:888
std::size_t operator()(const vccc::wstring_view &sv) const noexcept
Definition: string_view.hpp:865
Definition: enable_borrowed_range.hpp:17
The enable_view variable template is used to indicate whether a range is a view.
Definition: enable_view.hpp:36