21 Strings library [strings]

21.4 String view classes [string.view]

21.4.2 Class template basic_­string_­view [string.view.template]

template<class charT, class traits = char_traits<charT>>
class basic_string_view {
public:
  // types
  using traits_type            = traits;
  using value_type             = charT;
  using pointer                = value_type*;
  using const_pointer          = const value_type*;
  using reference              = value_type&;
  using const_reference        = const value_type&;
  using const_iterator         = implementation-defined; // see [string.view.iterators]
  using iterator               = const_iterator;223
  using const_reverse_iterator = reverse_iterator<const_iterator>;
  using reverse_iterator       = const_reverse_iterator;
  using size_type              = size_t;
  using difference_type        = ptrdiff_t;
  static constexpr size_type npos = size_type(-1);

  // [string.view.cons], construction and assignment
  constexpr basic_string_view() noexcept;
  constexpr basic_string_view(const basic_string_view&) noexcept = default;
  constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default;
  constexpr basic_string_view(const charT* str);
  constexpr basic_string_view(const charT* str, size_type len);
  template<class It, class End>
    constexpr basic_string_view(It begin, End end);

  // [string.view.iterators], iterator support
  constexpr const_iterator begin() const noexcept;
  constexpr const_iterator end() const noexcept;
  constexpr const_iterator cbegin() const noexcept;
  constexpr const_iterator cend() const noexcept;
  constexpr const_reverse_iterator rbegin() const noexcept;
  constexpr const_reverse_iterator rend() const noexcept;
  constexpr const_reverse_iterator crbegin() const noexcept;
  constexpr const_reverse_iterator crend() const noexcept;

  // [string.view.capacity], capacity
  constexpr size_type size() const noexcept;
  constexpr size_type length() const noexcept;
  constexpr size_type max_size() const noexcept;
  [[nodiscard]] constexpr bool empty() const noexcept;

  // [string.view.access], element access
  constexpr const_reference operator[](size_type pos) const;
  constexpr const_reference at(size_type pos) const;
  constexpr const_reference front() const;
  constexpr const_reference back() const;
  constexpr const_pointer data() const noexcept;

  // [string.view.modifiers], modifiers
  constexpr void remove_prefix(size_type n);
  constexpr void remove_suffix(size_type n);
  constexpr void swap(basic_string_view& s) noexcept;

  // [string.view.ops], string operations
  constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const;

  constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;

  constexpr int compare(basic_string_view s) const noexcept;
  constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
  constexpr int compare(size_type pos1, size_type n1, basic_string_view s,
                        size_type pos2, size_type n2) const;
  constexpr int compare(const charT* s) const;
  constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
  constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const;

  constexpr bool starts_with(basic_string_view x) const noexcept;
  constexpr bool starts_with(charT x) const noexcept;
  constexpr bool starts_with(const charT* x) const;
  constexpr bool ends_with(basic_string_view x) const noexcept;
  constexpr bool ends_with(charT x) const noexcept;
  constexpr bool ends_with(const charT* x) const;

  // [string.view.find], searching
  constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
  constexpr size_type find(charT c, size_type pos = 0) const noexcept;
  constexpr size_type find(const charT* s, size_type pos, size_type n) const;
  constexpr size_type find(const charT* s, size_type pos = 0) const;
  constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
  constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
  constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
  constexpr size_type rfind(const charT* s, size_type pos = npos) const;

  constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
  constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
  constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
  constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
  constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
  constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
  constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
  constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
  constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
  constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
  constexpr size_type find_first_not_of(const charT* s, size_type pos,
                                        size_type n) const;
  constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
  constexpr size_type find_last_not_of(basic_string_view s,
                                       size_type pos = npos) const noexcept;
  constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
  constexpr size_type find_last_not_of(const charT* s, size_type pos,
                                       size_type n) const;
  constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;

private:
  const_pointer data_;          // exposition only
  size_type size_;              // exposition only
};

// [string.view.deduct], deduction guide
template<class It, class End>
  basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>;
In every specialization basic_­string_­view<charT, traits>, the type traits shall meet the character traits requirements ([char.traits]).
Note
:
The program is ill-formed if traits​::​char_­type is not the same type as charT.
— end note
 ]
For a basic_­string_­view str, any operation that invalidates a pointer in the range [str.data(), ​str.data() + str.size()) invalidates pointers, iterators, and references returned from str's member functions.
The complexity of basic_­string_­view member functions is unless otherwise specified.
Because basic_­string_­view refers to a constant sequence, iterator and const_­iterator are the same type.

