24 #ifndef GUL14_STRING_VIEW_H_
25 #define GUL14_STRING_VIEW_H_
48 template <
typename charT,
typename traits>
49 class string_view_traits_eq {
51 string_view_traits_eq ( charT ch ) : ch_(ch) {}
52 bool operator()( charT val )
const {
return traits::eq (ch_, val); }
59 template <
typename charT,
typename BaseT = std::
char_traits<
charT>>
60 struct char_traits :
public BaseT
62 using char_type =
typename BaseT::char_type;
63 using int_type =
typename BaseT::int_type;
64 using pos_type =
typename BaseT::pos_type;
65 using off_type =
typename BaseT::off_type;
66 using state_type =
typename BaseT::state_type;
68 using base_traits = BaseT;
73 static constexpr
void assign(char_type& c1,
const char_type& c2) noexcept
78 static constexpr
int compare(
const char_type* s1,
const char_type* s2,
size_t n) noexcept
80 for (;n > 0; --n, ++s1, ++s2) {
83 else if (lt(*s2, *s1))
89 static constexpr
size_t length(
const char_type* s) noexcept
91 auto len = std::size_t{ };
92 while (!eq(s[len], char_type{ }))
97 static constexpr
const char_type* find(
const char_type* s, std::size_t n,
const char_type& a) noexcept
99 for (;n > 0; --n, ++s) {
113 template<
typename charT,
typename traits = gul14::
char_traits<
charT>>
117 typedef traits traits_type;
118 typedef charT value_type;
119 typedef charT* pointer;
120 typedef const charT* const_pointer;
121 typedef charT& reference;
122 typedef const charT& const_reference;
123 typedef const_pointer const_iterator;
124 typedef const_iterator iterator;
125 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
126 typedef const_reverse_iterator reverse_iterator;
127 typedef std::size_t size_type;
128 typedef std::ptrdiff_t difference_type;
129 static constexpr size_type npos = size_type(-1);
133 : ptr_(NULL), len_(0) {}
141 template<
typename Allocator,
typename Traits>
143 Allocator>& str) noexcept
144 : ptr_(str.data()), len_(str.length()) {}
147 : ptr_(str), len_(traits::length(str)) {}
150 : ptr_(str), len_(len) {}
153 constexpr const_iterator begin()
const noexcept {
return ptr_; }
154 constexpr const_iterator cbegin()
const noexcept {
return ptr_; }
155 constexpr const_iterator end()
const noexcept {
return ptr_ + len_; }
156 constexpr const_iterator cend()
const noexcept {
return ptr_ + len_; }
157 const_reverse_iterator rbegin()
const noexcept {
return const_reverse_iterator(end()); }
158 const_reverse_iterator crbegin()
const noexcept {
return const_reverse_iterator(end()); }
159 const_reverse_iterator rend()
const noexcept {
return const_reverse_iterator(begin()); }
160 const_reverse_iterator crend()
const noexcept {
return const_reverse_iterator(begin()); }
163 constexpr size_type size()
const noexcept {
return len_; }
164 constexpr size_type length()
const noexcept {
return len_; }
165 constexpr size_type max_size()
const noexcept {
return len_; }
166 constexpr
bool empty()
const noexcept {
return len_ == 0; }
169 constexpr const_reference operator[](size_type pos)
const noexcept {
return ptr_[pos]; }
171 constexpr const_reference at(
size_t pos)
const {
172 return pos >= len_ ?
throw std::out_of_range(
"gul14::string_view::at") : ptr_[pos];
175 constexpr const_reference front()
const {
return ptr_[0]; }
176 constexpr const_reference back()
const {
return ptr_[len_-1]; }
177 constexpr const_pointer data()
const noexcept {
return ptr_; }
180 constexpr
void remove_prefix(size_type n) {
187 constexpr
void remove_suffix(size_type n) {
199 template<
typename Allocator>
200 explicit operator std::basic_string<charT, typename traits::base_traits, Allocator>()
const {
201 return std::basic_string<charT, typename traits::base_traits, Allocator>(begin(), end());
204 size_type copy(charT* s, size_type n, size_type pos=0)
const {
206 throw std::out_of_range(
"string_view::copy" );
207 size_type rlen = (std::min)(n, len_ - pos);
210 std::copy(begin() + pos, begin() + pos + rlen, s);
216 throw std::out_of_range (
"string_view::substr" );
217 if (n == npos || pos + n > size())
223 const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
224 return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
229 return substr(pos1, n1).compare(x);
232 constexpr
int compare(size_type pos1, size_type n1,
234 return substr(pos1, n1).compare(x.substr(pos2, n2));
237 constexpr
int compare(
const charT* x)
const {
241 constexpr
int compare(size_type pos1, size_type n1,
const charT* x)
const {
245 constexpr
int compare(size_type pos1, size_type n1,
246 const charT* x, size_type n2)
const {
251 constexpr size_type find(
basic_string_view s, size_type pos = 0)
const noexcept {
258 auto const end = len_ - s.len_;
259 for (
auto cur = pos; cur <= end; ++cur) {
260 if (traits::compare(ptr_ + cur, s.ptr_, s.len_) == 0)
265 constexpr size_type find(charT c, size_type pos = 0)
const noexcept
267 constexpr size_type find(
const charT* s, size_type pos, size_type n)
const noexcept
269 constexpr size_type find(
const charT* s, size_type pos = 0)
const noexcept
273 constexpr size_type rfind(
basic_string_view s, size_type pos = npos)
const noexcept {
276 if (pos > len_ - s.len_)
280 for (
const charT* cur = ptr_ + pos; ; --cur) {
281 if (traits::compare(cur, s.ptr_, s.len_) == 0)
287 constexpr size_type rfind(charT c, size_type pos = npos)
const noexcept
289 constexpr size_type rfind(
const charT* s, size_type pos, size_type n)
const noexcept
291 constexpr size_type rfind(
const charT* s, size_type pos = npos)
const noexcept
295 constexpr size_type find_first_of(
basic_string_view s, size_type pos = 0)
const noexcept {
296 if (pos >= len_ || s.len_ == 0)
298 const_iterator iter = std::find_first_of
299 (this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
300 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
302 constexpr size_type find_first_of(charT c, size_type pos = 0)
const noexcept
304 constexpr size_type find_first_of(
const charT* s, size_type pos, size_type n)
const noexcept
306 constexpr size_type find_first_of(
const charT* s, size_type pos = 0)
const noexcept
310 constexpr size_type find_last_of(
basic_string_view s, size_type pos = npos)
const noexcept {
316 pos = len_ - (pos+1);
317 const_reverse_iterator iter = std::find_first_of
318 ( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
319 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
321 constexpr size_type find_last_of(charT c, size_type pos = npos)
const noexcept
323 constexpr size_type find_last_of(
const charT* s, size_type pos, size_type n)
const noexcept
325 constexpr size_type find_last_of(
const charT* s, size_type pos = npos)
const noexcept
329 constexpr size_type find_first_not_of(
basic_string_view s, size_type pos = 0)
const noexcept {
334 const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
335 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
337 constexpr size_type find_first_not_of(charT c, size_type pos = 0)
const noexcept
339 constexpr size_type find_first_not_of(
const charT* s, size_type pos, size_type n)
const noexcept
341 constexpr size_type find_first_not_of(
const charT* s, size_type pos = 0)
const noexcept
345 constexpr size_type find_last_not_of(
basic_string_view s, size_type pos = npos)
const noexcept {
350 pos = len_ - (pos+1);
351 const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
352 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
354 constexpr size_type find_last_not_of(charT c, size_type pos = npos)
const noexcept
356 constexpr size_type find_last_not_of(
const charT* s, size_type pos, size_type n)
const noexcept
358 constexpr size_type find_last_not_of(
const charT* s, size_type pos = npos)
const noexcept
362 template <
typename r_iter>
363 size_type reverse_distance(r_iter first, r_iter last)
const noexcept {
365 return len_ - 1 - std::distance ( first, last );
368 template <
typename Iterator>
369 Iterator find_not_of(Iterator first, Iterator last,
basic_string_view s)
const noexcept {
370 for (; first != last ; ++first)
371 if ( 0 == traits::find(s.ptr_, s.len_, *first))
384 template<
typename charT,
typename traits>
387 if (x.size () != y.size ())
return false;
388 return x.compare(y) == 0;
392 template<
typename charT,
typename traits>
393 inline bool operator!=(basic_string_view<charT, traits> x,
394 basic_string_view<charT, traits> y) noexcept {
395 if ( x.size () != y.size ())
return true;
396 return x.compare(y) != 0;
400 template<
typename charT,
typename traits>
401 inline bool operator<(basic_string_view<charT, traits> x,
402 basic_string_view<charT, traits> y) noexcept {
403 return x.compare(y) < 0;
407 template<
typename charT,
typename traits>
408 inline bool operator>(basic_string_view<charT, traits> x,
409 basic_string_view<charT, traits> y) noexcept {
410 return x.compare(y) > 0;
414 template<
typename charT,
typename traits>
415 inline bool operator<=(basic_string_view<charT, traits> x,
416 basic_string_view<charT, traits> y) noexcept {
417 return x.compare(y) <= 0;
421 template<
typename charT,
typename traits>
422 inline bool operator>=(basic_string_view<charT, traits> x,
423 basic_string_view<charT, traits> y) noexcept {
424 return x.compare(y) >= 0;
428 template<
typename charT,
typename traits,
typename Allocator>
429 inline bool operator==(basic_string_view<charT, traits> x,
430 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
431 return x == basic_string_view<charT, traits>(y);
434 template<
typename charT,
typename traits,
typename Allocator>
435 inline bool operator==(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
436 basic_string_view<charT, traits> y) noexcept {
437 return basic_string_view<charT, traits>(x) == y;
440 template<
typename charT,
typename traits>
441 inline bool operator==(basic_string_view<charT, traits> x,
442 const charT * y) noexcept {
443 return x == basic_string_view<charT, traits>(y);
446 template<
typename charT,
typename traits>
447 inline bool operator==(
const charT * x,
448 basic_string_view<charT, traits> y) noexcept {
449 return basic_string_view<charT, traits>(x) == y;
452 template<
typename charT,
typename traits,
typename Allocator>
453 inline bool operator!=(basic_string_view<charT, traits> x,
454 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
455 return x != basic_string_view<charT, traits>(y);
458 template<
typename charT,
typename traits,
typename Allocator>
459 inline bool operator!=(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
460 basic_string_view<charT, traits> y) noexcept {
461 return basic_string_view<charT, traits>(x) != y;
464 template<
typename charT,
typename traits>
465 inline bool operator!=(basic_string_view<charT, traits> x,
466 const charT * y) noexcept {
467 return x != basic_string_view<charT, traits>(y);
470 template<
typename charT,
typename traits>
471 inline bool operator!=(
const charT * x,
472 basic_string_view<charT, traits> y) noexcept {
473 return basic_string_view<charT, traits>(x) != y;
476 template<
typename charT,
typename traits,
typename Allocator>
477 inline bool operator<(basic_string_view<charT, traits> x,
478 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
479 return x < basic_string_view<charT, traits>(y);
482 template<
typename charT,
typename traits,
typename Allocator>
483 inline bool operator<(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
484 basic_string_view<charT, traits> y) noexcept {
485 return basic_string_view<charT, traits>(x) < y;
488 template<
typename charT,
typename traits>
489 inline bool operator<(basic_string_view<charT, traits> x,
490 const charT * y) noexcept {
491 return x < basic_string_view<charT, traits>(y);
494 template<
typename charT,
typename traits>
495 inline bool operator<(
const charT * x,
496 basic_string_view<charT, traits> y) noexcept {
497 return basic_string_view<charT, traits>(x) < y;
500 template<
typename charT,
typename traits,
typename Allocator>
501 inline bool operator>(basic_string_view<charT, traits> x,
502 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
503 return x > basic_string_view<charT, traits>(y);
506 template<
typename charT,
typename traits,
typename Allocator>
507 inline bool operator>(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
508 basic_string_view<charT, traits> y) noexcept {
509 return basic_string_view<charT, traits>(x) > y;
512 template<
typename charT,
typename traits>
513 inline bool operator>(basic_string_view<charT, traits> x,
514 const charT * y) noexcept {
515 return x > basic_string_view<charT, traits>(y);
518 template<
typename charT,
typename traits>
519 inline bool operator>(
const charT * x,
520 basic_string_view<charT, traits> y) noexcept {
521 return basic_string_view<charT, traits>(x) > y;
524 template<
typename charT,
typename traits,
typename Allocator>
525 inline bool operator<=(basic_string_view<charT, traits> x,
526 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
527 return x <= basic_string_view<charT, traits>(y);
530 template<
typename charT,
typename traits,
typename Allocator>
531 inline bool operator<=(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
532 basic_string_view<charT, traits> y) noexcept {
533 return basic_string_view<charT, traits>(x) <= y;
536 template<
typename charT,
typename traits>
537 inline bool operator<=(basic_string_view<charT, traits> x,
538 const charT * y) noexcept {
539 return x <= basic_string_view<charT, traits>(y);
542 template<
typename charT,
typename traits>
543 inline bool operator<=(
const charT * x,
544 basic_string_view<charT, traits> y) noexcept {
545 return basic_string_view<charT, traits>(x) <= y;
548 template<
typename charT,
typename traits,
typename Allocator>
549 inline bool operator>=(basic_string_view<charT, traits> x,
550 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
551 return x >= basic_string_view<charT, traits>(y);
554 template<
typename charT,
typename traits,
typename Allocator>
555 inline bool operator>=(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
556 basic_string_view<charT, traits> y) noexcept {
557 return basic_string_view<charT, traits>(x) >= y;
560 template<
typename charT,
typename traits>
561 inline bool operator>=(basic_string_view<charT, traits> x,
562 const charT * y) noexcept {
563 return x >= basic_string_view<charT, traits>(y);
566 template<
typename charT,
typename traits>
567 inline bool operator>=(
const charT * x,
568 basic_string_view<charT, traits> y) noexcept {
569 return basic_string_view<charT, traits>(x) >= y;
574 template<
class charT,
class traits>
575 inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
576 enum { chunk_size = 8 };
577 charT fill_chars[chunk_size];
578 std::fill_n(fill_chars,
static_cast< std::size_t
>(chunk_size), os.fill());
579 for (; n >= chunk_size && os.good(); n -= chunk_size)
580 os.write(fill_chars,
static_cast< std::size_t
>(chunk_size));
581 if (n > 0 && os.good())
582 os.write(fill_chars, n);
585 template<
class charT,
class traits>
586 void sv_insert_aligned(std::basic_ostream<charT,
typename char_traits<charT>::base_traits>& os,
const basic_string_view<charT,traits>& str) {
587 const std::size_t size = str.size();
588 const std::size_t alignment_size =
static_cast< std::size_t
>(os.width()) - size;
589 const bool align_left = (os.flags() & std::basic_ostream<charT, typename char_traits<charT>::base_traits>::adjustfield)
590 == std::basic_ostream<charT,
typename char_traits<charT>::base_traits>::left;
592 detail::sv_insert_fill_chars(os, alignment_size);
594 os.write(str.data(), size);
597 os.write(str.data(), size);
599 detail::sv_insert_fill_chars(os, alignment_size);
606 template<
class charT,
class traits>
607 inline std::basic_ostream<charT, typename char_traits<charT>::base_traits>&
608 operator<<(std::basic_ostream<charT,
typename char_traits<charT>::base_traits>& os,
609 const basic_string_view<charT,traits>& str) {
611 const std::size_t size = str.size();
612 const std::size_t w =
static_cast< std::size_t
>(os.width());
614 os.write(str.data(), size);
616 detail::sv_insert_aligned(os, str);
659 inline std::string &operator+=(std::string &a,
string_view b)
661 a.append(b.begin(), b.end());
665 inline std::string operator+(std::string a,
string_view b)
671 inline std::string operator+(
string_view a, std::string b)
673 b.insert(b.begin(), a.begin(), a.end());
A view to a contiguous sequence of chars or char-like objects.
Definition: string_view.h:114
void swap(SmallVector< ElementT, in_capacity > &a, SmallVector< ElementT, in_capacity > &b)
Exchange the contents of one SmallVector with those of another one.
Definition: SmallVector.h:1656
basic_string_view< char > string_view
A view to a contiguous sequence of chars.
Definition: string_view.h:630
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26