#include <compare>
#include <initializer_list>
namespace std {
template<class charT> struct char_traits;
template<> struct char_traits<char>;
template<> struct char_traits<char8_t>;
template<> struct char_traits<char16_t>;
template<> struct char_traits<char32_t>;
template<> struct char_traits<wchar_t>;
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
class basic_string;
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(basic_string<charT, traits, Allocator>&& lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(const basic_string<charT, traits, Allocator>& lhs,
basic_string<charT, traits, Allocator>&& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(basic_string<charT, traits, Allocator>&& lhs,
basic_string<charT, traits, Allocator>&& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(const charT* lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(const charT* lhs,
basic_string<charT, traits, Allocator>&& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(charT lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(charT lhs,
basic_string<charT, traits, Allocator>&& rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(const basic_string<charT, traits, Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(basic_string<charT, traits, Allocator>&& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(const basic_string<charT, traits, Allocator>& lhs,
charT rhs);
template<class charT, class traits, class Allocator>
constexpr basic_string<charT, traits, Allocator>
operator+(basic_string<charT, traits, Allocator>&& lhs,
charT rhs);
template<class charT, class traits, class Allocator>
constexpr bool
operator==(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs) noexcept;
template<class charT, class traits, class Allocator>
constexpr bool operator==(const basic_string<charT, traits, Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs) noexcept;
template<class charT, class traits, class Allocator>
constexpr see below operator<=>(const basic_string<charT, traits, Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
constexpr void
swap(basic_string<charT, traits, Allocator>& lhs,
basic_string<charT, traits, Allocator>& rhs)
noexcept(noexcept(lhs.swap(rhs)));
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,
basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,
const basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is,
basic_string<charT, traits, Allocator>& str,
charT delim);
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>&& is,
basic_string<charT, traits, Allocator>& str,
charT delim);
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is,
basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>&& is,
basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator, class U>
constexpr typename basic_string<charT, traits, Allocator>::size_type
erase(basic_string<charT, traits, Allocator>& c, const U& value);
template<class charT, class traits, class Allocator, class Predicate>
constexpr typename basic_string<charT, traits, Allocator>::size_type
erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred);
using string = basic_string<char>;
using u8string = basic_string<char8_t>;
using u16string = basic_string<char16_t>;
using u32string = basic_string<char32_t>;
using wstring = basic_string<wchar_t>;
int stoi(const string& str, size_t* idx = nullptr, int base = 10);
long stol(const string& str, size_t* idx = nullptr, int base = 10);
unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10);
long long stoll(const string& str, size_t* idx = nullptr, int base = 10);
unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
float stof(const string& str, size_t* idx = nullptr);
double stod(const string& str, size_t* idx = nullptr);
long double stold(const string& str, size_t* idx = nullptr);
string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);
int stoi(const wstring& str, size_t* idx = nullptr, int base = 10);
long stol(const wstring& str, size_t* idx = nullptr, int base = 10);
unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10);
long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10);
unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
float stof(const wstring& str, size_t* idx = nullptr);
double stod(const wstring& str, size_t* idx = nullptr);
long double stold(const wstring& str, size_t* idx = nullptr);
wstring to_wstring(int val);
wstring to_wstring(unsigned val);
wstring to_wstring(long val);
wstring to_wstring(unsigned long val);
wstring to_wstring(long long val);
wstring to_wstring(unsigned long long val);
wstring to_wstring(float val);
wstring to_wstring(double val);
wstring to_wstring(long double val);
namespace pmr {
template<class charT, class traits = char_traits<charT>>
using basic_string = std::basic_string<charT, traits, polymorphic_allocator<charT>>;
using string = basic_string<char>;
using u8string = basic_string<char8_t>;
using u16string = basic_string<char16_t>;
using u32string = basic_string<char32_t>;
using wstring = basic_string<wchar_t>;
}
template<class T> struct hash;
template<> struct hash<string>;
template<> struct hash<u8string>;
template<> struct hash<u16string>;
template<> struct hash<u32string>;
template<> struct hash<wstring>;
template<> struct hash<pmr::string>;
template<> struct hash<pmr::u8string>;
template<> struct hash<pmr::u16string>;
template<> struct hash<pmr::u32string>;
template<> struct hash<pmr::wstring>;
inline namespace literals {
inline namespace string_literals {
constexpr string operator""s(const char* str, size_t len);
constexpr u8string operator""s(const char8_t* str, size_t len);
constexpr u16string operator""s(const char16_t* str, size_t len);
constexpr u32string operator""s(const char32_t* str, size_t len);
constexpr wstring operator""s(const wchar_t* str, size_t len);
}
}
}
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.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:
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;
using const_iterator = implementation-defined;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static const size_type npos = -1;
constexpr basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
constexpr explicit basic_string(const Allocator& a) noexcept;
constexpr basic_string(const basic_string& str);
constexpr basic_string(basic_string&& str) noexcept;
constexpr basic_string(const basic_string& str, size_type pos,
const Allocator& a = Allocator());
constexpr basic_string(const basic_string& str, size_type pos, size_type n,
const Allocator& a = Allocator());
template<class T>
constexpr basic_string(const T& t, size_type pos, size_type n,
const Allocator& a = Allocator());
template<class T>
constexpr explicit basic_string(const T& t, const Allocator& a = Allocator());
constexpr basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
constexpr basic_string(const charT* s, const Allocator& a = Allocator());
constexpr basic_string(size_type n, charT c, const Allocator& a = Allocator());
template<class InputIterator>
constexpr basic_string(InputIterator begin, InputIterator end,
const Allocator& a = Allocator());
constexpr basic_string(initializer_list<charT>, const Allocator& = Allocator());
constexpr basic_string(const basic_string&, const Allocator&);
constexpr basic_string(basic_string&&, const Allocator&);
constexpr ~basic_string();
constexpr basic_string& operator=(const basic_string& str);
constexpr 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>
constexpr basic_string& operator=(const T& t);
constexpr basic_string& operator=(const charT* s);
constexpr basic_string& operator=(charT c);
constexpr basic_string& operator=(initializer_list<charT>);
constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;
constexpr iterator end() noexcept;
constexpr const_iterator end() const noexcept;
constexpr reverse_iterator rbegin() noexcept;
constexpr const_reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() noexcept;
constexpr const_reverse_iterator rend() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
constexpr size_type size() const noexcept;
constexpr size_type length() const noexcept;
constexpr size_type max_size() const noexcept;
constexpr void resize(size_type n, charT c);
constexpr void resize(size_type n);
constexpr size_type capacity() const noexcept;
constexpr void reserve(size_type res_arg);
constexpr void shrink_to_fit();
constexpr void clear() noexcept;
[[nodiscard]] constexpr bool empty() const noexcept;
constexpr const_reference operator[](size_type pos) const;
constexpr reference operator[](size_type pos);
constexpr const_reference at(size_type n) const;
constexpr reference at(size_type n);
constexpr const charT& front() const;
constexpr charT& front();
constexpr const charT& back() const;
constexpr charT& back();
constexpr basic_string& operator+=(const basic_string& str);
template<class T>
constexpr basic_string& operator+=(const T& t);
constexpr basic_string& operator+=(const charT* s);
constexpr basic_string& operator+=(charT c);
constexpr basic_string& operator+=(initializer_list<charT>);
constexpr basic_string& append(const basic_string& str);
constexpr basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
template<class T>
constexpr basic_string& append(const T& t);
template<class T>
constexpr basic_string& append(const T& t, size_type pos, size_type n = npos);
constexpr basic_string& append(const charT* s, size_type n);
constexpr basic_string& append(const charT* s);
constexpr basic_string& append(size_type n, charT c);
template<class InputIterator>
constexpr basic_string& append(InputIterator first, InputIterator last);
constexpr basic_string& append(initializer_list<charT>);
constexpr void push_back(charT c);
constexpr basic_string& assign(const basic_string& str);
constexpr basic_string& assign(basic_string&& str)
noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
allocator_traits<Allocator>::is_always_equal::value);
constexpr basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
template<class T>
constexpr basic_string& assign(const T& t);
template<class T>
constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos);
constexpr basic_string& assign(const charT* s, size_type n);
constexpr basic_string& assign(const charT* s);
constexpr basic_string& assign(size_type n, charT c);
template<class InputIterator>
constexpr basic_string& assign(InputIterator first, InputIterator last);
constexpr basic_string& assign(initializer_list<charT>);
constexpr basic_string& insert(size_type pos, const basic_string& str);
constexpr basic_string& insert(size_type pos1, const basic_string& str,
size_type pos2, size_type n = npos);
template<class T>
constexpr basic_string& insert(size_type pos, const T& t);
template<class T>
constexpr basic_string& insert(size_type pos1, const T& t,
size_type pos2, size_type n = npos);
constexpr basic_string& insert(size_type pos, const charT* s, size_type n);
constexpr basic_string& insert(size_type pos, const charT* s);
constexpr basic_string& insert(size_type pos, size_type n, charT c);
constexpr iterator insert(const_iterator p, charT c);
constexpr iterator insert(const_iterator p, size_type n, charT c);
template<class InputIterator>
constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last);
constexpr iterator insert(const_iterator p, initializer_list<charT>);
constexpr basic_string& erase(size_type pos = 0, size_type n = npos);
constexpr iterator erase(const_iterator p);
constexpr iterator erase(const_iterator first, const_iterator last);
constexpr void pop_back();
constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
size_type pos2, size_type n2 = npos);
template<class T>
constexpr basic_string& replace(size_type pos1, size_type n1, const T& t);
template<class T>
constexpr basic_string& replace(size_type pos1, size_type n1, const T& t,
size_type pos2, size_type n2 = npos);
constexpr basic_string& replace(size_type pos, size_type n1, const charT* s, size_type n2);
constexpr basic_string& replace(size_type pos, size_type n1, const charT* s);
constexpr basic_string& replace(size_type pos, size_type n1, size_type n2, charT c);
constexpr basic_string& replace(const_iterator i1, const_iterator i2,
const basic_string& str);
template<class T>
constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s,
size_type n);
constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
template<class InputIterator>
constexpr basic_string& replace(const_iterator i1, const_iterator i2,
InputIterator j1, InputIterator j2);
constexpr basic_string& replace(const_iterator, const_iterator, initializer_list<charT>);
constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const;
constexpr void swap(basic_string& str)
noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
allocator_traits<Allocator>::is_always_equal::value);
constexpr const charT* c_str() const noexcept;
constexpr const charT* data() const noexcept;
constexpr charT* data() noexcept;
constexpr operator basic_string_view<charT, traits>() const noexcept;
constexpr allocator_type get_allocator() const noexcept;
template<class T>
constexpr size_type find(const T& t, size_type pos = 0) const noexcept(see below);
constexpr size_type find(const basic_string& str, 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 find(charT c, size_type pos = 0) const noexcept;
template<class T>
constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(see below);
constexpr size_type rfind(const basic_string& str, 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 rfind(charT c, size_type pos = npos) const noexcept;
template<class T>
constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below);
constexpr size_type find_first_of(const basic_string& str, 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_first_of(charT c, size_type pos = 0) const noexcept;
template<class T>
constexpr size_type find_last_of(const T& t,
size_type pos = npos) const noexcept(see below);
constexpr size_type find_last_of(const basic_string& str,
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_last_of(charT c, size_type pos = npos) const noexcept;
template<class T>
constexpr size_type find_first_not_of(const T& t,
size_type pos = 0) const noexcept(see below);
constexpr size_type find_first_not_of(const basic_string& str,
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_first_not_of(charT c, size_type pos = 0) const noexcept;
template<class T>
constexpr size_type find_last_not_of(const T& t,
size_type pos = npos) const noexcept(see below);
constexpr size_type find_last_not_of(const basic_string& str,
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;
constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
constexpr basic_string substr(size_type pos = 0, size_type n = npos) const;
template<class T>
constexpr int compare(const T& t) const noexcept(see below);
template<class T>
constexpr int compare(size_type pos1, size_type n1, const T& t) const;
template<class T>
constexpr int compare(size_type pos1, size_type n1, const T& t,
size_type pos2, size_type n2 = npos) const;
constexpr int compare(const basic_string& str) const noexcept;
constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const;
constexpr int compare(size_type pos1, size_type n1, const basic_string& str,
size_type pos2, size_type n2 = npos) 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<charT, traits> 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<charT, traits> x) const noexcept;
constexpr bool ends_with(charT x) const noexcept;
constexpr 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
.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
. In every specialization
basic_string<charT, traits, Allocator>,
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 ]
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
.Calling non-const member functions, except
operator[],
at,
data,
front,
back,
begin,
rbegin,
end,
and
rend.
constexpr explicit basic_string(const Allocator& a) noexcept;
Postconditions:
size() is equal to
0. constexpr basic_string(const basic_string& str);
constexpr 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
. constexpr basic_string(const basic_string& str, size_type pos,
const Allocator& a = Allocator());
constexpr 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>
constexpr 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>
constexpr 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). constexpr basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
Preconditions:
[s, s + n) is a valid range
. Effects:
Constructs an object whose initial value is the range
[s, s + n). Postconditions:
size() is equal to
n, and
traits::compare(data(), s, n) is equal to
0. constexpr basic_string(const charT* s, const Allocator& a = Allocator());
[
Note: This affects class template argument deduction
. —
end note ]
Effects:
Equivalent to:
basic_string(s, traits::length(s), a). constexpr basic_string(size_type n, charT c, const Allocator& a = Allocator());
[
Note: This affects class template argument deduction
. —
end note ]
Effects:
Constructs an object whose value consists of
n copies of
c. template<class InputIterator>
constexpr basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
Effects:
Constructs a string from the values in the range
[begin, end),
as indicated in Table
77. constexpr basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
Effects:
Equivalent to
basic_string(il.begin(), il.end(), a). constexpr basic_string(const basic_string& str, const Allocator& alloc);
constexpr 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>;
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>;
constexpr 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.constexpr 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
. template<class T>
constexpr 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);
constexpr basic_string& operator=(const charT* s);
Effects:
Equivalent to:
return *this = basic_string_view<charT, traits>(s);
constexpr basic_string& operator=(charT c);
Effects:
Equivalent to:
return *this = basic_string_view<charT, traits>(addressof(c), 1);
constexpr basic_string& operator=(initializer_list<charT> il);
Effects:
Equivalent to:
return *this = basic_string_view<charT, traits>(il.begin(), il.size());
constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;
constexpr const_iterator cbegin() const noexcept;
Returns:
An iterator referring to the first character in the string
. constexpr iterator end() noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cend() const noexcept;
Returns:
An iterator which is the past-the-end value
. constexpr reverse_iterator rbegin() noexcept;
constexpr const_reverse_iterator rbegin() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
Returns:
An iterator which is semantically equivalent to
reverse_iterator(end()). constexpr reverse_iterator rend() noexcept;
constexpr const_reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
Returns:
An iterator which is semantically equivalent to
reverse_iterator(begin()). constexpr size_type size() const noexcept;
constexpr size_type length() const noexcept;
Returns:
A count of the number of char-like objects currently in the string
. Complexity:
Constant time
. constexpr 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
. constexpr 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.
constexpr void resize(size_type n);
Effects:
Equivalent to
resize(n, charT()). constexpr size_type capacity() const noexcept;
Returns:
The size of the allocated storage in the string
. Complexity:
Constant time
. constexpr 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. constexpr 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:
If the size is not equal to the old capacity,
linear in the size of the sequence;
otherwise constant
. Remarks:
Reallocation invalidates all the references, pointers, and iterators
referring to the elements in the sequence, as well as the past-the-end iterator
. [
Note: If no reallocation happens, they remain valid
. —
end note ]
constexpr void clear() noexcept;
Effects:
Equivalent to: erase(begin(), end());
[[nodiscard]] constexpr bool empty() const noexcept;
Effects:
Equivalent to:
return size() == 0;
constexpr const_reference operator[](size_type pos) const;
constexpr reference operator[](size_type pos);
Preconditions:
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
.Complexity:
Constant time
.
constexpr const_reference at(size_type pos) const;
constexpr reference at(size_type pos);
Throws:
out_of_range
if
pos >= size(). Returns:
operator[](pos).
constexpr const charT& front() const;
constexpr charT& front();
Effects:
Equivalent to: return operator[](0);
constexpr const charT& back() const;
constexpr charT& back();
Effects:
Equivalent to: return operator[](size() - 1);
constexpr basic_string& operator+=(const basic_string& str);
Effects:
Equivalent to: return append(str);
template<class T>
constexpr 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);
constexpr basic_string& operator+=(const charT* s);
Effects:
Equivalent to: return append(s);
constexpr basic_string& operator+=(charT c);
Effects:
Equivalent to: return append(size_type{1}, c);
constexpr basic_string& operator+=(initializer_list<charT> il);
Effects:
Equivalent to: return append(il);
constexpr basic_string& append(const basic_string& str);
Effects:
Equivalent to: return append(str.data(), str.size());
constexpr 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>
constexpr 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>
constexpr 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));
constexpr basic_string& append(const charT* s, size_type n);
Preconditions:
[s, s + n) is a valid range
. Effects:
Appends a copy of the range
[s, s + n) to the string
. constexpr basic_string& append(const charT* s);
Effects:
Equivalent to: return append(s, traits::length(s));
constexpr basic_string& append(size_type n, charT c);
Effects:
Appends
n copies of
c to the string
. template<class InputIterator>
constexpr basic_string& append(InputIterator first, InputIterator last);
Effects:
Equivalent to: return append(basic_string(first, last, get_allocator()));
constexpr basic_string& append(initializer_list<charT> il);
Effects:
Equivalent to: return append(il.begin(), il.size());
constexpr void push_back(charT c);
Effects:
Equivalent to
append(size_type{1}, c). constexpr basic_string& assign(const basic_string& str);
Effects:
Equivalent to: return *this = str;
constexpr 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);
constexpr 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>
constexpr 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>
constexpr 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));
constexpr basic_string& assign(const charT* s, size_type n);
Preconditions:
[s, s + n) is a valid range
. Effects:
Replaces the string controlled by
*this with
a copy of the range
[s, s + n). constexpr basic_string& assign(const charT* s);
Effects:
Equivalent to: return assign(s, traits::length(s));
constexpr basic_string& assign(initializer_list<charT> il);
Effects:
Equivalent to: return assign(il.begin(), il.size());
constexpr basic_string& assign(size_type n, charT c);
Effects:
Equivalent to:
clear();
resize(n, c);
return *this;
template<class InputIterator>
constexpr basic_string& assign(InputIterator first, InputIterator last);
Effects:
Equivalent to: return assign(basic_string(first, last, get_allocator()));
constexpr basic_string& insert(size_type pos, const basic_string& str);
Effects:
Equivalent to: return insert(pos, str.data(), str.size());
constexpr 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>
constexpr 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>
constexpr 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));
constexpr basic_string& insert(size_type pos, const charT* s, size_type n);
Preconditions:
[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
. constexpr basic_string& insert(size_type pos, const charT* s);
Effects:
Equivalent to: return insert(pos, s, traits::length(s));
constexpr basic_string& insert(size_type pos, size_type n, charT c);
Effects:
Inserts
n copies of
c before the character at position
pos
if
pos < size(),
or otherwise at the end of the string
. Throws:
- out_of_range if pos > size(),
- length_error if n > max_size() - size(), or
- any exceptions thrown by allocator_traits<Allocator>::allocate.
constexpr iterator insert(const_iterator p, charT c);
Preconditions:
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
. constexpr iterator insert(const_iterator p, size_type n, charT c);
Preconditions:
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>
constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last);
Preconditions:
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. constexpr iterator insert(const_iterator p, initializer_list<charT> il);
Effects:
Equivalent to: return insert(p, il.begin(), il.end());
constexpr 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).constexpr iterator erase(const_iterator p);
Preconditions:
p is a valid dereferenceable iterator on
*this. 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
.constexpr iterator erase(const_iterator first, const_iterator last);
Preconditions:
first and
last are valid iterators on
*this. [first, last) is a valid range
. 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
.constexpr void pop_back();
Effects:
Equivalent to
erase(end() - 1). constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
Effects:
Equivalent to: return replace(pos1, n1, str.data(), str.size());
constexpr 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>
constexpr 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>
constexpr 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));
constexpr basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2);
Preconditions:
[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).constexpr basic_string& replace(size_type pos, size_type n, const charT* s);
Effects:
Equivalent to: return replace(pos, n, s, traits::length(s));
constexpr 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.constexpr 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>
constexpr 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.
Preconditions:
[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());
constexpr 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));
constexpr 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));
constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
Preconditions:
[begin(), i1) and
[i1, i2) are valid ranges
. Effects:
Equivalent to: return replace(i1 - begin(), i2 - i1, n, c);
template<class InputIterator>
constexpr basic_string& replace(const_iterator i1, const_iterator i2,
InputIterator j1, InputIterator j2);
Effects:
Equivalent to: return replace(i1, i2, basic_string(j1, j2, get_allocator()));
constexpr basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<charT> il);
Effects:
Equivalent to: return replace(i1, i2, il.begin(), il.size());
constexpr 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
]
constexpr void swap(basic_string& s)
noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
allocator_traits<Allocator>::is_always_equal::value);
Preconditions:
allocator_traits<Allocator>::propagate_on_container_swap::value is
true
or
get_allocator() == s.get_allocator(). Postconditions:
*this
contains the same sequence of characters that was in
s,
s contains the same sequence of characters that was in
*this. Complexity:
Constant time
. constexpr const charT* c_str() const noexcept;
constexpr 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
. constexpr 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
. constexpr operator basic_string_view<charT, traits>() const noexcept;
Effects:
Equivalent to:
return basic_string_view<charT, traits>(data(), size());
constexpr 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
. 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 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
constexpr 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
constexpr 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
constexpr 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>
constexpr size_type find(const T& t, size_type pos = 0) const noexcept(see below);
template<class T>
constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(see below);
template<class T>
constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below);
template<class T>
constexpr size_type find_last_of(const T& t, size_type pos = npos) const noexcept(see below);
template<class T>
constexpr size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(see below);
template<class T>
constexpr 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>>. constexpr 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). template<class T>
constexpr 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>
constexpr 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>
constexpr 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));
constexpr int compare(const basic_string& str) const noexcept;
Effects:
Equivalent to:
return compare(basic_string_view<charT, traits>(str));
constexpr 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));
constexpr 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);
constexpr int compare(const charT* s) const;
Effects:
Equivalent to:
return compare(basic_string_view<charT, traits>(s));
constexpr 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));
constexpr 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));
constexpr bool starts_with(basic_string_view<charT, traits> x) const noexcept;
constexpr bool starts_with(charT x) const noexcept;
constexpr bool starts_with(const charT* x) const;
Effects:
Equivalent to:
return basic_string_view<charT, traits>(data(), size()).starts_with(x);
constexpr bool ends_with(basic_string_view<charT, traits> x) const noexcept;
constexpr bool ends_with(charT x) const noexcept;
constexpr bool ends_with(const charT* x) const;
Effects:
Equivalent to:
return basic_string_view<charT, traits>(data(), size()).ends_with(x);