tlx
string_view.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/container/string_view.hpp
3  *
4  * A simplified string_view implementation for portability.
5  *
6  * Copyright (C) 2012-2015 Marshall Clow
7  * Copyright (C) 2015 Beman Dawes
8  *
9  * Based on the StringRef implementation in LLVM (http://llvm.org) and
10  * N3422 by Jeffrey Yasskin
11  * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
12  * Updated July 2015 to reflect the Library Fundamentals TS
13  * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
14  *
15  * Part of tlx - http://panthema.net/tlx
16  *
17  * Copyright (C) 2016-2020 Timo Bingmann <tb@panthema.net>
18  *
19  * All rights reserved. Published under the Boost Software License, Version 1.0
20  ******************************************************************************/
21 
22 #ifndef TLX_CONTAINER_STRING_VIEW_HEADER
23 #define TLX_CONTAINER_STRING_VIEW_HEADER
24 
25 #include <algorithm>
26 #include <cstring>
27 #include <iterator>
28 #include <ostream>
29 #include <stdexcept>
30 #include <string>
31 
32 #include <tlx/string/hash_djb2.hpp>
33 
34 namespace tlx {
35 
36 //! \addtogroup tlx_container
37 //! \{
38 
39 /*!
40  * StringView is a reference to a part of a string, consisting of only a char
41  * pointer and a length. It does not have ownership of the substring and is used
42  * mainly for temporary objects.
43  */
45 {
46 public:
47  // types
48  typedef char value_type;
49  typedef char* pointer;
50  typedef const char* const_pointer;
51  typedef char& reference;
52  typedef const char& const_reference;
53  typedef const_pointer const_iterator;
54  typedef const_iterator iterator;
55  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
56  typedef const_reverse_iterator reverse_iterator;
57  typedef std::size_t size_type;
58  typedef std::ptrdiff_t difference_type;
59 
60  static constexpr size_type npos = size_type(-1);
61 
62  //! default construction
63  StringView() noexcept : ptr_(nullptr), size_(0) { }
64 
65  //! copy construction
66  StringView(const StringView& rhs) noexcept = default;
67  //! assignment
68  StringView& operator = (const StringView& rhs) noexcept = default;
69 
70  //! assign a whole string
71  StringView(const std::string& str) noexcept
72  : ptr_(str.data()), size_(str.size()) { }
73 
74  //! constructing a StringView from a temporary string is a bad idea
75  StringView(std::string&&) = delete;
76 
77  //! assign a whole C-style string
78  StringView(const char* str) noexcept
79  : ptr_(str), size_(str ? std::strlen(str) : 0) { }
80 
81  //! assign a C-style string with given length
82  StringView(const char* str, size_type size) noexcept
83  : ptr_(str), size_(size) { }
84 
85  //! assign a string iterator with given length
86  StringView(const std::string::const_iterator& begin, size_t size) noexcept
87  : ptr_(&(*begin)), size_(size) { }
88 
89  //! assign a string between two iterators
90  StringView(const std::string::const_iterator& begin,
91  const std::string::const_iterator& end) noexcept
92  : StringView(begin, end - begin) { }
93 
94  //! \name iterators
95  //! \{
96 
97  const_iterator begin() const noexcept { return ptr_; }
98  const_iterator cbegin() const noexcept { return ptr_; }
99  const_iterator end() const noexcept { return ptr_ + size_; }
100  const_iterator cend() const noexcept { return ptr_ + size_; }
101 
102  const_reverse_iterator rbegin() const noexcept {
103  return const_reverse_iterator(end());
104  }
105  const_reverse_iterator crbegin() const noexcept {
106  return const_reverse_iterator(end());
107  }
108  const_reverse_iterator rend() const noexcept {
109  return const_reverse_iterator(begin());
110  }
111  const_reverse_iterator crend() const noexcept {
112  return const_reverse_iterator(begin());
113  }
114 
115  //! \}
116 
117  //! \name capacity
118  //! \{
119 
120  size_type size() const noexcept { return size_; }
121  size_type length() const noexcept { return size_; }
122  size_type max_size() const noexcept { return size_; }
123  bool empty() const noexcept { return size_ == 0; }
124 
125  //! \}
126 
127  //! \name element access
128  //! \{
129 
130  const_pointer data() const noexcept { return ptr_; }
131 
132  const_reference operator [] (size_type pos) const noexcept {
133  return ptr_[pos];
134  }
135 
136  const_reference at(size_t pos) const {
137  if (pos >= size_)
138  throw std::out_of_range("StringView::at");
139  return ptr_[pos];
140  }
141 
142  const_reference front() const { return ptr_[0]; }
143  const_reference back() const { return ptr_[size_ - 1]; }
144 
145  //! \}
146 
147  //! \name modifiers
148  //! \{
149 
150  void clear() noexcept { size_ = 0; }
151 
152  void remove_prefix(size_type n) {
153  if (n > size_)
154  n = size_;
155  ptr_ += n;
156  size_ -= n;
157  }
158 
159  void remove_suffix(size_type n) {
160  if (n > size_)
161  n = size_;
162  size_ -= n;
163  }
164 
165  void swap(StringView& s) noexcept {
166  std::swap(ptr_, s.ptr_);
167  std::swap(size_, s.size_);
168  }
169 
170  //! \}
171 
172  // StringView string operations
173  explicit operator std::string() const {
174  return std::string(begin(), end());
175  }
176 
177  //! Returns the data of this StringView as a std::string
178  std::string to_string() const { return std::string(ptr_, size_); }
179 
180  size_type copy(char* s, size_type n, size_type pos = 0) const {
181  if (pos > size())
182  throw std::out_of_range("StringView::copy");
183  size_type rsize = std::min(n, size_ - pos);
184  std::copy(data(), data() + rsize, s);
185  return rsize;
186  }
187 
188  StringView substr(size_type pos, size_type n = npos) const {
189  if (pos > size())
190  throw std::out_of_range("StringView::substr");
191  return StringView(data() + pos, (std::min)(size() - pos, n));
192  }
193 
194  //! \name comparisons
195  //! \{
196 
197  int compare(StringView x) const noexcept {
198  const int cmp = std::strncmp(ptr_, x.ptr_, std::min(size_, x.size_));
199  return cmp != 0 ? cmp
200  : (size_ == x.size_ ? 0 : size_ < x.size_ ? -1 : 1);
201  }
202 
203  int compare(size_type pos1, size_type n1, StringView x) const noexcept {
204  return substr(pos1, n1).compare(x);
205  }
206 
207  int compare(size_type pos1, size_type n1, StringView x, size_type pos2,
208  size_type n2) const {
209  return substr(pos1, n1).compare(x.substr(pos2, n2));
210  }
211 
212  int compare(const char* x) const {
213  return compare(StringView(x));
214  }
215 
216  int compare(size_type pos1, size_type n1, const char* x) const {
217  return substr(pos1, n1).compare(StringView(x));
218  }
219 
220  int compare(
221  size_type pos1, size_type n1, const char* x, size_type n2) const {
222  return substr(pos1, n1).compare(StringView(x, n2));
223  }
224 
225  //! \}
226 
227  //! \name comparison operators
228  //! \{
229 
230  //! Equality operator to compare a StringView with another StringView
231  bool operator == (const StringView& other) const noexcept {
232  return size_ == other.size_ &&
233  std::equal(ptr_, ptr_ + size_, other.ptr_);
234  }
235 
236  //! Inequality operator to compare a StringView with another StringView
237  bool operator != (const StringView& other) const noexcept {
238  return !(operator == (other));
239  }
240 
241  //! Less operator to compare a StringView with another StringView
242  //! lexicographically
243  bool operator < (const StringView& other) const noexcept {
244  return std::lexicographical_compare(
245  ptr_, ptr_ + size_, other.ptr_, other.ptr_ + other.size_);
246  }
247 
248  //! Greater than
249  bool operator > (const StringView& other) const noexcept {
250  return other.operator < (*this);
251  }
252 
253  //! Less than or equal to
254  bool operator <= (const StringView& other) const noexcept {
255  return !other.operator < (*this);
256  }
257 
258  //! Less than or equal to
259  bool operator >= (const StringView& other) const noexcept {
260  return !operator < (other);
261  }
262 
263  //! \}
264 
265  //! \name searches
266  //! \{
267 
268  bool starts_with(char c) const noexcept {
269  return !empty() && c == front();
270  }
271 
272  bool starts_with(StringView x) const noexcept {
273  return size_ >= x.size_ && std::equal(ptr_, ptr_ + x.size_, x.ptr_);
274  }
275 
276  bool ends_with(char c) const noexcept {
277  return !empty() && c == back();
278  }
279 
280  bool ends_with(StringView x) const noexcept {
281  return size_ >= x.size_ &&
282  std::equal(ptr_ + size_ - x.size_, ptr_ + size_, x.ptr_);
283  }
284 
285  //! \}
286 
287  //! \name find
288  //! \{
289 
290  size_type find(StringView s, size_type pos = 0) const noexcept {
291  if (pos > size())
292  return npos;
293  if (s.empty())
294  return pos;
295  const_iterator iter =
296  std::search(cbegin() + pos, cend(), s.cbegin(), s.cend());
297  return iter == cend() ? npos : std::distance(cbegin(), iter);
298  }
299  size_type find(char c, size_type pos = 0) const noexcept {
300  return find(StringView(&c, 1), pos);
301  }
302  size_type find(const char* s, size_type pos, size_type n) const noexcept {
303  return find(StringView(s, n), pos);
304  }
305  size_type find(const char* s, size_type pos = 0) const noexcept {
306  return find(StringView(s), pos);
307  }
308 
309  //! \}
310 
311  //! \name rfind
312  //! \{
313 
314  size_type rfind(StringView s, size_type pos = npos) const noexcept {
315  if (size_ < s.size_)
316  return npos;
317  if (pos > size_ - s.size_)
318  pos = size_ - s.size_;
319  if (s.size_ == 0u) // an empty string is always found
320  return pos;
321  for (const char* cur = ptr_ + pos; ; --cur) {
322  if (std::strncmp(cur, s.ptr_, s.size_) == 0)
323  return cur - ptr_;
324  if (cur == ptr_)
325  return npos;
326  }
327  }
328  size_type rfind(char c, size_type pos = npos) const noexcept {
329  return rfind(StringView(&c, 1), pos);
330  }
331  size_type rfind(const char* s, size_type pos, size_type n) const noexcept {
332  return rfind(StringView(s, n), pos);
333  }
334  size_type rfind(const char* s, size_type pos = npos) const noexcept {
335  return rfind(StringView(s), pos);
336  }
337 
338  //! \}
339 
340  //! \name find_first_of
341  //! \{
342 
343  size_type find_first_of(StringView s, size_type pos = 0) const noexcept {
344  if (pos >= size_ || s.size_ == 0)
345  return npos;
346  const_iterator iter =
347  std::find_first_of(cbegin() + pos, cend(), s.cbegin(), s.cend());
348  return iter == cend() ? npos : std::distance(cbegin(), iter);
349  }
350  size_type find_first_of(char c, size_type pos = 0) const noexcept {
351  return find_first_of(StringView(&c, 1), pos);
352  }
353  size_type find_first_of(const char* s,
354  size_type pos, size_type n) const noexcept {
355  return find_first_of(StringView(s, n), pos);
356  }
357  size_type find_first_of(const char* s, size_type pos = 0) const noexcept {
358  return find_first_of(StringView(s), pos);
359  }
360 
361  //! \}
362 
363  //! \name find_last_of
364  //! \{
365 
366  size_type find_last_of(StringView s, size_type pos = npos) const noexcept {
367  if (s.size_ == 0u)
368  return npos;
369  if (pos >= size_)
370  pos = 0;
371  else
372  pos = size_ - (pos + 1);
373  const_reverse_iterator iter =
374  std::find_first_of(crbegin() + pos, crend(), s.cbegin(), s.cend());
375  return iter == crend() ? npos : reverse_distance(crbegin(), iter);
376  }
377  size_type find_last_of(char c, size_type pos = npos) const noexcept {
378  return find_last_of(StringView(&c, 1), pos);
379  }
380  size_type find_last_of(const char* s,
381  size_type pos, size_type n) const noexcept {
382  return find_last_of(StringView(s, n), pos);
383  }
384  size_type find_last_of(const char* s, size_type pos = npos) const noexcept {
385  return find_last_of(StringView(s), pos);
386  }
387 
388  //! \}
389 
390  //! \name find_first_not_of
391  //! \{
392 
394  size_type pos = 0) const noexcept {
395  if (pos >= size_)
396  return npos;
397  if (s.size_ == 0)
398  return pos;
399  const_iterator iter = find_not_of(cbegin() + pos, cend(), s);
400  return iter == cend() ? npos : std::distance(cbegin(), iter);
401  }
402  size_type find_first_not_of(char c, size_type pos = 0) const noexcept {
403  return find_first_not_of(StringView(&c, 1), pos);
404  }
405  size_type find_first_not_of(const char* s, size_type pos,
406  size_type n) const noexcept {
407  return find_first_not_of(StringView(s, n), pos);
408  }
409  size_type find_first_not_of(const char* s,
410  size_type pos = 0) const noexcept {
411  return find_first_not_of(StringView(s), pos);
412  }
413 
414  //! \}
415 
416  //! \name find_last_not_of
417  //! \{
418 
420  size_type pos = npos) const noexcept {
421  if (pos >= size_)
422  pos = size_ - 1;
423  if (s.size_ == 0u)
424  return pos;
425  pos = size_ - (pos + 1);
426  const_reverse_iterator iter = find_not_of(crbegin() + pos, crend(), s);
427  return iter == crend() ? npos : reverse_distance(crbegin(), iter);
428  }
429  size_type find_last_not_of(char c, size_type pos = npos) const noexcept {
430  return find_last_not_of(StringView(&c, 1), pos);
431  }
432  size_type find_last_not_of(const char* s,
433  size_type pos, size_type n) const noexcept {
434  return find_last_not_of(StringView(s, n), pos);
435  }
436  size_type find_last_not_of(const char* s,
437  size_type pos = npos) const noexcept {
438  return find_last_not_of(StringView(s), pos);
439  }
440 
441  //! \}
442 
443  // ostream
444  friend std::ostream& operator << (std::ostream& os, const StringView& v) {
445  os.write(v.data(), v.size());
446  return os;
447  }
448 
449 private:
450  template <typename r_iter>
451  size_type reverse_distance(r_iter first, r_iter last) const noexcept {
452  // Portability note here: std::distance is not NOEXCEPT, but calling it
453  // with a StringView::reverse_iterator will not throw.
454  return size_ - 1 - std::distance(first, last);
455  }
456 
457  template <typename Iterator>
458  Iterator find_not_of(Iterator first, Iterator last, StringView s) const
459  noexcept {
460  for ( ; first != last; ++first)
461  if (0 == std::char_traits<char>::find(s.ptr_, s.size_, *first))
462  return first;
463  return last;
464  }
465 
466  const char* ptr_;
467  size_type size_;
468 };
469 
470 /*----------------------------------------------------------------------------*/
471 
472 //! make alias due to STL similarity
474 
475 /*----------------------------------------------------------------------------*/
476 // comparison operators: StringView with std::string
477 
478 //! equality operator to compare a StringView with a std::string
479 static inline
480 bool operator == (const StringView& a, const std::string& b) noexcept {
481  return a.size() == b.size() &&
482  std::equal(a.begin(), a.end(), b.begin());
483 }
484 
485 //! equality operator to compare a StringView with a std::string
486 static inline
487 bool operator == (const std::string& a, const StringView& b) noexcept {
488  return a.size() == b.size() &&
489  std::equal(a.begin(), a.end(), b.begin());
490 }
491 
492 //! inequality operator to compare a StringView with a std::string
493 static inline
494 bool operator != (const StringView& a, const std::string& b) noexcept {
495  return !(a.operator == (b));
496 }
497 
498 //! inequality operator to compare a StringView with a std::string
499 static inline
500 bool operator != (const std::string& a, const StringView& b) noexcept {
501  return !(b.operator == (a));
502 }
503 
504 //! less operator to compare a StringView with a std::string
505 //! lexicographically
506 static inline
507 bool operator < (const StringView& a, const std::string& b) noexcept {
508  return std::lexicographical_compare(
509  a.begin(), a.end(), b.begin(), b.end());
510 }
511 
512 //! less operator to compare a StringView with a std::string
513 //! lexicographically
514 static inline
515 bool operator < (const std::string& a, const StringView& b) noexcept {
516  return std::lexicographical_compare(
517  a.begin(), a.end(), b.begin(), b.end());
518 }
519 
520 static inline
521 bool operator > (const StringView& x, const std::string& y) noexcept {
522  return x > StringView(y);
523 }
524 
525 static inline
526 bool operator > (const std::string& x, const StringView& y) noexcept {
527  return StringView(x) > y;
528 }
529 
530 static inline
531 bool operator <= (const StringView& x, const std::string& y) noexcept {
532  return x <= StringView(y);
533 }
534 
535 static inline
536 bool operator <= (const std::string& x, const StringView& y) noexcept {
537  return StringView(x) <= y;
538 }
539 
540 static inline
541 bool operator >= (const StringView& x, const std::string& y) noexcept {
542  return x >= StringView(y);
543 }
544 
545 static inline
546 bool operator >= (const std::string& x, const StringView& y) noexcept {
547  return StringView(x) >= y;
548 }
549 
550 /*----------------------------------------------------------------------------*/
551 // comparison operators: StringView with const char*
552 
553 //! equality operator to compare a StringView with a const char*
554 static inline
555 bool operator == (const StringView& x, const char* y) noexcept {
556  return x == StringView(y);
557 }
558 
559 //! equality operator to compare a StringView with a const char*
560 static inline
561 bool operator == (const char* x, const StringView& y) noexcept {
562  return StringView(x) == y;
563 }
564 
565 //! inequality operator to compare a StringView with a const char*
566 static inline
567 bool operator != (const StringView& x, const char* y) noexcept {
568  return x != StringView(y);
569 }
570 
571 //! inequality operator to compare a StringView with a const char*
572 static inline
573 bool operator != (const char* x, const StringView& y) noexcept {
574  return StringView(x) != y;
575 }
576 
577 static inline
578 bool operator < (const StringView& x, const char* y) noexcept {
579  return x < StringView(y);
580 }
581 
582 static inline
583 bool operator < (const char* x, const StringView& y) noexcept {
584  return StringView(x) < y;
585 }
586 
587 static inline
588 bool operator > (const StringView& x, const char* y) noexcept {
589  return x > StringView(y);
590 }
591 
592 static inline
593 bool operator > (const char* x, const StringView& y) noexcept {
594  return StringView(x) > y;
595 }
596 
597 static inline
598 bool operator <= (const StringView& x, const char* y) noexcept {
599  return x <= StringView(y);
600 }
601 
602 static inline
603 bool operator <= (const char* x, const StringView& y) noexcept {
604  return StringView(x) <= y;
605 }
606 
607 static inline
608 bool operator >= (const StringView& x, const char* y) noexcept {
609  return x >= StringView(y);
610 }
611 
612 static inline
613 bool operator >= (const char* x, const StringView& y) noexcept {
614  return StringView(x) >= y;
615 }
616 
617 //! \}
618 
619 } // namespace tlx
620 
621 namespace std {
622 template <>
623 struct hash<tlx::StringView> {
624  size_t operator () (const tlx::StringView& sv) const {
625  return tlx::hash_djb2(sv.data(), sv.size());
626  }
627 };
628 
629 } // namespace std
630 
631 #endif // !TLX_CONTAINER_STRING_VIEW_HEADER
632 
633 /******************************************************************************/
bool operator<(const StringView &other) const noexcept
Less operator to compare a StringView with another StringView lexicographically.
const_reverse_iterator reverse_iterator
Definition: string_view.hpp:56
size_type find_first_not_of(char c, size_type pos=0) const noexcept
const_pointer data() const noexcept
size_type find(char c, size_type pos=0) const noexcept
std::ptrdiff_t difference_type
Definition: string_view.hpp:58
StringView(const std::string &str) noexcept
assign a whole string
Definition: string_view.hpp:71
size_type find_first_of(StringView s, size_type pos=0) const noexcept
bool ends_with(char c) const noexcept
size_type find_first_not_of(const char *s, size_type pos=0) const noexcept
size_type rfind(const char *s, size_type pos, size_type n) const noexcept
bool ends_with(StringView x) const noexcept
void clear() noexcept
int compare(StringView x) const noexcept
int compare(size_type pos1, size_type n1, const char *x, size_type n2) const
int compare(const char *x) const
void remove_prefix(size_type n)
static constexpr size_type npos
Definition: string_view.hpp:60
size_type find_first_of(char c, size_type pos=0) const noexcept
StringView substr(size_type pos, size_type n=npos) const
size_type find_first_not_of(StringView s, size_type pos=0) const noexcept
size_type find_last_of(StringView s, size_type pos=npos) const noexcept
size_type rfind(const char *s, size_type pos=npos) const noexcept
const char * ptr_
int compare(size_type pos1, size_type n1, const char *x) const
size_type copy(char *s, size_type n, size_type pos=0) const
STL namespace.
const_reverse_iterator crend() const noexcept
const_iterator begin() const noexcept
Definition: string_view.hpp:97
size_type rfind(char c, size_type pos=npos) const noexcept
bool operator>=(const StringView &other) const noexcept
Less than or equal to.
StringView & operator=(const StringView &rhs) noexcept=default
assignment
static uint32_t hash_djb2(const unsigned char *str)
Simple, fast, but "insecure" string hash method by Dan Bernstein from http://www.cse.yorku.ca/~oz/hash.html.
Definition: hash_djb2.hpp:26
size_type find_last_not_of(const char *s, size_type pos=npos) const noexcept
bool operator<=(const StringView &other) const noexcept
Less than or equal to.
std::string to_string() const
Returns the data of this StringView as a std::string.
const_reference back() const
StringView(const std::string::const_iterator &begin, const std::string::const_iterator &end) noexcept
assign a string between two iterators
Definition: string_view.hpp:90
size_type reverse_distance(r_iter first, r_iter last) const noexcept
void swap(StringView &s) noexcept
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
Definition: string_view.hpp:98
bool starts_with(char c) const noexcept
size_type find(const char *s, size_type pos, size_type n) const noexcept
static uint32_t min(uint32_t x, uint32_t y)
Definition: md5.cpp:32
StringView(const std::string::const_iterator &begin, size_t size) noexcept
assign a string iterator with given length
Definition: string_view.hpp:86
const_iterator end() const noexcept
Definition: string_view.hpp:99
void remove_suffix(size_type n)
StringView(const char *str, size_type size) noexcept
assign a C-style string with given length
Definition: string_view.hpp:82
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...
size_type length() const noexcept
int compare(size_type pos1, size_type n1, StringView x, size_type pos2, size_type n2) const
size_type find_first_of(const char *s, size_type pos, size_type n) const noexcept
bool operator==(const StringView &other) const noexcept
Equality operator to compare a StringView with another StringView.
size_type rfind(StringView s, size_type pos=npos) const noexcept
size_type size() const noexcept
size_type find_first_not_of(const char *s, size_type pos, size_type n) const noexcept
const_reverse_iterator rbegin() const noexcept
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: string_view.hpp:55
StringView is a reference to a part of a string, consisting of only a char pointer and a length...
Definition: string_view.hpp:44
size_type find_last_of(const char *s, size_type pos, size_type n) const noexcept
bool operator!=(const StringView &other) const noexcept
Inequality operator to compare a StringView with another StringView.
const_reverse_iterator crbegin() const noexcept
const_reverse_iterator rend() const noexcept
bool empty() const noexcept
int compare(size_type pos1, size_type n1, StringView x) const noexcept
const_reference operator[](size_type pos) const noexcept
size_type find_last_not_of(char c, size_type pos=npos) const noexcept
Iterator find_not_of(Iterator first, Iterator last, StringView s) const noexcept
StringView(const char *str) noexcept
assign a whole C-style string
Definition: string_view.hpp:78
size_type max_size() const noexcept
const char & const_reference
Definition: string_view.hpp:52
size_type find_last_not_of(const char *s, size_type pos, size_type n) const noexcept
size_type find(const char *s, size_type pos=0) const noexcept
size_type find_last_of(const char *s, size_type pos=npos) const noexcept
StringView() noexcept
default construction
Definition: string_view.hpp:63
bool operator>(const StringView &other) const noexcept
Greater than.
bool starts_with(StringView x) const noexcept
const_pointer const_iterator
Definition: string_view.hpp:53
std::size_t size_type
Definition: string_view.hpp:57
size_type find_last_not_of(StringView s, size_type pos=npos) const noexcept
const_reference at(size_t pos) const
const_reference front() const
size_type find_first_of(const char *s, size_type pos=0) const noexcept
size_type find_last_of(char c, size_type pos=npos) const noexcept
friend std::ostream & operator<<(std::ostream &os, const StringView &v)
const char * const_pointer
Definition: string_view.hpp:50
size_type find(StringView s, size_type pos=0) const noexcept
const_iterator iterator
Definition: string_view.hpp:54