24 #ifndef GUL14_STRING_VIEW_H_
25 #define GUL14_STRING_VIEW_H_
41 template <
typename charT,
typename traits>
42 class string_view_traits_eq {
44 string_view_traits_eq ( charT ch ) : ch_(ch) {}
45 bool operator()( charT val )
const {
return traits::eq (ch_, val); }
52 template <
typename charT,
typename BaseT = std::
char_traits<
charT>>
53 struct char_traits :
public BaseT
55 using char_type =
typename BaseT::char_type;
56 using int_type =
typename BaseT::int_type;
57 using pos_type =
typename BaseT::pos_type;
58 using off_type =
typename BaseT::off_type;
59 using state_type =
typename BaseT::state_type;
61 using base_traits = BaseT;
66 static constexpr
void assign(char_type& c1,
const char_type& c2) noexcept
71 static constexpr
int compare(
const char_type* s1,
const char_type* s2,
size_t n) noexcept
73 for (;n > 0; --n, ++s1, ++s2) {
76 else if (lt(*s2, *s1))
82 static constexpr
size_t length(
const char_type* s) noexcept
84 auto len = std::size_t{ };
85 while (!eq(s[len], char_type{ }))
90 static constexpr
const char_type* find(
const char_type* s, std::size_t n,
const char_type& a) noexcept
92 for (;n > 0; --n, ++s) {
106 template<
typename charT,
typename traits = gul14::
char_traits<
charT>>
110 typedef traits traits_type;
111 typedef charT value_type;
112 typedef charT* pointer;
113 typedef const charT* const_pointer;
114 typedef charT& reference;
115 typedef const charT& const_reference;
116 typedef const_pointer const_iterator;
117 typedef const_iterator iterator;
118 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
119 typedef const_reverse_iterator reverse_iterator;
120 typedef std::size_t size_type;
121 typedef std::ptrdiff_t difference_type;
122 static constexpr size_type npos = size_type(-1);
126 : ptr_(NULL), len_(0) {}
134 template<
typename Allocator,
typename Traits>
136 Allocator>& str) noexcept
137 : ptr_(str.data()), len_(str.length()) {}
140 : ptr_(str), len_(traits::length(str)) {}
143 : ptr_(str), len_(len) {}
146 constexpr const_iterator begin()
const noexcept {
return ptr_; }
147 constexpr const_iterator cbegin()
const noexcept {
return ptr_; }
148 constexpr const_iterator end()
const noexcept {
return ptr_ + len_; }
149 constexpr const_iterator cend()
const noexcept {
return ptr_ + len_; }
150 const_reverse_iterator rbegin()
const noexcept {
return const_reverse_iterator(end()); }
151 const_reverse_iterator crbegin()
const noexcept {
return const_reverse_iterator(end()); }
152 const_reverse_iterator rend()
const noexcept {
return const_reverse_iterator(begin()); }
153 const_reverse_iterator crend()
const noexcept {
return const_reverse_iterator(begin()); }
156 constexpr size_type size()
const noexcept {
return len_; }
157 constexpr size_type length()
const noexcept {
return len_; }
158 constexpr size_type max_size()
const noexcept {
return len_; }
159 constexpr
bool empty()
const noexcept {
return len_ == 0; }
162 constexpr const_reference operator[](size_type pos)
const noexcept {
return ptr_[pos]; }
164 constexpr const_reference at(
size_t pos)
const {
165 return pos >= len_ ?
throw std::out_of_range(
"gul14::string_view::at") : ptr_[pos];
168 constexpr const_reference front()
const {
return ptr_[0]; }
169 constexpr const_reference back()
const {
return ptr_[len_-1]; }
170 constexpr const_pointer data()
const noexcept {
return ptr_; }
173 constexpr
void remove_prefix(size_type n) {
180 constexpr
void remove_suffix(size_type n) {
192 template<
typename Allocator>
193 explicit operator std::basic_string<charT, typename traits::base_traits, Allocator>()
const {
194 return std::basic_string<charT, typename traits::base_traits, Allocator>(begin(), end());
197 size_type copy(charT* s, size_type n, size_type pos=0)
const {
199 throw std::out_of_range(
"string_view::copy" );
200 size_type rlen = (std::min)(n, len_ - pos);
203 std::copy(begin() + pos, begin() + pos + rlen, s);
209 throw std::out_of_range (
"string_view::substr" );
210 if (n == npos || pos + n > size())
216 const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
217 return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
222 return substr(pos1, n1).compare(x);
225 constexpr
int compare(size_type pos1, size_type n1,
227 return substr(pos1, n1).compare(x.substr(pos2, n2));
230 constexpr
int compare(
const charT* x)
const {
234 constexpr
int compare(size_type pos1, size_type n1,
const charT* x)
const {
238 constexpr
int compare(size_type pos1, size_type n1,
239 const charT* x, size_type n2)
const {
244 constexpr size_type find(
basic_string_view s, size_type pos = 0)
const noexcept {
251 auto const end = len_ - s.len_;
252 for (
auto cur = pos; cur <= end; ++cur) {
253 if (traits::compare(ptr_ + cur, s.ptr_, s.len_) == 0)
258 constexpr size_type find(charT c, size_type pos = 0)
const noexcept
260 constexpr size_type find(
const charT* s, size_type pos, size_type n)
const noexcept
262 constexpr size_type find(
const charT* s, size_type pos = 0)
const noexcept
266 constexpr size_type rfind(
basic_string_view s, size_type pos = npos)
const noexcept {
269 if (pos > len_ - s.len_)
273 for (
const charT* cur = ptr_ + pos; ; --cur) {
274 if (traits::compare(cur, s.ptr_, s.len_) == 0)
280 constexpr size_type rfind(charT c, size_type pos = npos)
const noexcept
282 constexpr size_type rfind(
const charT* s, size_type pos, size_type n)
const noexcept
284 constexpr size_type rfind(
const charT* s, size_type pos = npos)
const noexcept
288 constexpr size_type find_first_of(
basic_string_view s, size_type pos = 0)
const noexcept {
289 if (pos >= len_ || s.len_ == 0)
291 const_iterator iter = std::find_first_of
292 (this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
293 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
295 constexpr size_type find_first_of(charT c, size_type pos = 0)
const noexcept
297 constexpr size_type find_first_of(
const charT* s, size_type pos, size_type n)
const noexcept
299 constexpr size_type find_first_of(
const charT* s, size_type pos = 0)
const noexcept
303 constexpr size_type find_last_of(
basic_string_view s, size_type pos = npos)
const noexcept {
309 pos = len_ - (pos+1);
310 const_reverse_iterator iter = std::find_first_of
311 ( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
312 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
314 constexpr size_type find_last_of(charT c, size_type pos = npos)
const noexcept
316 constexpr size_type find_last_of(
const charT* s, size_type pos, size_type n)
const noexcept
318 constexpr size_type find_last_of(
const charT* s, size_type pos = npos)
const noexcept
322 constexpr size_type find_first_not_of(
basic_string_view s, size_type pos = 0)
const noexcept {
327 const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
328 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
330 constexpr size_type find_first_not_of(charT c, size_type pos = 0)
const noexcept
332 constexpr size_type find_first_not_of(
const charT* s, size_type pos, size_type n)
const noexcept
334 constexpr size_type find_first_not_of(
const charT* s, size_type pos = 0)
const noexcept
338 constexpr size_type find_last_not_of(
basic_string_view s, size_type pos = npos)
const noexcept {
343 pos = len_ - (pos+1);
344 const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
345 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
347 constexpr size_type find_last_not_of(charT c, size_type pos = npos)
const noexcept
349 constexpr size_type find_last_not_of(
const charT* s, size_type pos, size_type n)
const noexcept
351 constexpr size_type find_last_not_of(
const charT* s, size_type pos = npos)
const noexcept
355 template <
typename r_iter>
356 size_type reverse_distance(r_iter first, r_iter last)
const noexcept {
358 return len_ - 1 - std::distance ( first, last );
361 template <
typename Iterator>
362 Iterator find_not_of(Iterator first, Iterator last,
basic_string_view s)
const noexcept {
363 for (; first != last ; ++first)
364 if ( 0 == traits::find(s.ptr_, s.len_, *first))
377 template<
typename charT,
typename traits>
380 if (x.size () != y.size ())
return false;
381 return x.compare(y) == 0;
385 template<
typename charT,
typename traits>
386 inline bool operator!=(basic_string_view<charT, traits> x,
387 basic_string_view<charT, traits> y) noexcept {
388 if ( x.size () != y.size ())
return true;
389 return x.compare(y) != 0;
393 template<
typename charT,
typename traits>
394 inline bool operator<(basic_string_view<charT, traits> x,
395 basic_string_view<charT, traits> y) noexcept {
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,
typename Allocator>
422 inline bool operator==(basic_string_view<charT, traits> x,
423 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
424 return x == basic_string_view<charT, traits>(y);
427 template<
typename charT,
typename traits,
typename Allocator>
428 inline bool operator==(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
429 basic_string_view<charT, traits> y) noexcept {
430 return basic_string_view<charT, traits>(x) == y;
433 template<
typename charT,
typename traits>
434 inline bool operator==(basic_string_view<charT, traits> x,
435 const charT * y) noexcept {
436 return x == basic_string_view<charT, traits>(y);
439 template<
typename charT,
typename traits>
440 inline bool operator==(
const charT * x,
441 basic_string_view<charT, traits> y) noexcept {
442 return basic_string_view<charT, traits>(x) == y;
445 template<
typename charT,
typename traits,
typename Allocator>
446 inline bool operator!=(basic_string_view<charT, traits> x,
447 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
448 return x != basic_string_view<charT, traits>(y);
451 template<
typename charT,
typename traits,
typename Allocator>
452 inline bool operator!=(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
453 basic_string_view<charT, traits> y) noexcept {
454 return basic_string_view<charT, traits>(x) != y;
457 template<
typename charT,
typename traits>
458 inline bool operator!=(basic_string_view<charT, traits> x,
459 const charT * y) noexcept {
460 return x != basic_string_view<charT, traits>(y);
463 template<
typename charT,
typename traits>
464 inline bool operator!=(
const charT * x,
465 basic_string_view<charT, traits> y) noexcept {
466 return basic_string_view<charT, traits>(x) != y;
469 template<
typename charT,
typename traits,
typename Allocator>
470 inline bool operator<(basic_string_view<charT, traits> x,
471 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
472 return x < basic_string_view<charT, traits>(y);
475 template<
typename charT,
typename traits,
typename Allocator>
476 inline bool operator<(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
477 basic_string_view<charT, traits> y) noexcept {
478 return basic_string_view<charT, traits>(x) < y;
481 template<
typename charT,
typename traits>
482 inline bool operator<(basic_string_view<charT, traits> x,
483 const charT * y) noexcept {
484 return x < basic_string_view<charT, traits>(y);
487 template<
typename charT,
typename traits>
488 inline bool operator<(
const charT * x,
489 basic_string_view<charT, traits> y) noexcept {
490 return basic_string_view<charT, traits>(x) < y;
493 template<
typename charT,
typename traits,
typename Allocator>
494 inline bool operator>(basic_string_view<charT, traits> x,
495 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
496 return x > basic_string_view<charT, traits>(y);
499 template<
typename charT,
typename traits,
typename Allocator>
500 inline bool operator>(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
501 basic_string_view<charT, traits> y) noexcept {
502 return basic_string_view<charT, traits>(x) > y;
505 template<
typename charT,
typename traits>
506 inline bool operator>(basic_string_view<charT, traits> x,
507 const charT * y) noexcept {
508 return x > basic_string_view<charT, traits>(y);
511 template<
typename charT,
typename traits>
512 inline bool operator>(
const charT * x,
513 basic_string_view<charT, traits> y) noexcept {
514 return basic_string_view<charT, traits>(x) > y;
517 template<
typename charT,
typename traits,
typename Allocator>
518 inline bool operator<=(basic_string_view<charT, traits> x,
519 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
520 return x <= basic_string_view<charT, traits>(y);
523 template<
typename charT,
typename traits,
typename Allocator>
524 inline bool operator<=(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
525 basic_string_view<charT, traits> y) noexcept {
526 return basic_string_view<charT, traits>(x) <= y;
529 template<
typename charT,
typename traits>
530 inline bool operator<=(basic_string_view<charT, traits> x,
531 const charT * y) noexcept {
532 return x <= basic_string_view<charT, traits>(y);
535 template<
typename charT,
typename traits>
536 inline bool operator<=(
const charT * x,
537 basic_string_view<charT, traits> y) noexcept {
538 return basic_string_view<charT, traits>(x) <= y;
541 template<
typename charT,
typename traits,
typename Allocator>
542 inline bool operator>=(basic_string_view<charT, traits> x,
543 const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & y) noexcept {
544 return x >= basic_string_view<charT, traits>(y);
547 template<
typename charT,
typename traits,
typename Allocator>
548 inline bool operator>=(
const std::basic_string<charT,
typename char_traits<charT>::base_traits, Allocator> & x,
549 basic_string_view<charT, traits> y) noexcept {
550 return basic_string_view<charT, traits>(x) >= y;
553 template<
typename charT,
typename traits>
554 inline bool operator>=(basic_string_view<charT, traits> x,
555 const charT * y) noexcept {
556 return x >= basic_string_view<charT, traits>(y);
559 template<
typename charT,
typename traits>
560 inline bool operator>=(
const charT * x,
561 basic_string_view<charT, traits> y) noexcept {
562 return basic_string_view<charT, traits>(x) >= y;
567 template<
class charT,
class traits>
568 inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
569 enum { chunk_size = 8 };
570 charT fill_chars[chunk_size];
571 std::fill_n(fill_chars,
static_cast< std::size_t
>(chunk_size), os.fill());
572 for (; n >= chunk_size && os.good(); n -= chunk_size)
573 os.write(fill_chars,
static_cast< std::size_t
>(chunk_size));
574 if (n > 0 && os.good())
575 os.write(fill_chars, n);
578 template<
class charT,
class traits>
579 void sv_insert_aligned(std::basic_ostream<charT,
typename char_traits<charT>::base_traits>& os,
const basic_string_view<charT,traits>& str) {
580 const std::size_t size = str.size();
581 const std::size_t alignment_size =
static_cast< std::size_t
>(os.width()) - size;
582 const bool align_left = (os.flags() & std::basic_ostream<charT, typename char_traits<charT>::base_traits>::adjustfield)
583 == std::basic_ostream<charT,
typename char_traits<charT>::base_traits>::left;
585 detail::sv_insert_fill_chars(os, alignment_size);
587 os.write(str.data(), size);
590 os.write(str.data(), size);
592 detail::sv_insert_fill_chars(os, alignment_size);
599 template<
class charT,
class traits>
600 inline std::basic_ostream<charT, typename char_traits<charT>::base_traits>&
601 operator<<(std::basic_ostream<charT,
typename char_traits<charT>::base_traits>& os,
602 const basic_string_view<charT,traits>& str) {
604 const std::size_t size = str.size();
605 const std::size_t w =
static_cast< std::size_t
>(os.width());
607 os.write(str.data(), size);
609 detail::sv_insert_aligned(os, str);
652 inline std::string &operator+=(std::string &a,
string_view b)
654 a.append(b.begin(), b.end());
658 inline std::string operator+(std::string a,
string_view b)
664 inline std::string operator+(
string_view a, std::string b)
666 b.insert(b.begin(), a.begin(), a.end());
A view to a contiguous sequence of chars or char-like objects.
Definition: string_view.h:107
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
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:1649
basic_string_view< char > string_view
A view to a contiguous sequence of chars.
Definition: string_view.h:623