20 Strings library [strings]

20.3 String classes [string.classes]

20.3.2 Class template basic_­string [basic.string]

The class template basic_­string describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects with the first element of the sequence at position zero.
Such a sequence is also called a “string” if the type of the char-like objects that it holds is clear from context.
In the rest of this Clause, the type of the char-like objects held in a basic_­string object is designated by charT.
A specialization of basic_­string is a contiguous container ([container.requirements.general]).
In all cases, [data(), data() + size()] is a valid range, data() + size() points at an object with value charT() (a “null terminator”), and size() <= capacity() is true.
namespace std {
  template<class charT, class traits = char_traits<charT>,
           class Allocator = allocator<charT>>
  class basic_string {
  public:
    // types
    using traits_type            = traits;
    using value_type             = charT;
    using allocator_type         = Allocator;
    using size_type              = typename allocator_traits<Allocator>::size_type;
    using difference_type        = typename allocator_traits<Allocator>::difference_type;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;

    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    static const size_type npos  = -1;

    // [string.cons], construct/copy/destroy
    basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
    explicit basic_string(const Allocator& a) noexcept;
    basic_string(const basic_string& str);
    basic_string(basic_string&& str) noexcept;
    basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator());
    basic_string(const basic_string& str, size_type pos, size_type n,
                 const Allocator& a = Allocator());
    template<class T>
      basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
    template<class T>
      explicit basic_string(const T& t, const Allocator& a = Allocator());
    basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
    basic_string(const charT* s, const Allocator& a = Allocator());
    basic_string(size_type n, charT c, const Allocator& a = Allocator());
    template<class InputIterator>
      basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
    basic_string(initializer_list<charT>, const Allocator& = Allocator());
    basic_string(const basic_string&, const Allocator&);
    basic_string(basic_string&&, const Allocator&);

    ~basic_string();
    basic_string& operator=(const basic_string& str);
    basic_string& operator=(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    template<class T>
      basic_string& operator=(const T& t);
    basic_string& operator=(const charT* s);
    basic_string& operator=(charT c);
    basic_string& operator=(initializer_list<charT>);

    // [string.iterators], iterators
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [string.capacity], capacity
    size_type size() const noexcept;
    size_type length() const noexcept;
    size_type max_size() const noexcept;
    void resize(size_type n, charT c);
    void resize(size_type n);
    size_type capacity() const noexcept;
    void reserve(size_type res_arg);
    void shrink_to_fit();
    void clear() noexcept;
    [[nodiscard]] bool empty() const noexcept;

    // [string.access], element access
    const_reference operator[](size_type pos) const;
    reference       operator[](size_type pos);
    const_reference at(size_type n) const;
    reference       at(size_type n);

    const charT& front() const;
    charT&       front();
    const charT& back() const;
    charT&       back();

    // [string.modifiers], modifiers
    basic_string& operator+=(const basic_string& str);
    template<class T>
      basic_string& operator+=(const T& t);
    basic_string& operator+=(const charT* s);
    basic_string& operator+=(charT c);
    basic_string& operator+=(initializer_list<charT>);
    basic_string& append(const basic_string& str);
    basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
    template<class T>
      basic_string& append(const T& t);
    template<class T>
      basic_string& append(const T& t, size_type pos, size_type n = npos);
    basic_string& append(const charT* s, size_type n);
    basic_string& append(const charT* s);
    basic_string& append(size_type n, charT c);
    template<class InputIterator>
      basic_string& append(InputIterator first, InputIterator last);
    basic_string& append(initializer_list<charT>);

    void push_back(charT c);

    basic_string& assign(const basic_string& str);
    basic_string& assign(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
    template<class T>
      basic_string& assign(const T& t);
    template<class T>
      basic_string& assign(const T& t, size_type pos, size_type n = npos);
    basic_string& assign(const charT* s, size_type n);
    basic_string& assign(const charT* s);
    basic_string& assign(size_type n, charT c);
    template<class InputIterator>
      basic_string& assign(InputIterator first, InputIterator last);
    basic_string& assign(initializer_list<charT>);

    basic_string& insert(size_type pos, const basic_string& str);
    basic_string& insert(size_type pos1, const basic_string& str,
                         size_type pos2, size_type n = npos);
    template<class T>
      basic_string& insert(size_type pos, const T& t);
    template<class T>
      basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos);
    basic_string& insert(size_type pos, const charT* s, size_type n);
    basic_string& insert(size_type pos, const charT* s);
    basic_string& insert(size_type pos, size_type n, charT c);
    iterator insert(const_iterator p, charT c);
    iterator insert(const_iterator p, size_type n, charT c);
    template<class InputIterator>
      iterator insert(const_iterator p, InputIterator first, InputIterator last);
    iterator insert(const_iterator p, initializer_list<charT>);

    basic_string& erase(size_type pos = 0, size_type n = npos);
    iterator erase(const_iterator p);
    iterator erase(const_iterator first, const_iterator last);

    void pop_back();

    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
                          size_type pos2, size_type n2 = npos);
    template<class T>
      basic_string& replace(size_type pos1, size_type n1, const T& t);
    template<class T>
      basic_string& replace(size_type pos1, size_type n1, const T& t,
                            size_type pos2, size_type n2 = npos);
    basic_string& replace(size_type pos, size_type n1, const charT* s, size_type n2);
    basic_string& replace(size_type pos, size_type n1, const charT* s);
    basic_string& replace(size_type pos, size_type n1, size_type n2, charT c);

    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
    template<class T>
      basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
    basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
    basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
    template<class InputIterator>
      basic_string& replace(const_iterator i1, const_iterator i2,
                            InputIterator j1, InputIterator j2);
    basic_string& replace(const_iterator, const_iterator, initializer_list<charT>);