21.4.2.1 Construction and assignment [string.view.cons]

constexpr basic_string_view() noexcept;
Postconditions: size_­ == 0 and data_­ == nullptr.
constexpr basic_string_view(const charT* str);
Preconditions: [str, str + traits​::​length(str)) is a valid range.
Effects: Constructs a basic_­string_­view, initializing data_­ with str and initializing size_­ with traits​::​length(str).
Complexity: .
constexpr basic_string_view(const charT* str, size_type len);
Preconditions: [str, str + len) is a valid range.
Effects: Constructs a basic_­string_­view, initializing data_­ with str and initializing size_­ with len.
template<class It, class End> constexpr basic_string_view(It begin, End end);
Constraints:
  • It satisfies contiguous_­iterator.
  • End satisfies sized_­sentinel_­for<It>.
  • is_­same_­v<iter_­value_­t<It>, charT> is true.
  • is_­convertible_­v<End, size_­type> is false.
Preconditions:
  • [begin, end) is a valid range.
  • It models contiguous_­iterator.
  • End models sized_­sentinel_­for<It>.
Effects: Initializes data_­ with to_­address(begin) and initializes size_­ with end - begin.

21.4.2.2 Iterator support [string.view.iterators]

using const_iterator = implementation-defined;
A type that meets the requirements of a constant Cpp17RandomAccessIterator ([random.access.iterators]), models contiguous_­iterator ([iterator.concept.contiguous]), and meets the constexpr iterator requirements ([iterator.requirements.general]), whose value_­type is the template parameter charT.
All requirements on container iterators ([container.requirements]) apply to basic_­string_­view​::​const_­iterator as well.
constexpr const_iterator begin() const noexcept; constexpr const_iterator cbegin() const noexcept;
Returns: An iterator such that
  • if !empty(), addressof(*begin()) == data_­,
  • otherwise, an unspecified value such that [begin(), end()) is a valid range.
constexpr const_iterator end() const noexcept; constexpr const_iterator cend() const noexcept;
Returns: begin() + size().
constexpr const_reverse_iterator rbegin() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept;
Returns: const_­reverse_­iterator(end()).
constexpr const_reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crend() const noexcept;
Returns: const_­reverse_­iterator(begin()).

21.4.2.3 Capacity [string.view.capacity]

constexpr size_type size() const noexcept; constexpr size_type length() const noexcept;
Returns: size_­.
constexpr size_type max_size() const noexcept;
Returns: The largest possible number of char-like objects that can be referred to by a basic_­string_­view.
[[nodiscard]] constexpr bool empty() const noexcept;
Returns: size_­ == 0.

21.4.2.4 Element access [string.view.access]

constexpr const_reference operator[](size_type pos) const;
Preconditions: pos < size().
Returns: data_­[pos].
Throws: Nothing.
Note
:
Unlike basic_­string​::​operator[], basic_­string_­view​::​operator[](size()) has undefined behavior instead of returning charT().
— end note
 ]
constexpr const_reference at(size_type pos) const;
Throws: out_­of_­range if pos >= size().
Returns: data_­[pos].
constexpr const_reference front() const;
Preconditions: !empty().
Returns: data_­[0].
Throws: Nothing.
constexpr const_reference back() const;
Preconditions: !empty().
Returns: data_­[size() - 1].
Throws: Nothing.
constexpr const_pointer data() const noexcept;
Returns: data_­.
Note
:
Unlike basic_­string​::​data() and string-literals, data() may return a pointer to a buffer that is not null-terminated.
Therefore it is typically a mistake to pass data() to a function that takes just a const charT* and expects a null-terminated string.
— end note
 ]

21.4.2.5 Modifiers [string.view.modifiers]

constexpr void remove_prefix(size_type n);
Preconditions: n <= size().
Effects: Equivalent to: data_­ += n; size_­ -= n;
constexpr void remove_suffix(size_type n);
Preconditions: n <= size().
Effects: Equivalent to: size_­ -= n;
constexpr void swap(basic_string_view& s) noexcept;
Effects: Exchanges the values of *this and s.

21.4.2.6 String operations [string.view.ops]

constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const;
Let rlen be the smaller of n and size() - pos.
Throws: out_­of_­range if pos > size().
Preconditions: [s, s + rlen) is a valid range.
Effects: Equivalent to traits​::​copy(s, data() + pos, rlen).
Returns: rlen.
Complexity: .
constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
Let rlen be the smaller of n and size() - pos.
Throws: out_­of_­range if pos > size().
Effects: Determines rlen, the effective length of the string to reference.
Returns: basic_­string_­view(data() + pos, rlen).
constexpr int compare(basic_string_view str) const noexcept;
Let rlen be the smaller of size() and str.size().
Effects: Determines rlen, the effective length of the strings to compare.
The function then compares the two strings by calling traits​::​compare(data(), str.data(), rlen).
Complexity: .
Returns: The nonzero result if the result of the comparison is nonzero.
Otherwise, returns a value as indicated in Table 70.
Table 70: compare() results   [tab:string.view.compare]
Condition
Return Value
size() < str.size()
< 0
size() == str.size()
 0
size() > str.size()
> 0
constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const;
Effects: Equivalent to: return substr(pos1, n1).compare(str);
constexpr int compare(size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2) const;
Effects: Equivalent to: return substr(pos1, n1).compare(str.substr(pos2, n2));
constexpr int compare(const charT* s) const;
Effects: Equivalent to: return compare(basic_­string_­view(s));
constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
Effects: Equivalent to: return substr(pos1, n1).compare(basic_­string_­view(s));
constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const;
Effects: Equivalent to: return substr(pos1, n1).compare(basic_­string_­view(s, n2));
constexpr bool starts_with(basic_string_view x) const noexcept;
Effects: Equivalent to: return substr(0, x.size()) == x;
constexpr bool starts_with(charT x) const noexcept;
Effects: Equivalent to: return !empty() && traits​::​eq(front(), x);
constexpr bool starts_with(const charT* x) const;
Effects: Equivalent to: return starts_­with(basic_­string_­view(x));
constexpr bool ends_with(basic_string_view x) const noexcept;
Effects: Equivalent to:
return size() >= x.size() && compare(size() - x.size(), npos, x) == 0;
constexpr bool ends_with(charT x) const noexcept;
Effects: Equivalent to: return !empty() && traits​::​eq(back(), x);
constexpr bool ends_with(const charT* x) const;
Effects: Equivalent to: return ends_­with(basic_­string_­view(x));

21.4.2.7 Searching [string.view.find]

Member functions in this subclause have complexity at worst, although implementations should do better.
Let F be one of find, rfind, find_­first_­of, find_­last_­of, find_­first_­not_­of, and find_­last_­not_­of.
  • Each member function of the form
    constexpr return-type F(const charT* s, size_type pos) const;
    
    has effects equivalent to: return F(basic_­string_­view(s), pos);
  • Each member function of the form
    constexpr return-type F(const charT* s, size_type pos, size_type n) const;
    
    has effects equivalent to: return F(basic_­string_­view(s, n), pos);
  • Each member function of the form
    constexpr return-type F(charT c, size_type pos) const noexcept;
    
    has effects equivalent to: return F(basic_­string_­view(addressof(c), 1), pos);
constexpr size_type find(basic_string_view str, size_type pos = 0) const noexcept;
Let xpos be the lowest position, if possible, such that the following conditions hold:
  • pos <= xpos
  • xpos + str.size() <= size()
  • traits​::​eq(at(xpos + I), str.at(I)) for all elements I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type rfind(basic_string_view str, size_type pos = npos) const noexcept;
Let xpos be the highest position, if possible, such that the following conditions hold:
  • xpos <= pos
  • xpos + str.size() <= size()
  • traits​::​eq(at(xpos + I), str.at(I)) for all elements I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_first_of(basic_string_view str, size_type pos = 0) const noexcept;
Let xpos be the lowest position, if possible, such that the following conditions hold:
  • pos <= xpos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for some element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_last_of(basic_string_view str, size_type pos = npos) const noexcept;
Let xpos be the highest position, if possible, such that the following conditions hold:
  • xpos <= pos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for some element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_first_not_of(basic_string_view str, size_type pos = 0) const noexcept;
Let xpos be the lowest position, if possible, such that the following conditions hold:
  • pos <= xpos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for no element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_last_not_of(basic_string_view str, size_type pos = npos) const noexcept;
Let xpos be the highest position, if possible, such that the following conditions hold:
  • xpos <= pos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for no element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.