string_view.hpp
Go to the documentation of this file.
1 
14 #ifndef CORE_STRING_VIEW_HPP
15 #define CORE_STRING_VIEW_HPP
16 
17 #include <initializer_list>
18 #include <functional>
19 #include <stdexcept>
20 #include <algorithm>
21 #include <iterator>
22 #include <string>
23 #include <limits>
24 
25 #include <cstdlib>
26 #include <ciso646>
27 
28 #if defined(_MSC_VER)
29  #pragma warning(push)
30  #pragma warning(disable:5030)
31  #pragma warning(disable:4702)
32 #endif /* defined(_MSC_VER) */
33 
34 namespace core {
35 inline namespace v2 {
36 namespace impl {
37 
38 /* implementations of MurmurHash2 *Endian Neutral* (but not alignment!) */
39 template <::std::size_t=sizeof(::std::size_t)> struct murmur;
40 template <> struct murmur<4> {
41  constexpr murmur () = default;
42 
43  ::std::uint32_t operator () (void const* p, ::std::size_t len) const noexcept {
44  static constexpr ::std::uint32_t magic = UINT32_C(0x5BD1E995);
45  static constexpr auto shift = 24;
46 
47  auto hash = static_cast<::std::uint32_t>(len);
48  auto data = static_cast<::std::uint8_t const*>(p);
49 
50  while (len >= sizeof(::std::uint32_t)) {
51  ::std::uint32_t mix = data[0];
52  mix |= ::std::uint32_t(data[1]) << 8;
53  mix |= ::std::uint32_t(data[2]) << 16;
54  mix |= ::std::uint32_t(data[3]) << 24;
55 
56  mix *= magic;
57  mix ^= mix >> shift;
58  mix *= magic;
59 
60  hash *= magic;
61  hash ^= mix;
62 
63  data += sizeof(::std::uint32_t);
64  len -= sizeof(::std::uint32_t);
65  }
66 
67  switch (len) {
68  case 3: hash ^= ::std::uint32_t(data[2]) << 16; [[clang::fallthrough]];
69  case 2: hash ^= ::std::uint32_t(data[1]) << 8; [[clang::fallthrough]];
70  case 1: hash ^= ::std::uint32_t(data[0]);
71  hash *= magic;
72  }
73 
74  hash ^= hash >> 13;
75  hash *= magic;
76  hash ^= hash >> 15;
77 
78  return hash;
79  }
80 };
81 
82 template <> struct murmur<8> {
83  constexpr murmur () = default;
84 
85  ::std::uint64_t operator () (void const* p, ::std::size_t len) const noexcept {
86  static constexpr ::std::uint64_t magic = UINT64_C(0xC6A4A7935BD1E995);
87  static constexpr auto shift = 47;
88 
89  ::std::uint64_t hash = len * magic;
90 
91  auto data = static_cast<::std::uint8_t const*>(p);
92 
93  while (len >= sizeof(::std::uint64_t)) {
94  ::std::uint64_t mix = data[0];
95  mix |= ::std::uint64_t(data[1]) << 8;
96  mix |= ::std::uint64_t(data[2]) << 16;
97  mix |= ::std::uint64_t(data[3]) << 24;
98  mix |= ::std::uint64_t(data[4]) << 32;
99  mix |= ::std::uint64_t(data[5]) << 40;
100  mix |= ::std::uint64_t(data[6]) << 48;
101  mix |= ::std::uint64_t(data[7]) << 54;
102 
103  mix *= magic;
104  mix ^= mix >> shift;
105  mix *= magic;
106 
107  hash ^= mix;
108  hash *= magic;
109 
110  data += sizeof(::std::uint64_t);
111  len -= sizeof(::std::uint64_t);
112  }
113 
114  switch (len & 7) {
115  case 7: hash ^= ::std::uint64_t(data[6]) << 48; [[clang::fallthrough]];
116  case 6: hash ^= ::std::uint64_t(data[5]) << 40; [[clang::fallthrough]];
117  case 5: hash ^= ::std::uint64_t(data[4]) << 32; [[clang::fallthrough]];
118  case 4: hash ^= ::std::uint64_t(data[3]) << 24; [[clang::fallthrough]];
119  case 3: hash ^= ::std::uint64_t(data[2]) << 16; [[clang::fallthrough]];
120  case 2: hash ^= ::std::uint64_t(data[1]) << 8; [[clang::fallthrough]];
121  case 1: hash ^= ::std::uint64_t(data[0]);
122  hash *= magic;
123  }
124 
125  hash ^= hash >> shift;
126  hash *= magic;
127  hash ^= hash >> shift;
128 
129  return hash;
130  }
131 };
132 
133 }}} /* namespace core::v2::impl */
134 
135 namespace core {
136 inline namespace v2 {
137 
138 #ifndef CORE_NO_EXCEPTIONS
139 [[noreturn]] inline void throw_out_of_range (char const* msg) {
140  throw ::std::out_of_range { msg };
141 }
142 #else /* CORE_NO_EXCEPTIONS */
143 [[noreturn]] inline void throw_out_of_range (char const*) { ::std::abort(); }
144 #endif /* CORE_NO_EXCEPTIONS */
145 
146 template <class CharT, class Traits=::std::char_traits<CharT>>
148  using difference_type = ::std::ptrdiff_t;
149  using value_type = CharT;
150  using size_type = ::std::size_t;
151 
152  using reference = value_type const&;
153  using pointer = value_type const*;
154 
157 
160 
161  using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
163 
164  using traits = Traits;
165 
167 
168  template <class Allocator>
170  ::std::basic_string<CharT, Traits, Allocator> const& that
171  ) : str { that.data() }, len { that.size() } { }
172 
173  constexpr basic_string_view (pointer str, size_type len) noexcept :
174  str { str },
175  len { len }
176  { }
177 
178  basic_string_view (pointer str) noexcept :
179  basic_string_view { str, traits::length(str) }
180  { }
181 
182  constexpr basic_string_view (basic_string_view const&) noexcept = default;
183  constexpr basic_string_view () noexcept = default;
184  basic_string_view& operator = (basic_string_view const&) noexcept = default;
185 
186  template <class Allocator>
187  explicit operator ::std::basic_string<CharT, Traits, Allocator> () const {
188  return ::std::basic_string<CharT, Traits, Allocator> {
189  this->data(),
190  this->size()
191  };
192  }
193 
194  template <class Allocator=std::allocator<CharT>>
195  ::std::basic_string<CharT, Traits, Allocator> to_string (
196  Allocator const& allocator = Allocator()
197  ) const {
198  return ::std::basic_string<CharT, Traits, Allocator> {
199  this->data(),
200  this->size(),
201  allocator
202  };
203  }
204 
205  constexpr const_iterator begin () const noexcept { return this->data(); }
206  constexpr const_iterator end () const noexcept {
207  return this->data() + this->size();
208  }
209 
210  constexpr const_iterator cbegin () const noexcept { return this->begin(); }
211  constexpr const_iterator cend () const noexcept { return this->end(); }
212 
213  const_reverse_iterator rbegin () const noexcept {
214  return const_reverse_iterator { this->end()};
215  }
216 
217  const_reverse_iterator rend () const noexcept {
218  return const_reverse_iterator { this->begin() };
219  }
220 
221  const_reverse_iterator crbegin () const noexcept { return this->rbegin(); }
222  const_reverse_iterator crend () const noexcept { return this->rend(); }
223 
224  constexpr size_type max_size () const noexcept {
226  }
227  constexpr size_type length () const noexcept { return this->size(); }
228  constexpr size_type size () const noexcept { return this->len; }
229 
230  constexpr bool empty () const noexcept { return this->size() == 0; }
231 
232  constexpr reference operator [] (size_type idx) const {
233  return this->str[idx];
234  }
235 
236  constexpr reference front () const { return this->str[0]; }
237  constexpr reference back () const { return this->str[this->size() - 1]; }
238  constexpr pointer data () const { return this->str; }
239 
241  if (n > this->size()) { n = this->size(); }
242  this->str += n;
243  this->len -= n;
244  }
245 
247  if (n > this->size()) { n = this->size(); }
248  this->len -= n;
249  }
250 
251  void clear () noexcept {
252  this->str = nullptr;
253  this->len = 0;
254  }
255 
256  size_type copy (CharT* s, size_type n, size_type pos = 0) const {
257  if (pos > this->size()) {
258  throw_out_of_range("position greater than size");
259  }
260  auto const rlen = std::min(n, this->size() - pos);
261  ::std::copy_n(this->begin() + pos, rlen, s);
262  return rlen;
263  }
264 
266  size_type pos=0,
267  size_type n=npos
268  ) const noexcept {
269  return pos > this->size()
270  ? (throw_out_of_range("start position out of range"), *this)
272  this->data() + pos,
273  n == npos or pos + n > this->size()
274  ? (this->size() - pos)
275  : n
276  };
277  }
278 
279  bool starts_with (value_type value) const noexcept {
280  return not this->empty() and traits::eq(value, this->front());
281  }
282 
283  bool ends_with (value_type value) const noexcept {
284  return not this->empty() and traits::eq(value, this->back());
285  }
286 
287  bool starts_with (basic_string_view that) const noexcept {
288  return this->size() >= that.size() and
289  traits::compare(this->data(), that.data(), that.size()) == 0;
290  }
291 
292  bool ends_with (basic_string_view that) const noexcept {
293  return this->size() >= that.size() and
294  traits::compare(
295  this->data() + this->size() - that.size(),
296  that.data(),
297  that.size()
298  ) == 0;
299  }
300 
301  /* compare */
303  auto cmp = traits::compare(
304  this->data(),
305  s.data(),
306  ::std::min(this->size(), s.size())
307  );
308 
309  if (cmp != 0) { return cmp; }
310  if (this->size() == s.size()) { return 0; }
311  if (this->size() < s.size()) { return -1; }
312  return 1;
313  }
314 
316  size_type pos,
317  size_type n,
319  ) const noexcept { return this->substr(pos, n).compare(s); }
320 
322  size_type pos1,
323  size_type n1,
325  size_type pos2,
326  size_type n2
327  ) const noexcept {
328  return this->substr(pos1, n1).compare(s.substr(pos2, n2));
329  }
330 
331  difference_type compare (pointer s) const noexcept {
332  return this->compare(basic_string_view { s });
333  }
334 
336  size_type pos,
337  size_type n,
338  pointer s
339  ) const noexcept {
340  return this->substr(pos, n).compare(basic_string_view { s });
341  }
342 
344  size_type pos,
345  size_type n1,
346  pointer s,
347  size_type n2
348  ) const noexcept {
349  return this->substr(pos, n1).compare(basic_string_view { s, n2 });
350  }
351 
352  reference at (size_type idx) const {
353  static constexpr auto error = "requested index out of range";
354  if (idx >= this->size()) { throw_out_of_range(error); }
355  return this->str[idx];
356  }
357 
358  /* find-first-not-of */
360  basic_string_view str,
361  size_type pos = 0) const noexcept {
362  if (pos > this->size()) { return npos; }
363  auto begin = this->begin() + pos;
364  auto end = this->end();
365  auto const predicate = [str] (value_type v) { return str.find(v) == npos; };
366  auto iter = std::find_if(begin, end, predicate);
367  if (iter == end) { return npos; }
368  return static_cast<size_type>(::std::distance(this->begin(), iter));
369  }
370 
372  pointer s,
373  size_type pos,
374  size_type n) const noexcept {
375  return this->find_first_not_of(basic_string_view { s, n }, pos);
376  }
377 
378  size_type find_first_not_of (pointer s, size_type pos = 0) const noexcept {
379  return this->find_first_not_of(basic_string_view { s }, pos);
380  }
381 
382  size_type find_first_not_of (value_type c, size_type pos = 0) const noexcept {
383  return this->find_first_not_of(
384  basic_string_view { ::std::addressof(c), 1 },
385  pos);
386  }
387 
388  /* find-first-of */
390  basic_string_view str,
391  size_type pos = 0) const noexcept {
392  if (pos > this->size()) { return npos; }
393  auto iter = ::std::find_first_of(
394  this->begin() + pos, this->end(),
395  str.begin(), str.end(),
396  traits::eq);
397  if (iter == this->end()) { return npos; }
398  return static_cast<size_type>(::std::distance(this->begin(), iter));
399  }
400 
401  size_type find_first_of (pointer s, size_type p, size_type n) const noexcept {
402  return this->find_first_of(basic_string_view { s, n }, p);
403  }
404 
405  size_type find_first_of (pointer s, size_type pos = 0) const noexcept {
406  return this->find_first_of(basic_string_view { s }, pos);
407  }
408 
409  size_type find_first_of (value_type c, size_type pos = 0) const noexcept {
410  return this->find_first_of(
411  basic_string_view { ::std::addressof(c), 1 },
412  pos);
413  }
414 
415  /* find */
416  size_type find (basic_string_view str, size_type pos = 0) const noexcept {
417  if (pos >= this->size()) { return npos; }
418  auto iter = ::std::search(
419  this->begin() + pos, this->end(),
420  str.begin(), str.end(),
421  traits::eq);
422  if (iter == this->end()) { return npos; }
423  return static_cast<size_type>(::std::distance(this->begin(), iter));
424  }
425 
426  size_type find (pointer s, size_type p, size_type n) const noexcept {
427  return this->find(basic_string_view { s, n }, p);
428  }
429 
430  size_type find (pointer s, size_type pos = 0) const noexcept {
431  return this->find(basic_string_view { s }, pos);
432  }
433 
434  size_type find (value_type c, size_type pos = 0) const noexcept {
435  return this->find(basic_string_view { ::std::addressof(c), 1 }, pos);
436  }
437 
439  basic_string_view str,
440  size_type pos = npos) const noexcept {
441  auto const offset = this->size() - ::std::min(this->size(), pos);
442  auto begin = this->rbegin() + static_cast<difference_type>(offset);
443  auto end = this->rend();
444  auto const predicate = [str] (value_type v) { return str.find(v) == npos; };
445  auto iter = ::std::find_if(begin, end, predicate);
446  if (iter == end) { return npos; }
447  auto const distance = static_cast<size_type>(
448  ::std::distance(this->rbegin(), iter));
449  return this->size() - distance - 1;
450  }
451 
453  pointer s,
454  size_type p,
455  size_type n) const noexcept {
456  return this->find_last_not_of(basic_string_view { s, n }, p);
457  }
458 
459  size_type find_last_not_of (pointer s, size_type p = npos) const noexcept {
460  return this->find_last_not_of(basic_string_view { s }, p);
461  }
462 
464  value_type c,
465  size_type pos = npos) const noexcept {
466  return this->find_last_not_of(
467  basic_string_view { ::std::addressof(c), 1 },
468  pos);
469  }
470 
472  basic_string_view str,
473  size_type pos = npos) const noexcept {
474  auto const offset = this->size() - ::std::min(this->size(), pos);
475  auto begin = this->rbegin() + static_cast<difference_type>(offset);
476  auto end = this->rend();
477 
478  auto iter = ::std::find_first_of(
479  begin, end,
480  str.rbegin(), str.rend(),
481  traits::eq);
482  if (iter == end) { return npos; }
483  auto const distance = static_cast<size_type>(
484  ::std::distance(this->rbegin(), iter));
485  return this->size() - distance - 1;
486  }
487 
488  size_type find_last_of (pointer s, size_type p, size_type n) const noexcept {
489  return this->find_last_of(basic_string_view { s, n }, p);
490  }
491 
492  size_type find_last_of (pointer s, size_type p=npos) const noexcept {
493  return this->find_last_of(basic_string_view { s }, p);
494  }
495 
496  size_type find_last_of (value_type c, size_type p=npos) const noexcept {
497  return this->find_last_of(basic_string_view { ::std::addressof(c), 1 }, p);
498  }
499 
500  size_type rfind (basic_string_view str, size_type pos=npos) const noexcept {
501  auto const offset = this->size() - ::std::min(this->size(), pos);
502  auto begin = this->rbegin() + offset;
503  auto end = this->rend();
504  auto iter = ::std::search(
505  begin, end,
506  str.rbegin(), str.rend(),
507  traits::eq);
508  if (iter == end) { return npos; }
509  auto const distance = static_cast<size_type>(
510  ::std::distance(this->rbegin(), iter));
511  return this->size() - distance - 1;
512  }
513 
514  size_type rfind (pointer s, size_type p, size_type n) const noexcept {
515  return this->rfind(basic_string_view { s, n }, p);
516  }
517 
518  size_type rfind (pointer s, size_type p=npos) const noexcept {
519  return this->rfind(basic_string_view { s }, p);
520  }
521 
522  size_type rfind (value_type c, size_type p=npos) const noexcept {
523  return this->rfind(basic_string_view { ::std::addressof(c), 1 }, p);
524  }
525 
526  void swap (basic_string_view& that) noexcept {
528  swap(this->str, that.str);
529  swap(this->len, that.len);
530  }
531 
532 private:
533  pointer str { nullptr };
534  size_type len { 0 };
535 };
536 
541 
542 /* string_view comparison string_view */
543 template <class CharT, typename Traits>
547 ) noexcept { return lhs.size() == rhs.size() and lhs.compare(rhs) == 0; }
548 
549 template <class CharT, typename Traits>
553 ) noexcept { return lhs.size() != rhs.size() or lhs.compare(rhs) != 0; }
554 
555 template <class CharT, typename Traits>
559 ) noexcept { return lhs.compare(rhs) >= 0; }
560 
561 template <class CharT, typename Traits>
565 ) noexcept { return lhs.compare(rhs) <= 0; }
566 
567 template <class CharT, typename Traits>
571 ) noexcept { return lhs.compare(rhs) > 0; }
572 
573 template <class CharT, typename Traits>
577 ) noexcept { return lhs.compare(rhs) < 0; }
578 
579 /* string_view comparison string */
580 template <class CharT, class Traits, class Allocator>
583  ::std::basic_string<CharT, Traits, Allocator> const& rhs
584 ) noexcept { return lhs == basic_string_view<CharT, Traits> { rhs }; }
585 
586 template <class CharT, class Traits, class Allocator>
589  ::std::basic_string<CharT, Traits, Allocator> const& rhs
590 ) noexcept { return lhs != basic_string_view<CharT, Traits> { rhs }; }
591 
592 template <class CharT, class Traits, class Allocator>
595  ::std::basic_string<CharT, Traits, Allocator> const& rhs
596 ) noexcept { return lhs >= basic_string_view<CharT, Traits> { rhs }; }
597 
598 template <class CharT, class Traits, class Allocator>
601  ::std::basic_string<CharT, Traits, Allocator> const& rhs
602 ) noexcept { return lhs <= basic_string_view<CharT, Traits> { rhs }; }
603 
604 template <class CharT, class Traits, class Allocator>
607  ::std::basic_string<CharT, Traits, Allocator> const& rhs
608 ) noexcept { return lhs > basic_string_view<CharT, Traits> { rhs }; }
609 
610 template <class CharT, class Traits, class Allocator>
613  ::std::basic_string<CharT, Traits, Allocator> const& rhs
614 ) noexcept { return lhs < basic_string_view<CharT, Traits> { rhs }; }
615 
616 /* string comparison string_view */
617 template <class CharT, class Traits, class Allocator>
619  ::std::basic_string<CharT, Traits, Allocator> const& lhs,
621 ) noexcept { return basic_string_view<CharT, Traits> { lhs } == rhs; }
622 
623 template <class CharT, class Traits, class Allocator>
625  ::std::basic_string<CharT, Traits, Allocator> const& lhs,
627 ) noexcept { return basic_string_view<CharT, Traits> { lhs } != rhs; }
628 
629 template <class CharT, class Traits, class Allocator>
631  ::std::basic_string<CharT, Traits, Allocator> const& lhs,
633 ) noexcept { return basic_string_view<CharT, Traits> { lhs } >= rhs; }
634 
635 template <class CharT, class Traits, class Allocator>
637  ::std::basic_string<CharT, Traits, Allocator> const& lhs,
639 ) noexcept { return basic_string_view<CharT, Traits> { lhs } <= rhs; }
640 
641 template <class CharT, class Traits, class Allocator>
643  ::std::basic_string<CharT, Traits, Allocator> const& lhs,
645 ) noexcept { return basic_string_view<CharT, Traits> { lhs } > rhs; }
646 
647 template <class CharT, class Traits, class Allocator>
649  ::std::basic_string<CharT, Traits, Allocator> const& lhs,
651 ) noexcept { return basic_string_view<CharT, Traits> { lhs } < rhs; }
652 
653 /* string_view comparison CharT* */
654 template <class CharT, class Traits>
657  CharT const* rhs
658 ) noexcept { return lhs == basic_string_view<CharT, Traits> { rhs }; }
659 
660 template <class CharT, class Traits>
663  CharT const* rhs
664 ) noexcept { return lhs != basic_string_view<CharT, Traits> { rhs }; }
665 
666 template <class CharT, class Traits>
669  CharT const* rhs
670 ) noexcept { return lhs >= basic_string_view<CharT, Traits> { rhs }; }
671 
672 template <class CharT, class Traits>
675  CharT const* rhs
676 ) noexcept { return lhs <= basic_string_view<CharT, Traits> { rhs }; }
677 
678 template <class CharT, class Traits>
681  CharT const* rhs
682 ) noexcept { return lhs > basic_string_view<CharT, Traits> { rhs }; }
683 
684 template <class CharT, class Traits>
687  CharT const* rhs
688 ) noexcept { return lhs < basic_string_view<CharT, Traits> { rhs }; }
689 
690 /* CharT* comparison string_view */
691 template <class CharT, class Traits>
693  CharT const* lhs,
695 ) noexcept { return basic_string_view<CharT, Traits> { lhs } == rhs; }
696 
697 template <class CharT, class Traits>
699  CharT const* lhs,
701 ) noexcept { return basic_string_view<CharT, Traits> { lhs } != rhs; }
702 
703 template <class CharT, class Traits>
705  CharT const* lhs,
707 ) noexcept { return basic_string_view<CharT, Traits> { lhs } >= rhs; }
708 
709 template <class CharT, class Traits>
711  CharT const* lhs,
713 ) noexcept { return basic_string_view<CharT, Traits> { lhs } <= rhs; }
714 
715 template <class CharT, class Traits>
717  CharT const* lhs,
719 ) noexcept { return basic_string_view<CharT, Traits> { lhs } > rhs; }
720 
721 template <class CharT, class Traits>
723  CharT const* lhs,
725 ) noexcept { return basic_string_view<CharT, Traits> { lhs } < rhs; }
726 
727 template <class CharT, class Traits>
728 ::std::basic_ostream<CharT, Traits>& operator << (
729  ::std::basic_ostream<CharT, Traits>& os,
731 ) { return os << str.to_string(); }
732 
733 template <class CharT, class Traits>
734 void swap (
737 ) noexcept { return lhs.swap(rhs); }
738 
739 }} /* namespace core::v2 */
740 
741 namespace std {
742 
743 template <typename CharT, typename Traits>
744 struct hash<core::v2::basic_string_view<CharT, Traits>> {
746  using result_type = size_t;
747 
748  result_type operator ()(argument_type const& ref) const noexcept {
749  static constexpr core::impl::murmur<sizeof(size_t)> hasher { };
750  return hasher(ref.data(), ref.size());
751  }
752 };
753 
754 } /* namespace std */
755 
756 
757 #if defined(_MSC_VER)
758  #pragma warning(pop)
759 #endif /* defined(_MSC_VER) */
760 #endif /* CORE_STRING_VIEW_HPP */
basic_string_view(pointer str) noexcept
basic_string_view(::std::basic_string< CharT, Traits, Allocator > const &that)
constexpr bool empty(Container const &container) noexcept
Definition: iterator.hpp:37
size_type rfind(basic_string_view str, size_type pos=npos) const noexcept
value_type const & reference
auto rbegin(Container const &container) -> decltype(container.rbegin())
Definition: iterator.hpp:106
typename impl::find_if< T, F >::type find_if
Definition: meta.hpp:233
void swap(basic_string_view &that) noexcept
constexpr auto size(Container const &container) noexcept -> decltype(container.size())
Definition: iterator.hpp:29
const_reverse_iterator rbegin() const noexcept
constexpr const_iterator cend() const noexcept
size_type find_last_not_of(basic_string_view str, size_type pos=npos) const noexcept
constexpr basic_string_view(pointer str, size_type len) noexcept
size_type find_first_of(value_type c, size_type pos=0) const noexcept
size_type find_first_not_of(pointer s, size_type pos, size_type n) const noexcept
constexpr size_type size() const noexcept
difference_type compare(size_type pos, size_type n, basic_string_view s) const noexcept
::std::basic_ostream< CharT, Traits > & operator<<(::std::basic_ostream< CharT, Traits > &os, basic_string_view< CharT, Traits > const &str)
difference_type compare(size_type pos1, size_type n1, basic_string_view s, size_type pos2, size_type n2) const noexcept
size_type find_last_of(basic_string_view str, size_type pos=npos) const noexcept
size_type find_first_of(pointer s, size_type pos=0) const noexcept
Copyright © 2013 - 2015 MNMLSTC.
Definition: algorithm.hpp:23
size_type find_first_of(pointer s, size_type p, size_type n) const noexcept
constexpr pointer data() const
const_reverse_iterator crbegin() const noexcept
bool operator>(basic_string_view< CharT, Traits > lhs, basic_string_view< CharT, Traits > rhs) noexcept
::std::reverse_iterator< const_iterator > const_reverse_iterator
size_type find_last_not_of(pointer s, size_type p=npos) const noexcept
void throw_out_of_range(char const *msg)
constexpr reference back() const
constexpr T const & max(T const &lhs, T const &rhs)
Definition: algorithm.hpp:79
constexpr basic_string_view substr(size_type pos=0, size_type n=npos) const noexcept
size_type find(pointer s, size_type p, size_type n) const noexcept
size_type find_first_not_of(value_type c, size_type pos=0) const noexcept
value_type const * pointer
size_type find_first_not_of(basic_string_view str, size_type pos=0) const noexcept
bool ends_with(value_type value) const noexcept
size_type rfind(value_type c, size_type p=npos) const noexcept
difference_type compare(size_type pos, size_type n, pointer s) const noexcept
size_type find_first_not_of(pointer s, size_type pos=0) const noexcept
bool starts_with(basic_string_view that) const noexcept
bool ends_with(basic_string_view that) const noexcept
size_type find_last_of(value_type c, size_type p=npos) const noexcept
size_type find_last_not_of(value_type c, size_type pos=npos) const noexcept
bool operator>=(basic_string_view< CharT, Traits > lhs, basic_string_view< CharT, Traits > rhs) noexcept
::std::basic_string< CharT, Traits, Allocator > to_string(Allocator const &allocator=Allocator()) const
constexpr auto data(Container const &container) noexcept -> decltype(container.data())
Definition: iterator.hpp:79
size_type find(pointer s, size_type pos=0) const noexcept
bool operator==(basic_string_view< CharT, Traits > lhs, basic_string_view< CharT, Traits > rhs) noexcept
reference at(size_type idx) const
auto search(Range1 &&rng1, Range2 &&rng2) -> meta::when< meta::all_of< meta::list< Range1, Range2 >, is_range >(), decltype(::std::begin(::core::forward< Range1 >(rng1))) >
Definition: algorithm.hpp:599
size_type copy(CharT *s, size_type n, size_type pos=0) const
auto find(Range &&rng, T const &value) -> enable_if_t< is_range< Range >::value, decltype(::std::begin(::core::forward< Range >(rng))) >
Definition: algorithm.hpp:450
constexpr reference front() const
size_type find_last_not_of(pointer s, size_type p, size_type n) const noexcept
difference_type compare(pointer s) const noexcept
size_type find(basic_string_view str, size_type pos=0) const noexcept
constexpr const_iterator cbegin() const noexcept
void swap(any &lhs, any &rhs) noexcept
Definition: any.hpp:333
bool starts_with(value_type value) const noexcept
const_reverse_iterator reverse_iterator
constexpr auto front(Container const &container) -> decltype(container.front())
Definition: iterator.hpp:46
constexpr const_iterator end() const noexcept
size_type find_last_of(pointer s, size_type p, size_type n) const noexcept
bool operator<=(basic_string_view< CharT, Traits > lhs, basic_string_view< CharT, Traits > rhs) noexcept
constexpr const_iterator begin() const noexcept
constexpr size_type length() const noexcept
size_type rfind(pointer s, size_type p=npos) const noexcept
auto find_first_of(IRange &&irng, FRange &&frng) -> meta::when< meta::all_of< meta::list< IRange, FRange >, is_range >(), decltype(::std::begin(::core::forward< IRange >(irng))) >
Definition: algorithm.hpp:530
void remove_prefix(size_type n)
const_reverse_iterator rend() const noexcept
constexpr auto back(Container const &container) -> decltype(container.back())
Definition: iterator.hpp:62
difference_type compare(size_type pos, size_type n1, pointer s, size_type n2) const noexcept
size_type find_first_of(basic_string_view str, size_type pos=0) const noexcept
difference_type compare(basic_string_view s) const noexcept
constexpr bool empty() const noexcept
constexpr T const & min(T const &lhs, T const &rhs)
Definition: algorithm.hpp:69
size_type find_last_of(pointer s, size_type p=npos) const noexcept
const_reverse_iterator crend() const noexcept
size_type rfind(pointer s, size_type p, size_type n) const noexcept
void remove_suffix(size_type n)
constexpr size_type max_size() const noexcept
size_type find(value_type c, size_type pos=0) const noexcept
bool operator!=(basic_string_view< CharT, Traits > lhs, basic_string_view< CharT, Traits > rhs) noexcept
void swap(basic_string_view< CharT, Traits > &lhs, basic_string_view< CharT, Traits > &rhs) noexcept
auto rend(Container const &container) -> decltype(container.rend())
Definition: iterator.hpp:121
bool operator<(basic_string_view< CharT, Traits > lhs, basic_string_view< CharT, Traits > rhs) noexcept
::std::ptrdiff_t difference_type