    size_type copy(charT* s, size_type n, size_type pos = 0) const;

    void swap(basic_string& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
               allocator_traits<Allocator>::is_always_equal::value);

    // [string.ops], string operations
    const charT* c_str() const noexcept;
    const charT* data() const noexcept;
    charT* data() noexcept;
    operator basic_string_view<charT, traits>() const noexcept;
    allocator_type get_allocator() const noexcept;

    template<class T>
      size_type find (const T& t, size_type pos = 0) const noexcept(see below);
    size_type find (const basic_string& str, size_type pos = 0) const noexcept;
    size_type find (const charT* s, size_type pos, size_type n) const;
    size_type find (const charT* s, size_type pos = 0) const;
    size_type find (charT c, size_type pos = 0) const noexcept;
    template<class T>
      size_type rfind(const T& t, size_type pos = npos) const noexcept(see below);
    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
    size_type rfind(const charT* s, size_type pos, size_type n) const;
    size_type rfind(const charT* s, size_type pos = npos) const;
    size_type rfind(charT c, size_type pos = npos) const noexcept;

    template<class T>
      size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below);
    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
    size_type find_first_of(const charT* s, size_type pos, size_type n) const;
    size_type find_first_of(const charT* s, size_type pos = 0) const;
    size_type find_first_of(charT c, size_type pos = 0) const noexcept;
    template<class T>
      size_type find_last_of (const T& t, size_type pos = npos) const noexcept(see below);
    size_type find_last_of (const basic_string& str, size_type pos = npos) const noexcept;
    size_type find_last_of (const charT* s, size_type pos, size_type n) const;
    size_type find_last_of (const charT* s, size_type pos = npos) const;
    size_type find_last_of (charT c, size_type pos = npos) const noexcept;

    template<class T>
      size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(see below);
    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
    size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
    size_type find_first_not_of(const charT* s, size_type pos = 0) const;
    size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
    template<class T>
      size_type find_last_not_of (const T& t, size_type pos = npos) const noexcept(see below);
    size_type find_last_not_of (const basic_string& str, size_type pos = npos) const noexcept;
    size_type find_last_not_of (const charT* s, size_type pos, size_type n) const;
    size_type find_last_not_of (const charT* s, size_type pos = npos) const;
    size_type find_last_not_of (charT c, size_type pos = npos) const noexcept;

    basic_string substr(size_type pos = 0, size_type n = npos) const;
    template<class T>
      int compare(const T& t) const noexcept(see below);
    template<class T>
      int compare(size_type pos1, size_type n1, const T& t) const;
    template<class T>
      int compare(size_type pos1, size_type n1, const T& t,
                  size_type pos2, size_type n2 = npos) const;
    int compare(const basic_string& str) const noexcept;
    int compare(size_type pos1, size_type n1, const basic_string& str) const;
    int compare(size_type pos1, size_type n1, const basic_string& str,
                size_type pos2, size_type n2 = npos) const;
    int compare(const charT* s) const;
    int compare(size_type pos1, size_type n1, const charT* s) const;
    int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const;

    bool starts_with(basic_string_view<charT, traits> x) const noexcept;
    bool starts_with(charT x) const noexcept;
    bool starts_with(const charT* x) const;
    bool ends_with(basic_string_view<charT, traits> x) const noexcept;
    bool ends_with(charT x) const noexcept;
    bool ends_with(const charT* x) const;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    basic_string(InputIterator, InputIterator, Allocator = Allocator())
      -> basic_string<typename iterator_traits<InputIterator>::value_type,
                      char_traits<typename iterator_traits<InputIterator>::value_type>,
                      Allocator>;

  template<class charT,
           class traits,
           class Allocator = allocator<charT>>
    explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
      -> basic_string<charT, traits, Allocator>;

  template<class charT,
           class traits,
           class Allocator = allocator<charT>>
    basic_string(basic_string_view<charT, traits>,
                 typename see below::size_type, typename see below::size_type,
                 const Allocator& = Allocator())
      -> basic_string<charT, traits, Allocator>;
}
A size_­type parameter type in a basic_­string deduction guide refers to the size_­type member type of the type deduced by the deduction guide.

20.3.2.1 General requirements [string.require]

If any operation would cause size() to exceed max_­size(), that operation throws an exception object of type length_­error.
If any member function or operator of basic_­string throws an exception, that function or operator has no other effect on the basic_­string object.
In every specialization basic_­string<charT, traits, Allocator>, the type allocator_­traits<Allocator>::value_­type shall name the same type as charT.
Every object of type basic_­string<charT, traits, Allocator> uses an object of type Allocator to allocate and free storage for the contained charT objects as needed.
The Allocator object used is obtained as described in [container.requirements.general].
In every specialization basic_­string<charT, traits, Allocator>, the type traits shall satisfy 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
]
References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:
  • Passing as an argument to any standard library function taking a reference to non-const basic_­string as an argument.225
  • Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
For example, as an argument to non-member functions swap(), operator>>(), and getline(), or as an argument to basic_­string::swap().

20.3.2.2 Constructors and assignment operators [string.cons]

explicit basic_string(const Allocator& a) noexcept;
Ensures: size() is equal to 0.
basic_string(const basic_string& str); basic_string(basic_string&& str) noexcept;
Effects: Constructs an object whose value is that of str prior to this call.
Remarks: In the second form, str is left in a valid but unspecified state.
basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator()); basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator());
Effects: Let n be npos for the first overload.
Equivalent to:
basic_string(basic_string_view<charT, traits>(str).substr(pos, n), a)
template<class T> basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
Constraints: is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true.
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t; and then behaves the same as:
basic_string(sv.substr(pos, n), a);
template<class T> explicit basic_string(const T& t, const Allocator& a = Allocator());
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t; and then behaves the same as basic_­string(sv.data(), sv.size(), a).
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
Expects: [s, s + n) is a valid range.
Effects: Constructs an object whose initial value is the range [s, s + n).
Ensures: size() is equal to n, and traits::compare(data(), s, n) is equal to 0.
basic_string(const charT* s, const Allocator& a = Allocator());
Constraints: Allocator is a type that qualifies as an allocator ([container.requirements.general]).
[Note
:
This affects class template argument deduction.
end note
]
Effects: Equivalent to: basic_­string(s, traits::length(s), a).
basic_string(size_type n, charT c, const Allocator& a = Allocator());
Constraints: Allocator is a type that qualifies as an allocator ([container.requirements.general]).
[Note
:
This affects class template argument deduction.
end note
]
Effects: Constructs an object whose value consists of n copies of c.
template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Constructs a string from the values in the range [begin, end), as indicated in Table 66.
basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
Effects: Equivalent to basic_­string(il.begin(), il.end(), a).
basic_string(const basic_string& str, const Allocator& alloc); basic_string(basic_string&& str, const Allocator& alloc);
Effects: Constructs an object whose value is that of str prior to this call.
The stored allocator is constructed from alloc.
In the second form, str is left in a valid but unspecified state.
Throws: The second form throws nothing if alloc == str.get_­allocator().
template<class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator()) -> basic_string<typename iterator_traits<InputIterator>::value_type, char_traits<typename iterator_traits<InputIterator>::value_type>, Allocator>;
Constraints: InputIterator is a type that qualifies as an input iterator, and Allocator is a type that qualifies as an allocator ([container.requirements.general]).
template<class charT, class traits, class Allocator = allocator<charT>> explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator()) -> basic_string<charT, traits, Allocator>; template<class charT, class traits, class Allocator = allocator<charT>> basic_string(basic_string_view<charT, traits>, typename see below::size_type, typename see below::size_type, const Allocator& = Allocator()) -> basic_string<charT, traits, Allocator>;
Constraints: Allocator is a type that qualifies as an allocator ([container.requirements.general]).
basic_string& operator=(const basic_string& str);
Effects: If *this and str are the same object, has no effect.
Otherwise, replaces the value of *this with a copy of str.
Returns: *this.
basic_string& operator=(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.
Returns: *this.
template<class T> basic_string& operator=(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return assign(sv);
basic_string& operator=(const charT* s);
Effects: Equivalent to: return *this = basic_­string_­view<charT, traits>(s);
basic_string& operator=(charT c);
Effects: Equivalent to:
return *this = basic_string_view<charT, traits>(addressof(c), 1);
basic_string& operator=(initializer_list<charT> il);
Effects: Equivalent to:
return *this = basic_string_view<charT, traits>(il.begin(), il.size());

20.3.2.3 Iterator support [string.iterators]

iterator begin() noexcept; const_iterator begin() const noexcept; const_iterator cbegin() const noexcept;
Returns: An iterator referring to the first character in the string.
iterator end() noexcept; const_iterator end() const noexcept; const_iterator cend() const noexcept;
Returns: An iterator which is the past-the-end value.
reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator crbegin() const noexcept;
Returns: An iterator which is semantically equivalent to reverse_­iterator(end()).
reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crend() const noexcept;
Returns: An iterator which is semantically equivalent to reverse_­iterator(begin()).

20.3.2.4 Capacity [string.capacity]

size_type size() const noexcept; size_type length() const noexcept;
Returns: A count of the number of char-like objects currently in the string.
Complexity: Constant time.
size_type max_size() const noexcept;
Returns: The largest possible number of char-like objects that can be stored in a basic_­string.
Complexity: Constant time.
void resize(size_type n, charT c);
Effects: Alters the value of *this as follows:
  • If n <= size(), erases the last size() - n elements.
  • If n > size(), appends n - size() copies of c.
void resize(size_type n);
Effects: Equivalent to resize(n, charT()).
size_type capacity() const noexcept;
Returns: The size of the allocated storage in the string.
Complexity: Constant time.
void reserve(size_type res_arg);
Effects: A directive that informs a basic_­string of a planned change in size, so that the storage allocation can be managed accordingly.
After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise.
Reallocation happens at this point if and only if the current capacity is less than the argument of reserve().
Throws: length_­error if res_­arg > max_­size() or any exceptions thrown by allocator_­traits <Allocator>::allocate.
void shrink_to_fit();
Effects: shrink_­to_­fit is a non-binding request to reduce capacity() to size().
[Note
:
The request is non-binding to allow latitude for implementation-specific optimizations.
end note
]
It does not increase capacity(), but may reduce capacity() by causing reallocation.
Complexity: Linear in the size of the sequence.
Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence as well as the past-the-end iterator.
If no reallocation happens, they remain valid.
void clear() noexcept;
Effects: Equivalent to: erase(begin(), end());
[[nodiscard]] bool empty() const noexcept;
Effects: Equivalent to: return size() == 0;

20.3.2.5 Element access [string.access]

const_reference operator[](size_type pos) const; reference operator[](size_type pos);
Expects: pos <= size().
Returns: *(begin() + pos) if pos < size().
Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.
Throws: Nothing.
Complexity: Constant time.
const_reference at(size_type pos) const; reference at(size_type pos);
Throws: out_­of_­range if pos >= size().
Returns: operator[](pos).
const charT& front() const; charT& front();
Expects: !empty().
Effects: Equivalent to: return operator[](0);
const charT& back() const; charT& back();
Expects: !empty().
Effects: Equivalent to: return operator[](size() - 1);

20.3.2.6 Modifiers [string.modifiers]

20.3.2.6.1 basic_­string​::​operator+= [string.op.append]

basic_string& operator+=(const basic_string& str);
Effects: Equivalent to: return append(str);
template<class T> basic_string& operator+=(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return append(sv);
basic_string& operator+=(const charT* s);
Effects: Equivalent to: return append(s);
basic_string& operator+=(charT c);
Effects: Equivalent to: return append(size_­type{1}, c);
basic_string& operator+=(initializer_list<charT> il);
Effects: Equivalent to: return append(il);

20.3.2.6.2 basic_­string​::​append [string.append]

basic_string& append(const basic_string& str);
Effects: Equivalent to: return append(str.data(), str.size());
basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
Effects: Equivalent to:
return append(basic_string_view<charT, traits>(str).substr(pos, n));
template<class T> basic_string& append(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return append(sv.data(), sv.size());
template<class T> basic_string& append(const T& t, size_type pos, size_type n = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return append(sv.substr(pos, n));
basic_string& append(const charT* s, size_type n);
Expects: [s, s + n) is a valid range.
Effects: Appends a copy of the range [s, s + n) to the string.
Returns: *this.
basic_string& append(const charT* s);
Effects: Equivalent to: return append(s, traits::length(s));
basic_string& append(size_type n, charT c);
Effects: Appends n copies of c to the string.
Returns: *this.
template<class InputIterator> basic_string& append(InputIterator first, InputIterator last);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Equivalent to: return append(basic_­string(first, last, get_­allocator()));
basic_string& append(initializer_list<charT> il);
Effects: Equivalent to: return append(il.begin(), il.size());
void push_back(charT c);
Effects: Equivalent to append(size_­type{1}, c).

20.3.2.6.3 basic_­string​::​assign [string.assign]

basic_string& assign(const basic_string& str);
Effects: Equivalent to: return *this = str;
basic_string& assign(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Equivalent to: return *this = std::move(str);
basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
Effects: Equivalent to:
return assign(basic_string_view<charT, traits>(str).substr(pos, n));
template<class T> basic_string& assign(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return assign(sv.data(), sv.size());
template<class T> basic_string& assign(const T& t, size_type pos, size_type n = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return assign(sv.substr(pos, n));
basic_string& assign(const charT* s, size_type n);
Expects: [s, s + n) is a valid range.
Effects: Replaces the string controlled by *this with a copy of the range [s, s + n).
Returns: *this.
basic_string& assign(const charT* s);
Effects: Equivalent to: return assign(s, traits::length(s));
basic_string& assign(initializer_list<charT> il);
Effects: Equivalent to: return assign(il.begin(), il.size());
basic_string& assign(size_type n, charT c);
Effects: Equivalent to:
clear();
resize(n, c);
return *this;
template<class InputIterator> basic_string& assign(InputIterator first, InputIterator last);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Equivalent to: return assign(basic_­string(first, last, get_­allocator()));

20.3.2.6.4 basic_­string​::​insert [string.insert]

basic_string& insert(size_type pos, const basic_string& str);
Effects: Equivalent to: return insert(pos, str.data(), str.size());
basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n = npos);
Effects: Equivalent to:
return insert(pos1, basic_string_view<charT, traits>(str), pos2, n);
template<class T> basic_string& insert(size_type pos, const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return insert(pos, sv.data(), sv.size());
template<class T> basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return insert(pos1, sv.substr(pos2, n));
basic_string& insert(size_type pos, const charT* s, size_type n);
Expects: [s, s + n) is a valid range.
Throws:
  • out_­of_­range if pos > size(),
  • length_­error if n > max_­size() - size(), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Inserts a copy of the range [s, s + n) immediately before the character at position pos if pos < size(), or otherwise at the end of the string.
Returns: *this.
basic_string& insert(size_type pos, const charT* s);
Effects: Equivalent to: return insert(pos, s, traits::length(s));
basic_string& insert(size_type pos, size_type n, charT c);
Throws:
  • out_­of_­range if pos > size(),
  • length_­error if n > max_­size() - size(), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Inserts n copies of c before the character at position pos if pos < size(), or otherwise at the end of the string.
iterator insert(const_iterator p, charT c);
Expects: p is a valid iterator on *this.
Effects: Inserts a copy of c at the position p.
Returns: An iterator which refers to the inserted character.
iterator insert(const_iterator p, size_type n, charT c);
Expects: p is a valid iterator on *this.
Effects: Inserts n copies of c at the position p.
Returns: An iterator which refers to the first inserted character, or p if n == 0.
template<class InputIterator> iterator insert(const_iterator p, InputIterator first, InputIterator last);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Expects: p is a valid iterator on *this.
Effects: Equivalent to insert(p - begin(), basic_­string(first, last, get_­allocator())).
Returns: An iterator which refers to the first inserted character, or p if first == last.
iterator insert(const_iterator p, initializer_list<charT> il);
Effects: Equivalent to: return insert(p, il.begin(), il.end());

20.3.2.6.5 basic_­string​::​erase [string.erase]

basic_string& erase(size_type pos = 0, size_type n = npos);
Throws: out_­of_­range if pos > size().
Effects: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
Removes the characters in the range [begin() + pos, begin() + pos + xlen).
Returns: *this.
iterator erase(const_iterator p);
Expects: p is a valid dereferenceable iterator on *this.
Throws: Nothing.
Effects: Removes the character referred to by p.
Returns: An iterator which points to the element immediately following p prior to the element being erased.
If no such element exists, end() is returned.
iterator erase(const_iterator first, const_iterator last);
Expects: first and last are valid iterators on *this.
[first, last) is a valid range.
Throws: Nothing.
Effects: Removes the characters in the range [first, last).
Returns: An iterator which points to the element pointed to by last prior to the other elements being erased.
If no such element exists, end() is returned.
void pop_back();
Expects: !empty().
Throws: Nothing.
Effects: Equivalent to erase(end() - 1).

20.3.2.6.6 basic_­string​::​replace [string.replace]

basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
Effects: Equivalent to: return replace(pos1, n1, str.data(), str.size());
basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos);
Effects: Equivalent to:
return replace(pos1, n1, basic_string_view<charT, traits>(str).substr(pos2, n2));
template<class T> basic_string& replace(size_type pos1, size_type n1, const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return replace(pos1, n1, sv.data(), sv.size());
template<class T> basic_string& replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return replace(pos1, n1, sv.substr(pos2, n2));
basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2);
Expects: [s, s + n2) is a valid range.
Throws:
  • out_­of_­range if pos1 > size(),
  • length_­error if the length of the resulting string would exceed max_­size() (see below), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Determines the effective length xlen of the string to be removed as the smaller of n1 and size() - pos1.
If size() - xlen >= max_­size() - n2 throws length_­error.
Otherwise, the function replaces the characters in the range [begin() + pos1, begin() + pos1 + xlen) with a copy of the range [s, s + n2).
Returns: *this.
basic_string& replace(size_type pos, size_type n, const charT* s);
Effects: Equivalent to: return replace(pos, n, s, traits::length(s));
basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
Throws:
  • out_­of_­range if pos1 > size(),
  • length_­error if the length of the resulting string would exceed max_­size() (see below), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Determines the effective length xlen of the string to be removed as the smaller of n1 and size() - pos1.
If size() - xlen >= max_­size() - n2 throws length_­error.
Otherwise, the function replaces the characters in the range [begin() + pos1, begin() + pos1 + xlen) with n2 copies of c.
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
Effects: Equivalent to: return replace(i1, i2, basic_­string_­view<charT, traits>(str));
template<class T> basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Expects: [begin(), i1) and [i1, i2) are valid ranges.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return replace(i1 - begin(), i2 - i1, sv.data(), sv.size());
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
Effects: Equivalent to: return replace(i1, i2, basic_­string_­view<charT, traits>(s, n));
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
Effects: Equivalent to: return replace(i1, i2, basic_­string_­view<charT, traits>(s));
basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
Expects: [begin(), i1) and [i1, i2) are valid ranges.
Effects: Equivalent to: return replace(i1 - begin(), i2 - i1, n, c);
template<class InputIterator> basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Equivalent to: return replace(i1, i2, basic_­string(j1, j2, get_­allocator()));
basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<charT> il);
Effects: Equivalent to: return replace(i1, i2, il.begin(), il.size());

20.3.2.6.7 basic_­string​::​copy [string.copy]

size_type copy(charT* s, size_type n, size_type pos = 0) const;
Effects: Equivalent to: return basic_­string_­view<charT, traits>(*this).copy(s, n, pos);
[Note
:
This does not terminate s with a null object.
end note
]

20.3.2.6.8 basic_­string​::​swap [string.swap]

void swap(basic_string& s) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Expects: allocator_­traits<Allocator>::propagate_­on_­container_­swap::value is true or get_­allocator() == s.get_­allocator().
Ensures: *this contains the same sequence of characters that was in s, s contains the same sequence of characters that was in *this.
Throws: Nothing.
Complexity: Constant time.

20.3.2.7 String operations [string.ops]

20.3.2.7.1 Accessors [string.accessors]

const charT* c_str() const noexcept; const charT* data() const noexcept;
Returns: A pointer p such that p + i == addressof(operator[](i)) for each i in [0, size()].
Complexity: Constant time.
Remarks: The program shall not modify any of the values stored in the character array; otherwise, the behavior is undefined.
charT* data() noexcept;
Returns: A pointer p such that p + i == addressof(operator[](i)) for each i in [0, size()].
Complexity: Constant time.
Remarks: The program shall not modify the value stored at p + size() to any value other than charT(); otherwise, the behavior is undefined.
operator basic_string_view<charT, traits>() const noexcept;
Effects: Equivalent to: return basic_­string_­view<charT, traits>(data(), size());
allocator_type get_allocator() const noexcept;
Returns: A copy of the Allocator object used to construct the string or, if that allocator has been replaced, a copy of the most recent replacement.

20.3.2.7.2 Searching [string.find]

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
    size_type F(const basic_string& str, size_type pos) const noexcept;
    
    has effects equivalent to: return F(basic_­string_­view<charT, traits>(str), pos);
  • Each member function of the form
    size_type F(const charT* s, size_type pos) const;
    
    has effects equivalent to: return F(basic_­string_­view<charT, traits>(s), pos);
  • Each member function of the form
    size_type F(const charT* s, size_type pos, size_type n) const;
    
    has effects equivalent to: return F(basic_­string_­view<charT, traits>(s, n), pos);
  • Each member function of the form
    size_type F(charT c, size_type pos) const noexcept;
    
    has effects equivalent to:
    return F(basic_string_view<charT, traits>(addressof(c), 1), pos);
    
template<class T> size_type find(const T& t, size_type pos = 0) const noexcept(see below); template<class T> size_type rfind(const T& t, size_type pos = npos) const noexcept(see below); template<class T> size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below); template<class T> size_type find_last_of(const T& t, size_type pos = npos) const noexcept(see below); template<class T> size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(see below); template<class T> size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(see below);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Let G be the name of the function.
Equivalent to:
basic_string_view<charT, traits> s = *this, sv = t;
return s.G(sv, pos);
Remarks: The expression inside noexcept is equivalent to is_­nothrow_­convertible_­v<const T&, basic_­string_­view<charT, traits>>.

20.3.2.7.3 basic_­string​::​substr [string.substr]

basic_string substr(size_type pos = 0, size_type n = npos) const;
Throws: out_­of_­range if pos > size().
Effects: Determines the effective length rlen of the string to copy as the smaller of n and size() - pos.
Returns: basic_­string(data()+pos, rlen).

20.3.2.7.4 basic_­string​::​compare [string.compare]

template<class T> int compare(const T& t) const noexcept(see below);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to: return basic_­string_­view<charT, traits>(*this).compare(t);
Remarks: The expression inside noexcept is equivalent to is_­nothrow_­convertible_­v<const T&, basic_­string_­view<charT, traits>>.
template<class T> int compare(size_type pos1, size_type n1, const T& t) const;
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
return basic_string_view<charT, traits>(*this).substr(pos1, n1).compare(t);
template<class T> int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const;
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> s = *this, sv = t;
return s.substr(pos1, n1).compare(sv.substr(pos2, n2));
int compare(const basic_string& str) const noexcept;
Effects: Equivalent to: return compare(basic_­string_­view<charT, traits>(str));
int compare(size_type pos1, size_type n1, const basic_string& str) const;
Effects: Equivalent to: return compare(pos1, n1, basic_­string_­view<charT, traits>(str));
int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const;
Effects: Equivalent to:
return compare(pos1, n1, basic_string_view<charT, traits>(str), pos2, n2);
int compare(const charT* s) const;
Effects: Equivalent to: return compare(basic_­string_­view<charT, traits>(s));
int compare(size_type pos, size_type n1, const charT* s) const;
Effects: Equivalent to: return compare(pos, n1, basic_­string_­view<charT, traits>(s));
int compare(size_type pos, size_type n1, const charT* s, size_type n2) const;
Effects: Equivalent to: return compare(pos, n1, basic_­string_­view<charT, traits>(s, n2));

20.3.2.7.5 basic_­string​::​starts_­with [string.starts.with]

bool starts_with(basic_string_view<charT, traits> x) const noexcept; bool starts_with(charT x) const noexcept; bool starts_with(const charT* x) const;
Effects: Equivalent to:
return basic_string_view<charT, traits>(data(), size()).starts_with(x);

20.3.2.7.6 basic_­string​::​ends_­with [string.ends.with]

bool ends_with(basic_string_view<charT, traits> x) const noexcept; bool ends_with(charT x) const noexcept; bool ends_with(const charT* x) const;
Effects: Equivalent to:
return basic_string_view<charT, traits>(data(), size()).ends_with(x);