2010-05-12 03:42:16 +08:00
|
|
|
// -*- C++ -*-
|
|
|
|
//===--------------------------- string -----------------------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_STRING
|
|
|
|
#define _LIBCPP_STRING
|
|
|
|
|
|
|
|
/*
|
|
|
|
string synopsis
|
|
|
|
|
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
|
|
|
|
template <class stateT>
|
|
|
|
class fpos
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
stateT st;
|
|
|
|
public:
|
|
|
|
fpos(streamoff = streamoff());
|
|
|
|
|
|
|
|
operator streamoff() const;
|
|
|
|
|
|
|
|
stateT state() const;
|
|
|
|
void state(stateT);
|
|
|
|
|
|
|
|
fpos& operator+=(streamoff);
|
|
|
|
fpos operator+ (streamoff) const;
|
|
|
|
fpos& operator-=(streamoff);
|
|
|
|
fpos operator- (streamoff) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
|
|
|
|
|
|
|
|
template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
|
|
|
|
template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
|
|
|
|
|
|
|
|
template <class charT>
|
|
|
|
struct char_traits
|
|
|
|
{
|
|
|
|
typedef charT char_type;
|
|
|
|
typedef ... int_type;
|
|
|
|
typedef streamoff off_type;
|
|
|
|
typedef streampos pos_type;
|
|
|
|
typedef mbstate_t state_type;
|
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
static void assign(char_type& c1, const char_type& c2) noexcept;
|
2012-07-21 03:09:12 +08:00
|
|
|
static constexpr bool eq(char_type c1, char_type c2) noexcept;
|
|
|
|
static constexpr bool lt(char_type c1, char_type c2) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
static int compare(const char_type* s1, const char_type* s2, size_t n);
|
|
|
|
static size_t length(const char_type* s);
|
|
|
|
static const char_type* find(const char_type* s, size_t n, const char_type& a);
|
|
|
|
static char_type* move(char_type* s1, const char_type* s2, size_t n);
|
|
|
|
static char_type* copy(char_type* s1, const char_type* s2, size_t n);
|
|
|
|
static char_type* assign(char_type* s, size_t n, char_type a);
|
|
|
|
|
2012-07-21 03:09:12 +08:00
|
|
|
static constexpr int_type not_eof(int_type c) noexcept;
|
|
|
|
static constexpr char_type to_char_type(int_type c) noexcept;
|
|
|
|
static constexpr int_type to_int_type(char_type c) noexcept;
|
|
|
|
static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
|
|
|
|
static constexpr int_type eof() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <> struct char_traits<char>;
|
|
|
|
template <> struct char_traits<wchar_t>;
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
|
2010-05-12 03:42:16 +08:00
|
|
|
class basic_string
|
|
|
|
{
|
2010-08-22 08:02:43 +08:00
|
|
|
public:
|
|
|
|
// types:
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef traits traits_type;
|
|
|
|
typedef typename traits_type::char_type value_type;
|
|
|
|
typedef Allocator allocator_type;
|
|
|
|
typedef typename allocator_type::size_type size_type;
|
|
|
|
typedef typename allocator_type::difference_type difference_type;
|
|
|
|
typedef typename allocator_type::reference reference;
|
|
|
|
typedef typename allocator_type::const_reference const_reference;
|
|
|
|
typedef typename allocator_type::pointer pointer;
|
|
|
|
typedef typename allocator_type::const_pointer const_pointer;
|
|
|
|
typedef implementation-defined iterator;
|
|
|
|
typedef implementation-defined const_iterator;
|
|
|
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
|
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
|
|
|
|
|
|
static const size_type npos = -1;
|
|
|
|
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string()
|
|
|
|
noexcept(is_nothrow_default_constructible<allocator_type>::value);
|
|
|
|
explicit basic_string(const allocator_type& a);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(const basic_string& str);
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string(basic_string&& str)
|
|
|
|
noexcept(is_nothrow_move_constructible<allocator_type>::value);
|
2016-04-08 02:13:41 +08:00
|
|
|
basic_string(const basic_string& str, size_type pos,
|
2010-06-03 02:20:39 +08:00
|
|
|
const allocator_type& a = allocator_type());
|
2016-04-08 02:13:41 +08:00
|
|
|
basic_string(const basic_string& str, size_type pos, size_type n,
|
2016-07-21 13:31:24 +08:00
|
|
|
const Allocator& a = Allocator());
|
2016-11-15 02:22:19 +08:00
|
|
|
template<class T>
|
|
|
|
basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string(const value_type* s, const allocator_type& a = allocator_type());
|
|
|
|
basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
|
|
|
|
template<class InputIterator>
|
2010-06-03 02:20:39 +08:00
|
|
|
basic_string(InputIterator begin, InputIterator end,
|
|
|
|
const allocator_type& a = allocator_type());
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(initializer_list<value_type>, const Allocator& = Allocator());
|
|
|
|
basic_string(const basic_string&, const Allocator&);
|
|
|
|
basic_string(basic_string&&, const Allocator&);
|
|
|
|
|
|
|
|
~basic_string();
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
operator basic_string_view<charT, traits>() const noexcept;
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& operator=(const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& operator=(const T& t); // C++17
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string& operator=(basic_string&& str)
|
|
|
|
noexcept(
|
2015-08-19 02:57:00 +08:00
|
|
|
allocator_type::propagate_on_container_move_assignment::value ||
|
|
|
|
allocator_type::is_always_equal::value ); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& operator=(const value_type* s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& operator=(value_type c);
|
|
|
|
basic_string& operator=(initializer_list<value_type>);
|
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
iterator begin() noexcept;
|
|
|
|
const_iterator begin() const noexcept;
|
|
|
|
iterator end() noexcept;
|
|
|
|
const_iterator end() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
reverse_iterator rbegin() noexcept;
|
|
|
|
const_reverse_iterator rbegin() const noexcept;
|
|
|
|
reverse_iterator rend() noexcept;
|
|
|
|
const_reverse_iterator rend() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
const_iterator cbegin() const noexcept;
|
|
|
|
const_iterator cend() const noexcept;
|
|
|
|
const_reverse_iterator crbegin() const noexcept;
|
|
|
|
const_reverse_iterator crend() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type size() const noexcept;
|
|
|
|
size_type length() const noexcept;
|
|
|
|
size_type max_size() const noexcept;
|
|
|
|
size_type capacity() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void resize(size_type n, value_type c);
|
|
|
|
void resize(size_type n);
|
|
|
|
|
|
|
|
void reserve(size_type res_arg = 0);
|
|
|
|
void shrink_to_fit();
|
2011-05-30 03:57:12 +08:00
|
|
|
void clear() noexcept;
|
|
|
|
bool empty() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
const_reference operator[](size_type pos) const;
|
|
|
|
reference operator[](size_type pos);
|
|
|
|
|
|
|
|
const_reference at(size_type n) const;
|
|
|
|
reference at(size_type n);
|
|
|
|
|
|
|
|
basic_string& operator+=(const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& operator+=(const T& t); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& operator+=(const value_type* s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& operator+=(value_type c);
|
|
|
|
basic_string& operator+=(initializer_list<value_type>);
|
|
|
|
|
|
|
|
basic_string& append(const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& append(const T& t); // C++17
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& append(const value_type* s, size_type n);
|
|
|
|
basic_string& append(const value_type* s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& append(size_type n, value_type c);
|
2010-06-03 02:20:39 +08:00
|
|
|
template<class InputIterator>
|
|
|
|
basic_string& append(InputIterator first, InputIterator last);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& append(initializer_list<value_type>);
|
|
|
|
|
|
|
|
void push_back(value_type c);
|
|
|
|
void pop_back();
|
|
|
|
reference front();
|
|
|
|
const_reference front() const;
|
|
|
|
reference back();
|
|
|
|
const_reference back() const;
|
|
|
|
|
|
|
|
basic_string& assign(const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& assign(const T& t); // C++17
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string& assign(basic_string&& str);
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& assign(const value_type* s, size_type n);
|
|
|
|
basic_string& assign(const value_type* s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& assign(size_type n, value_type c);
|
2010-06-03 02:20:39 +08:00
|
|
|
template<class InputIterator>
|
|
|
|
basic_string& assign(InputIterator first, InputIterator last);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& assign(initializer_list<value_type>);
|
|
|
|
|
|
|
|
basic_string& insert(size_type pos1, const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& insert(size_type pos1, const T& t);
|
2010-06-03 02:20:39 +08:00
|
|
|
basic_string& insert(size_type pos1, const basic_string& str,
|
|
|
|
size_type pos2, size_type n);
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& insert(size_type pos, const value_type* s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& insert(size_type pos, size_type n, value_type c);
|
|
|
|
iterator insert(const_iterator p, value_type c);
|
|
|
|
iterator insert(const_iterator p, size_type n, value_type c);
|
2010-06-03 02:20:39 +08:00
|
|
|
template<class InputIterator>
|
|
|
|
iterator insert(const_iterator p, InputIterator first, InputIterator last);
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator p, initializer_list<value_type>);
|
|
|
|
|
|
|
|
basic_string& erase(size_type pos = 0, size_type n = npos);
|
|
|
|
iterator erase(const_iterator position);
|
|
|
|
iterator erase(const_iterator first, const_iterator last);
|
|
|
|
|
|
|
|
basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17
|
2010-06-03 02:20:39 +08:00
|
|
|
basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
|
2014-03-05 03:17:19 +08:00
|
|
|
size_type pos2, size_type n2=npos); // C++14
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& replace(size_type pos1, size_type n1, const T& t,
|
|
|
|
size_type pos2, size_type n); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);
|
|
|
|
basic_string& replace(size_type pos, size_type n1, const value_type* s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);
|
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);
|
2010-06-03 02:20:39 +08:00
|
|
|
template<class InputIterator>
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
|
|
|
|
basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type copy(value_type* s, size_type n, size_type pos = 0) const;
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string substr(size_type pos = 0, size_type n = npos) const;
|
|
|
|
|
2011-06-04 02:40:47 +08:00
|
|
|
void swap(basic_string& str)
|
2015-07-14 04:04:56 +08:00
|
|
|
noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
|
|
|
|
allocator_traits<allocator_type>::is_always_equal::value); // C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-06-29 00:59:19 +08:00
|
|
|
const value_type* c_str() const noexcept;
|
|
|
|
const value_type* data() const noexcept;
|
2016-03-08 23:44:30 +08:00
|
|
|
value_type* data() noexcept; // C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
allocator_type get_allocator() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find(const basic_string& str, size_type pos = 0) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
size_type find(const T& t, size_type pos = 0) const; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
|
|
|
|
size_type find(const value_type* s, size_type pos = 0) const noexcept;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find(value_type c, size_type pos = 0) const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
size_type rfind(const T& t, size_type pos = npos) const; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
|
|
|
|
size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type rfind(value_type c, size_type pos = npos) const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
size_type find_first_of(const T& t, size_type pos = 0) const; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
|
|
|
|
size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
size_type find_last_of(const T& t, size_type pos = npos) const noexcept; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
|
|
|
|
size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
size_type find_first_not_of(const T& t, size_type pos = 0) const; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
|
|
|
|
size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
size_type find_last_not_of(const T& t, size_type pos = npos) const; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
|
|
|
|
size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
int compare(const basic_string& str) const noexcept;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
int compare(const T& t) const noexcept; // C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
int compare(size_type pos1, size_type n1, const basic_string& str) const;
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class T>
|
|
|
|
int compare(size_type pos1, size_type n1, const T& t) const; // C++17
|
2010-06-03 02:20:39 +08:00
|
|
|
int compare(size_type pos1, size_type n1, const basic_string& str,
|
2014-03-05 03:17:19 +08:00
|
|
|
size_type pos2, size_type n2=npos) const; // C++14
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class T>
|
|
|
|
int compare(size_type pos1, size_type n1, const T& t,
|
|
|
|
size_type pos2, size_type n2=npos) const; // C++17
|
2013-06-29 00:59:19 +08:00
|
|
|
int compare(const value_type* s) const noexcept;
|
|
|
|
int compare(size_type pos1, size_type n1, const value_type* s) const;
|
|
|
|
int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-12-05 04:11:38 +08:00
|
|
|
bool starts_with(basic_string_view<charT, traits> sv) const noexcept; // C++2a
|
|
|
|
bool starts_with(charT c) const noexcept; // C++2a
|
|
|
|
bool starts_with(const charT* s) const; // C++2a
|
|
|
|
bool ends_with(basic_string_view<charT, traits> sv) const noexcept; // C++2a
|
|
|
|
bool ends_with(charT c) const noexcept; // C++2a
|
|
|
|
bool ends_with(const charT* s) const; // C++2a
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
bool __invariants() const;
|
|
|
|
};
|
|
|
|
|
2018-02-08 14:34:03 +08:00
|
|
|
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>; // C++17
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class charT, class traits, class Allocator>
|
|
|
|
basic_string<charT, traits, Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
operator+(const basic_string<charT, traits, Allocator>& lhs,
|
|
|
|
const basic_string<charT, traits, Allocator>& rhs);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
|
|
|
basic_string<charT, traits, Allocator>
|
|
|
|
operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);
|
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
|
|
|
basic_string<charT, traits, Allocator>
|
|
|
|
operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);
|
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
|
|
|
basic_string<charT, traits, Allocator>
|
|
|
|
operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
|
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
|
|
|
basic_string<charT, traits, Allocator>
|
|
|
|
operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
|
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
bool operator==(const basic_string<charT, traits, Allocator>& lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
bool operator< (const basic_string<charT, traits, Allocator>& lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
bool operator> (const basic_string<charT, traits, Allocator>& lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2011-05-30 03:57:12 +08:00
|
|
|
bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
2010-06-03 02:20:39 +08:00
|
|
|
void swap(basic_string<charT, traits, Allocator>& lhs,
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string<charT, traits, Allocator>& rhs)
|
|
|
|
noexcept(noexcept(lhs.swap(rhs)));
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
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>
|
2010-08-22 08:02:43 +08:00
|
|
|
basic_istream<charT, traits>&
|
2010-06-03 02:20:39 +08:00
|
|
|
getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
|
|
|
|
charT delim);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class charT, class traits, class Allocator>
|
|
|
|
basic_istream<charT, traits>&
|
|
|
|
getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
|
|
|
|
|
2018-12-15 02:49:35 +08:00
|
|
|
template<class charT, class traits, class Allocator, class U>
|
2020-05-02 19:58:03 +08:00
|
|
|
typename basic_string<charT, traits, Allocator>::size_type
|
|
|
|
erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
|
2018-12-15 02:49:35 +08:00
|
|
|
template<class charT, class traits, class Allocator, class Predicate>
|
2020-05-02 19:58:03 +08:00
|
|
|
typename basic_string<charT, traits, Allocator>::size_type
|
|
|
|
erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
|
2018-12-15 02:49:35 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef basic_string<char> string;
|
|
|
|
typedef basic_string<wchar_t> wstring;
|
2010-06-03 02:20:39 +08:00
|
|
|
typedef basic_string<char16_t> u16string;
|
|
|
|
typedef basic_string<char32_t> u32string;
|
|
|
|
|
|
|
|
int stoi (const string& str, size_t* idx = 0, int base = 10);
|
|
|
|
long stol (const string& str, size_t* idx = 0, int base = 10);
|
|
|
|
unsigned long stoul (const string& str, size_t* idx = 0, int base = 10);
|
|
|
|
long long stoll (const string& str, size_t* idx = 0, int base = 10);
|
|
|
|
unsigned long long stoull(const string& str, size_t* idx = 0, int base = 10);
|
|
|
|
|
|
|
|
float stof (const string& str, size_t* idx = 0);
|
|
|
|
double stod (const string& str, size_t* idx = 0);
|
|
|
|
long double stold(const string& str, size_t* idx = 0);
|
|
|
|
|
|
|
|
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 = 0, int base = 10);
|
|
|
|
long stol (const wstring& str, size_t* idx = 0, int base = 10);
|
|
|
|
unsigned long stoul (const wstring& str, size_t* idx = 0, int base = 10);
|
|
|
|
long long stoll (const wstring& str, size_t* idx = 0, int base = 10);
|
|
|
|
unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);
|
|
|
|
|
|
|
|
float stof (const wstring& str, size_t* idx = 0);
|
|
|
|
double stod (const wstring& str, size_t* idx = 0);
|
|
|
|
long double stold(const wstring& str, size_t* idx = 0);
|
|
|
|
|
|
|
|
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);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <> struct hash<string>;
|
|
|
|
template <> struct hash<u16string>;
|
|
|
|
template <> struct hash<u32string>;
|
|
|
|
template <> struct hash<wstring>;
|
|
|
|
|
2013-07-24 01:05:24 +08:00
|
|
|
basic_string<char> operator "" s( const char *str, size_t len ); // C++14
|
|
|
|
basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14
|
|
|
|
basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
|
|
|
|
basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <__config>
|
2016-07-21 13:31:24 +08:00
|
|
|
#include <string_view>
|
2010-05-12 03:42:16 +08:00
|
|
|
#include <iosfwd>
|
|
|
|
#include <cstring>
|
2010-05-25 01:49:41 +08:00
|
|
|
#include <cstdio> // For EOF.
|
2010-05-12 03:42:16 +08:00
|
|
|
#include <cwchar>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <iterator>
|
|
|
|
#include <utility>
|
|
|
|
#include <memory>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <initializer_list>
|
|
|
|
#include <__functional_base>
|
2018-09-13 03:41:40 +08:00
|
|
|
#include <version>
|
2010-05-12 03:42:16 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
|
|
|
|
#include <cstdint>
|
|
|
|
#endif
|
2016-07-21 13:31:24 +08:00
|
|
|
|
2014-08-11 07:53:08 +08:00
|
|
|
#include <__debug>
|
|
|
|
|
2011-10-18 04:05:10 +08:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2010-05-12 03:42:16 +08:00
|
|
|
#pragma GCC system_header
|
2011-10-18 04:05:10 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-06-01 06:07:49 +08:00
|
|
|
_LIBCPP_PUSH_MACROS
|
|
|
|
#include <__undef_macros>
|
|
|
|
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
|
|
|
// fpos
|
|
|
|
|
|
|
|
template <class _StateT>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS fpos
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
_StateT __st_;
|
|
|
|
streamoff __off_;
|
|
|
|
public:
|
|
|
|
_LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY fpos& operator+=(streamoff __off) {__off_ += __off; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY fpos operator+ (streamoff __off) const {fpos __t(*this); __t += __off; return __t;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY fpos operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _StateT>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
|
|
|
|
{return streamoff(__x) - streamoff(__y);}
|
|
|
|
|
|
|
|
template <class _StateT>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
|
|
|
|
{return streamoff(__x) == streamoff(__y);}
|
|
|
|
|
|
|
|
template <class _StateT>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
|
|
|
|
{return streamoff(__x) != streamoff(__y);}
|
|
|
|
|
|
|
|
// basic_string
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
2011-06-15 03:58:17 +08:00
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
2011-06-15 03:58:17 +08:00
|
|
|
operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
2011-06-15 03:58:17 +08:00
|
|
|
operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-22 01:31:55 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
2011-06-15 03:58:17 +08:00
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
2011-06-15 03:58:17 +08:00
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-07-29 10:54:41 +08:00
|
|
|
_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <bool>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS __basic_string_common
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
protected:
|
2016-08-25 23:09:01 +08:00
|
|
|
_LIBCPP_NORETURN void __throw_length_error() const;
|
|
|
|
_LIBCPP_NORETURN void __throw_out_of_range() const;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <bool __b>
|
|
|
|
void
|
|
|
|
__basic_string_common<__b>::__throw_length_error() const
|
|
|
|
{
|
2016-08-25 23:09:01 +08:00
|
|
|
_VSTD::__throw_length_error("basic_string");
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <bool __b>
|
|
|
|
void
|
|
|
|
__basic_string_common<__b>::__throw_out_of_range() const
|
|
|
|
{
|
2016-08-25 23:09:01 +08:00
|
|
|
_VSTD::__throw_out_of_range("basic_string");
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-09-16 06:27:07 +08:00
|
|
|
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common<true>)
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-01-14 05:54:34 +08:00
|
|
|
#ifdef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {};
|
|
|
|
#elif defined(_LIBCPP_HAS_NO_NOEXCEPT)
|
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {};
|
|
|
|
#else
|
2019-11-18 14:46:58 +08:00
|
|
|
template <class _Iter, bool = __is_cpp17_forward_iterator<_Iter>::value>
|
2016-01-14 05:54:34 +08:00
|
|
|
struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT((
|
2019-05-30 00:01:36 +08:00
|
|
|
noexcept(++(declval<_Iter&>())) &&
|
|
|
|
is_nothrow_assignable<_Iter&, _Iter>::value &&
|
|
|
|
noexcept(declval<_Iter>() == declval<_Iter>()) &&
|
2016-01-14 05:54:34 +08:00
|
|
|
noexcept(*declval<_Iter>())
|
|
|
|
)) {};
|
|
|
|
|
2019-05-30 00:01:36 +08:00
|
|
|
template <class _Iter>
|
2016-01-14 05:54:34 +08:00
|
|
|
struct __libcpp_string_gets_noexcept_iterator_impl<_Iter, false> : public false_type {};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_string_gets_noexcept_iterator
|
|
|
|
: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
|
|
|
|
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _CharT, class _Traits, class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
struct __can_be_converted_to_string_view : public _BoolConstant<
|
|
|
|
is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
|
|
|
|
!is_convertible<const _Tp&, const _CharT*>::value
|
|
|
|
> {};
|
2016-09-25 06:45:42 +08:00
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
|
|
|
template <class _CharT, size_t = sizeof(_CharT)>
|
|
|
|
struct __padding
|
|
|
|
{
|
|
|
|
unsigned char __xx[sizeof(_CharT)-1];
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _CharT>
|
|
|
|
struct __padding<_CharT, 1>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS basic_string
|
2010-05-12 03:42:16 +08:00
|
|
|
: private __basic_string_common<true>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef basic_string __self;
|
2016-07-21 13:31:24 +08:00
|
|
|
typedef basic_string_view<_CharT, _Traits> __self_view;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef _Traits traits_type;
|
2017-03-16 02:41:11 +08:00
|
|
|
typedef _CharT value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef _Allocator allocator_type;
|
2010-11-18 01:55:08 +08:00
|
|
|
typedef allocator_traits<allocator_type> __alloc_traits;
|
|
|
|
typedef typename __alloc_traits::size_type size_type;
|
|
|
|
typedef typename __alloc_traits::difference_type difference_type;
|
2011-06-04 02:40:47 +08:00
|
|
|
typedef value_type& reference;
|
|
|
|
typedef const value_type& const_reference;
|
2010-11-18 01:55:08 +08:00
|
|
|
typedef typename __alloc_traits::pointer pointer;
|
|
|
|
typedef typename __alloc_traits::const_pointer const_pointer;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-03-21 08:36:05 +08:00
|
|
|
static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array");
|
|
|
|
static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout");
|
|
|
|
static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial");
|
|
|
|
static_assert(( is_same<_CharT, typename traits_type::char_type>::value),
|
2013-08-24 01:37:05 +08:00
|
|
|
"traits_type::char_type must be the same type as CharT");
|
2018-03-21 08:36:05 +08:00
|
|
|
static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
|
2013-08-24 01:37:05 +08:00
|
|
|
"Allocator::value_type must be same type as value_type");
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef __wrap_iter<pointer> iterator;
|
|
|
|
typedef __wrap_iter<const_pointer> const_iterator;
|
2011-07-01 05:18:19 +08:00
|
|
|
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
|
|
|
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
private:
|
2013-05-01 05:44:48 +08:00
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
|
|
|
struct __long
|
|
|
|
{
|
|
|
|
pointer __data_;
|
|
|
|
size_type __size_;
|
|
|
|
size_type __cap_;
|
|
|
|
};
|
|
|
|
|
2017-10-17 21:16:01 +08:00
|
|
|
#ifdef _LIBCPP_BIG_ENDIAN
|
2017-07-12 09:45:13 +08:00
|
|
|
static const size_type __short_mask = 0x01;
|
|
|
|
static const size_type __long_mask = 0x1ul;
|
2013-05-01 05:44:48 +08:00
|
|
|
#else // _LIBCPP_BIG_ENDIAN
|
2017-07-12 09:45:13 +08:00
|
|
|
static const size_type __short_mask = 0x80;
|
|
|
|
static const size_type __long_mask = ~(size_type(~0) >> 1);
|
2013-05-01 05:44:48 +08:00
|
|
|
#endif // _LIBCPP_BIG_ENDIAN
|
|
|
|
|
|
|
|
enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
|
|
|
|
(sizeof(__long) - 1)/sizeof(value_type) : 2};
|
|
|
|
|
|
|
|
struct __short
|
|
|
|
{
|
|
|
|
value_type __data_[__min_cap];
|
|
|
|
struct
|
|
|
|
: __padding<value_type>
|
|
|
|
{
|
|
|
|
unsigned char __size_;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
struct __long
|
|
|
|
{
|
|
|
|
size_type __cap_;
|
|
|
|
size_type __size_;
|
|
|
|
pointer __data_;
|
|
|
|
};
|
|
|
|
|
2017-10-17 21:16:01 +08:00
|
|
|
#ifdef _LIBCPP_BIG_ENDIAN
|
2017-07-12 09:45:13 +08:00
|
|
|
static const size_type __short_mask = 0x80;
|
|
|
|
static const size_type __long_mask = ~(size_type(~0) >> 1);
|
2010-08-22 08:02:43 +08:00
|
|
|
#else // _LIBCPP_BIG_ENDIAN
|
2017-07-12 09:45:13 +08:00
|
|
|
static const size_type __short_mask = 0x01;
|
|
|
|
static const size_type __long_mask = 0x1ul;
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_BIG_ENDIAN
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
|
|
|
|
(sizeof(__long) - 1)/sizeof(value_type) : 2};
|
|
|
|
|
|
|
|
struct __short
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
unsigned char __size_;
|
2012-10-31 03:06:59 +08:00
|
|
|
value_type __lx;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
value_type __data_[__min_cap];
|
|
|
|
};
|
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
2013-08-24 01:37:05 +08:00
|
|
|
union __ulx{__long __lx; __short __lxx;};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-08-24 01:37:05 +08:00
|
|
|
enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
struct __raw
|
|
|
|
{
|
|
|
|
size_type __words[__n_words];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct __rep
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
__long __l;
|
|
|
|
__short __s;
|
|
|
|
__raw __r;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
__compressed_pair<__rep, allocator_type> __r_;
|
|
|
|
|
|
|
|
public:
|
2020-01-17 04:00:34 +08:00
|
|
|
_LIBCPP_FUNC_VIS
|
2010-05-12 03:42:16 +08:00
|
|
|
static const size_type npos = -1;
|
|
|
|
|
2011-06-04 02:40:47 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_string()
|
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
|
2015-06-04 03:56:43 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)
|
|
|
|
#if _LIBCPP_STD_VER <= 14
|
|
|
|
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
|
|
|
|
#else
|
|
|
|
_NOEXCEPT;
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(const basic_string& __str);
|
|
|
|
basic_string(const basic_string& __str, const allocator_type& __a);
|
2015-06-04 03:56:43 +08:00
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-01-26 08:06:59 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string(basic_string&& __str)
|
2015-06-04 03:56:43 +08:00
|
|
|
#if _LIBCPP_STD_VER <= 14
|
2011-06-04 02:40:47 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
|
2015-06-04 03:56:43 +08:00
|
|
|
#else
|
|
|
|
_NOEXCEPT;
|
|
|
|
#endif
|
|
|
|
|
2011-01-26 08:06:59 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(basic_string&& __str, const allocator_type& __a);
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2020-01-16 06:29:55 +08:00
|
|
|
template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
|
2018-07-17 13:48:48 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
|
2018-07-17 13:48:48 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
|
|
|
|
__init(__s, traits_type::length(__s));
|
|
|
|
# if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
# endif
|
|
|
|
}
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2020-01-16 06:29:55 +08:00
|
|
|
template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
|
2018-07-03 02:41:15 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string(const _CharT* __s, const _Allocator& __a);
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string(const _CharT* __s, size_type __n);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string(size_type __n, _CharT __c);
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2020-01-16 06:29:55 +08:00
|
|
|
template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
|
2018-07-03 02:41:15 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string(size_type __n, _CharT __c, const _Allocator& __a);
|
|
|
|
|
2016-04-08 02:13:41 +08:00
|
|
|
basic_string(const basic_string& __str, size_type __pos, size_type __n,
|
2017-02-17 09:17:10 +08:00
|
|
|
const _Allocator& __a = _Allocator());
|
2016-04-08 02:13:41 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string(const basic_string& __str, size_type __pos,
|
2017-02-17 09:17:10 +08:00
|
|
|
const _Allocator& __a = _Allocator());
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2020-01-16 05:57:08 +08:00
|
|
|
template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string(const _Tp& __t, size_type __pos, size_type __n,
|
2020-01-16 05:57:08 +08:00
|
|
|
const allocator_type& __a = allocator_type());
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2020-01-16 05:57:08 +08:00
|
|
|
template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
|
|
|
|
!__is_same_uncvref<_Tp, basic_string>::value> >
|
2018-07-03 02:41:15 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
|
|
|
explicit basic_string(const _Tp& __t);
|
|
|
|
|
2020-01-16 05:57:08 +08:00
|
|
|
template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
|
2018-07-03 02:41:15 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
|
|
|
explicit basic_string(const _Tp& __t, const allocator_type& __a);
|
|
|
|
|
2020-01-16 06:29:55 +08:00
|
|
|
template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> >
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(_InputIterator __first, _InputIterator __last);
|
2020-01-16 06:29:55 +08:00
|
|
|
template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> >
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string(initializer_list<_CharT> __il);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-10-31 11:42:50 +08:00
|
|
|
inline ~basic_string();
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
|
|
|
|
|
2010-11-18 01:55:08 +08:00
|
|
|
basic_string& operator=(const basic_string& __str);
|
2017-01-24 05:24:58 +08:00
|
|
|
|
2020-01-16 05:57:08 +08:00
|
|
|
template <class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string& operator=(const _Tp& __t)
|
|
|
|
{__self_view __sv = __t; return assign(__sv);}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string& operator=(basic_string&& __str)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
|
2017-04-19 08:28:44 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif
|
2013-06-29 00:59:19 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& operator=(value_type __c);
|
|
|
|
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator begin() _NOEXCEPT
|
|
|
|
{return iterator(this, __get_pointer());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator begin() const _NOEXCEPT
|
|
|
|
{return const_iterator(this, __get_pointer());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator end() _NOEXCEPT
|
|
|
|
{return iterator(this, __get_pointer() + size());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator end() const _NOEXCEPT
|
|
|
|
{return const_iterator(this, __get_pointer() + size());}
|
|
|
|
#else
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator begin() _NOEXCEPT
|
|
|
|
{return iterator(__get_pointer());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator begin() const _NOEXCEPT
|
2013-06-29 00:59:19 +08:00
|
|
|
{return const_iterator(__get_pointer());}
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator end() _NOEXCEPT
|
|
|
|
{return iterator(__get_pointer() + size());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator end() const _NOEXCEPT
|
2013-06-29 00:59:19 +08:00
|
|
|
{return const_iterator(__get_pointer() + size());}
|
2013-08-24 01:37:05 +08:00
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
reverse_iterator rbegin() _NOEXCEPT
|
|
|
|
{return reverse_iterator(end());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_reverse_iterator rbegin() const _NOEXCEPT
|
|
|
|
{return const_reverse_iterator(end());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
reverse_iterator rend() _NOEXCEPT
|
|
|
|
{return reverse_iterator(begin());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_reverse_iterator rend() const _NOEXCEPT
|
|
|
|
{return const_reverse_iterator(begin());}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator cbegin() const _NOEXCEPT
|
|
|
|
{return begin();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator cend() const _NOEXCEPT
|
|
|
|
{return end();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_reverse_iterator crbegin() const _NOEXCEPT
|
|
|
|
{return rbegin();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_reverse_iterator crend() const _NOEXCEPT
|
|
|
|
{return rend();}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __is_long() ? __get_long_size() : __get_short_size();}
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
|
2015-08-28 15:02:42 +08:00
|
|
|
{return (__is_long() ? __get_long_cap()
|
|
|
|
: static_cast<size_type>(__min_cap)) - 1;}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void resize(size_type __n, value_type __c);
|
|
|
|
_LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
|
|
|
|
|
2018-11-29 02:18:34 +08:00
|
|
|
void reserve(size_type __res_arg);
|
2018-11-27 04:15:38 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n);
|
|
|
|
|
2018-11-29 02:18:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void reserve() _NOEXCEPT {reserve(0);}
|
2010-09-24 01:31:07 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 02:40:47 +08:00
|
|
|
void shrink_to_fit() _NOEXCEPT {reserve();}
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
void clear() _NOEXCEPT;
|
2017-11-16 04:02:27 +08:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool empty() const _NOEXCEPT {return size() == 0;}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
const_reference at(size_type __n) const;
|
|
|
|
reference at(size_type __n);
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
|
|
|
|
&& !__is_same_uncvref<_Tp, basic_string >::value,
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
operator+=(const _Tp& __t) {__self_view __sv = __t; return append(__sv);}
|
2016-07-21 13:31:24 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);}
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& append(const basic_string& __str);
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
|
|
|
|
&& !__is_same_uncvref<_Tp, basic_string>::value,
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2016-10-04 07:40:48 +08:00
|
|
|
template <class _Tp>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
|
|
|
|
&& !__is_same_uncvref<_Tp, basic_string>::value,
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
append(const _Tp& __t, size_type __pos, size_type __n=npos);
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& append(const value_type* __s, size_type __n);
|
|
|
|
basic_string& append(const value_type* __s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& append(size_type __n, value_type __c);
|
2018-11-27 04:15:38 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __append_default_init(size_type __n);
|
|
|
|
|
2016-10-31 10:46:25 +08:00
|
|
|
template <class _ForwardIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
|
|
|
basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _InputIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-10-31 10:46:25 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
append(_InputIterator __first, _InputIterator __last) {
|
|
|
|
const basic_string __temp (__first, __last, __alloc());
|
|
|
|
append(__temp.data(), __temp.size());
|
|
|
|
return *this;
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _ForwardIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-10-31 10:46:25 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
append(_ForwardIterator __first, _ForwardIterator __last) {
|
|
|
|
return __append_forward_unsafe(__first, __last);
|
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 01:31:07 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void push_back(value_type __c);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void pop_back();
|
2019-03-19 11:30:07 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY reference front() _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference back() _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2016-03-10 02:08:29 +08:00
|
|
|
basic_string& assign(const basic_string& __str) { return *this = __str; }
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-06-01 10:29:37 +08:00
|
|
|
basic_string& assign(basic_string&& __str)
|
2015-10-06 00:17:34 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
|
2017-06-01 10:29:37 +08:00
|
|
|
{*this = _VSTD::move(__str); return *this;}
|
2011-05-30 03:57:12 +08:00
|
|
|
#endif
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
|
2016-10-04 07:40:48 +08:00
|
|
|
template <class _Tp>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
|
|
|
|
&& !__is_same_uncvref<_Tp, basic_string>::value,
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2017-06-01 10:29:37 +08:00
|
|
|
assign(const _Tp & __t, size_type __pos, size_type __n=npos);
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& assign(const value_type* __s, size_type __n);
|
|
|
|
basic_string& assign(const value_type* __s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& assign(size_type __n, value_type __c);
|
|
|
|
template<class _InputIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
assign(_InputIterator __first, _InputIterator __last);
|
|
|
|
template<class _ForwardIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
assign(_ForwardIterator __first, _ForwardIterator __last);
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 01:31:07 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& insert(size_type __pos1, const basic_string& __str);
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
insert(size_type __pos1, const _Tp& __t)
|
|
|
|
{ __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
|
|
|
|
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
|
|
|
|
basic_string& insert(size_type __pos, const value_type* __s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& insert(size_type __pos, size_type __n, value_type __c);
|
|
|
|
iterator insert(const_iterator __pos, value_type __c);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __pos, size_type __n, value_type __c);
|
|
|
|
template<class _InputIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
|
|
|
|
template<class _ForwardIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 01:31:07 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __pos, initializer_list<value_type> __il)
|
|
|
|
{return insert(__pos, __il.begin(), __il.end());}
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
basic_string& erase(size_type __pos = 0, size_type __n = npos);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator erase(const_iterator __pos);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator erase(const_iterator __first, const_iterator __last);
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
|
2014-03-05 03:17:19 +08:00
|
|
|
basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
|
|
|
|
basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _InputIterator>
|
[libc++] Make _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS export members
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
2017-03-02 11:02:50 +08:00
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_input_iterator<_InputIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-11-18 05:11:40 +08:00
|
|
|
replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 01:31:07 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
|
2010-05-12 03:42:16 +08:00
|
|
|
{return replace(__i1, __i2, __il.begin(), __il.end());}
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string substr(size_type __pos = 0, size_type __n = npos) const;
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 02:40:47 +08:00
|
|
|
void swap(basic_string& __str)
|
2015-07-14 04:04:56 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_NOEXCEPT;
|
2015-07-14 04:04:56 +08:00
|
|
|
#else
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
|
2015-07-14 04:04:56 +08:00
|
|
|
__is_nothrow_swappable<allocator_type>::value);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
const value_type* c_str() const _NOEXCEPT {return data();}
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-11-17 06:13:26 +08:00
|
|
|
const value_type* data() const _NOEXCEPT {return _VSTD::__to_address(__get_pointer());}
|
2017-11-21 04:23:27 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
|
2016-03-08 23:44:30 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* data() _NOEXCEPT {return _VSTD::__to_address(__get_pointer());}
|
2016-03-08 23:44:30 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
find(const _Tp& __t, size_type __pos = 0) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
rfind(const _Tp& __t, size_type __pos = npos) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
find_first_of(const _Tp& __t, size_type __pos = 0) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
find_last_of(const _Tp& __t, size_type __pos = npos) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
find_first_not_of(const _Tp &__t, size_type __pos = 0) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
find_last_not_of(const _Tp& __t, size_type __pos = npos) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-05-30 03:57:12 +08:00
|
|
|
int compare(const basic_string& __str) const _NOEXCEPT;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
int
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
compare(const _Tp &__t) const;
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
int
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
|
2014-03-05 03:17:19 +08:00
|
|
|
int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
2016-10-14 13:29:46 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
|
2016-09-25 06:45:42 +08:00
|
|
|
int
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
|
2013-06-29 00:59:19 +08:00
|
|
|
int compare(const value_type* __s) const _NOEXCEPT;
|
|
|
|
int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
|
|
|
|
int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-12-05 04:11:38 +08:00
|
|
|
#if _LIBCPP_STD_VER > 17
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool starts_with(__self_view __sv) const _NOEXCEPT
|
|
|
|
{ return __self_view(data(), size()).starts_with(__sv); }
|
|
|
|
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool starts_with(value_type __c) const _NOEXCEPT
|
|
|
|
{ return !empty() && _Traits::eq(front(), __c); }
|
|
|
|
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool starts_with(const value_type* __s) const _NOEXCEPT
|
|
|
|
{ return starts_with(__self_view(__s)); }
|
|
|
|
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool ends_with(__self_view __sv) const _NOEXCEPT
|
|
|
|
{ return __self_view(data(), size()).ends_with( __sv); }
|
|
|
|
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool ends_with(value_type __c) const _NOEXCEPT
|
|
|
|
{ return !empty() && _Traits::eq(back(), __c); }
|
|
|
|
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool ends_with(const value_type* __s) const _NOEXCEPT
|
|
|
|
{ return ends_with(__self_view(__s)); }
|
|
|
|
#endif
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY bool __invariants() const;
|
2013-04-23 07:55:13 +08:00
|
|
|
|
2018-05-30 01:04:37 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT;
|
2019-05-21 05:56:51 +08:00
|
|
|
|
2013-04-23 07:55:13 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool __is_long() const _NOEXCEPT
|
|
|
|
{return bool(__r_.first().__s.__size_ & __short_mask);}
|
|
|
|
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
|
|
|
|
bool __dereferenceable(const const_iterator* __i) const;
|
|
|
|
bool __decrementable(const const_iterator* __i) const;
|
|
|
|
bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
|
|
|
|
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
|
|
|
|
|
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
private:
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
allocator_type& __alloc() _NOEXCEPT
|
|
|
|
{return __r_.second();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const allocator_type& __alloc() const _NOEXCEPT
|
|
|
|
{return __r_.second();}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __set_short_size(size_type __s) _NOEXCEPT
|
2017-10-17 21:16:01 +08:00
|
|
|
# ifdef _LIBCPP_BIG_ENDIAN
|
2013-05-01 05:44:48 +08:00
|
|
|
{__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
|
|
|
|
# else
|
2010-05-12 03:42:16 +08:00
|
|
|
{__r_.first().__s.__size_ = (unsigned char)(__s);}
|
2013-05-01 05:44:48 +08:00
|
|
|
# endif
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __get_short_size() const _NOEXCEPT
|
2017-10-17 21:16:01 +08:00
|
|
|
# ifdef _LIBCPP_BIG_ENDIAN
|
2013-05-01 05:44:48 +08:00
|
|
|
{return __r_.first().__s.__size_ >> 1;}
|
|
|
|
# else
|
|
|
|
{return __r_.first().__s.__size_;}
|
|
|
|
# endif
|
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __set_short_size(size_type __s) _NOEXCEPT
|
2017-10-17 21:16:01 +08:00
|
|
|
# ifdef _LIBCPP_BIG_ENDIAN
|
2013-05-01 05:44:48 +08:00
|
|
|
{__r_.first().__s.__size_ = (unsigned char)(__s);}
|
|
|
|
# else
|
2010-05-12 03:42:16 +08:00
|
|
|
{__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
|
2013-05-01 05:44:48 +08:00
|
|
|
# endif
|
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __get_short_size() const _NOEXCEPT
|
2017-10-17 21:16:01 +08:00
|
|
|
# ifdef _LIBCPP_BIG_ENDIAN
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __r_.first().__s.__size_;}
|
2013-05-01 05:44:48 +08:00
|
|
|
# else
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __r_.first().__s.__size_ >> 1;}
|
2013-05-01 05:44:48 +08:00
|
|
|
# endif
|
|
|
|
|
2015-10-14 07:48:28 +08:00
|
|
|
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
2013-05-01 05:44:48 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __set_long_size(size_type __s) _NOEXCEPT
|
|
|
|
{__r_.first().__l.__size_ = __s;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __get_long_size() const _NOEXCEPT
|
|
|
|
{return __r_.first().__l.__size_;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __set_size(size_type __s) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
|
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __set_long_cap(size_type __s) _NOEXCEPT
|
|
|
|
{__r_.first().__l.__cap_ = __long_mask | __s;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __get_long_cap() const _NOEXCEPT
|
2011-12-02 04:21:04 +08:00
|
|
|
{return __r_.first().__l.__cap_ & size_type(~__long_mask);}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __set_long_pointer(pointer __p) _NOEXCEPT
|
|
|
|
{__r_.first().__l.__data_ = __p;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pointer __get_long_pointer() _NOEXCEPT
|
|
|
|
{return __r_.first().__l.__data_;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_pointer __get_long_pointer() const _NOEXCEPT
|
|
|
|
{return __r_.first().__l.__data_;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pointer __get_short_pointer() _NOEXCEPT
|
2013-06-29 00:59:19 +08:00
|
|
|
{return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_pointer __get_short_pointer() const _NOEXCEPT
|
2013-06-29 00:59:19 +08:00
|
|
|
{return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pointer __get_pointer() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __is_long() ? __get_long_pointer() : __get_short_pointer();}
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_pointer __get_pointer() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __is_long() ? __get_long_pointer() : __get_short_pointer();}
|
|
|
|
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __zero() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_type (&__a)[__n_words] = __r_.first().__r.__words;
|
|
|
|
for (unsigned __i = 0; __i < __n_words; ++__i)
|
|
|
|
__a[__i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <size_type __a> static
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-08-15 02:00:20 +08:00
|
|
|
size_type __align_it(size_type __s) _NOEXCEPT
|
2015-08-28 15:02:42 +08:00
|
|
|
{return (__s + (__a-1)) & ~(__a-1);}
|
2010-05-12 03:42:16 +08:00
|
|
|
enum {__alignment = 16};
|
2011-05-30 03:57:12 +08:00
|
|
|
static _LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __recommend(size_type __s) _NOEXCEPT
|
2018-02-08 05:30:17 +08:00
|
|
|
{
|
|
|
|
if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1;
|
|
|
|
size_type __guess = __align_it<sizeof(value_type) < __alignment ?
|
|
|
|
__alignment/sizeof(value_type) : 1 > (__s+1) - 1;
|
|
|
|
if (__guess == __min_cap) ++__guess;
|
|
|
|
return __guess;
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-04-01 11:20:48 +08:00
|
|
|
inline
|
2013-06-29 00:59:19 +08:00
|
|
|
void __init(const value_type* __s, size_type __sz, size_type __reserve);
|
2017-04-01 11:20:48 +08:00
|
|
|
inline
|
2013-06-29 00:59:19 +08:00
|
|
|
void __init(const value_type* __s, size_type __sz);
|
2017-04-01 11:20:48 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void __init(size_type __n, value_type __c);
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2020-03-05 06:52:46 +08:00
|
|
|
// Slow path for the (inlined) copy constructor for 'long' strings.
|
|
|
|
// Always externally instantiated and not inlined.
|
|
|
|
// Requires that __s is zero terminated.
|
|
|
|
// The main reason for this function to exist is because for unstable, we
|
|
|
|
// want to allow inlining of the copy constructor. However, we don't want
|
|
|
|
// to call the __init() functions as those are marked as inline which may
|
|
|
|
// result in over-aggressive inlining by the compiler, where our aim is
|
|
|
|
// to only inline the fast path code directly in the ctor.
|
|
|
|
void __init_copy_ctor_external(const value_type* __s, size_type __sz);
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _InputIterator>
|
2017-04-01 11:20:48 +08:00
|
|
|
inline
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
__init(_InputIterator __first, _InputIterator __last);
|
|
|
|
|
|
|
|
template <class _ForwardIterator>
|
2017-04-01 11:20:48 +08:00
|
|
|
inline
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
__init(_ForwardIterator __first, _ForwardIterator __last);
|
|
|
|
|
|
|
|
void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
|
2010-08-22 08:02:43 +08:00
|
|
|
size_type __n_copy, size_type __n_del, size_type __n_add = 0);
|
2010-05-12 03:42:16 +08:00
|
|
|
void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
|
|
|
|
size_type __n_copy, size_type __n_del,
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type __n_add, const value_type* __p_new_stuff);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2020-02-27 04:55:49 +08:00
|
|
|
// __assign_no_alias is invoked for assignment operations where we
|
|
|
|
// have proof that the input does not alias the current instance.
|
|
|
|
// For example, operator=(basic_string) performs a 'self' check.
|
|
|
|
template <bool __is_short>
|
2020-04-11 06:36:31 +08:00
|
|
|
basic_string& __assign_no_alias(const value_type* __s, size_type __n);
|
2020-02-27 04:55:49 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __erase_to_end(size_type __pos);
|
|
|
|
|
Inline basic_string::erase for fastpath where __n == npos
Summary:
This change checks for the case where people want to erase a string to the end, i.e., __n == npos, and inlines the call if so.
This also demonstrates keeping the ABI intact for V1, but inlining the erase() method for unstable.
Reviewers: EricWF, mclow.lists, ldionne
Reviewed By: EricWF, ldionne
Subscribers: smeenai, dexonsmith, christof, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D73743
2020-02-27 02:25:43 +08:00
|
|
|
// __erase_external_with_move is invoked for erase() invocations where
|
|
|
|
// `n ~= npos`, likely requiring memory moves on the string data.
|
|
|
|
void __erase_external_with_move(size_type __pos, size_type __n);
|
|
|
|
|
2010-11-18 01:55:08 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __copy_assign_alloc(const basic_string& __str)
|
|
|
|
{__copy_assign_alloc(__str, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_copy_assignment::value>());}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __copy_assign_alloc(const basic_string& __str, true_type)
|
|
|
|
{
|
2017-01-31 11:40:52 +08:00
|
|
|
if (__alloc() == __str.__alloc())
|
|
|
|
__alloc() = __str.__alloc();
|
|
|
|
else
|
2010-11-18 01:55:08 +08:00
|
|
|
{
|
2017-01-31 11:40:52 +08:00
|
|
|
if (!__str.__is_long())
|
|
|
|
{
|
2018-03-09 05:15:26 +08:00
|
|
|
__clear_and_shrink();
|
2017-01-31 11:40:52 +08:00
|
|
|
__alloc() = __str.__alloc();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type __a = __str.__alloc();
|
|
|
|
pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap());
|
2018-03-09 05:15:26 +08:00
|
|
|
__clear_and_shrink();
|
2017-01-31 11:40:52 +08:00
|
|
|
__alloc() = _VSTD::move(__a);
|
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__str.__get_long_cap());
|
|
|
|
__set_long_size(__str.size());
|
|
|
|
}
|
2010-11-18 01:55:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-02 04:21:04 +08:00
|
|
|
void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
|
2010-11-18 01:55:08 +08:00
|
|
|
{}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2015-08-19 02:57:00 +08:00
|
|
|
void __move_assign(basic_string& __str, false_type)
|
|
|
|
_NOEXCEPT_(__alloc_traits::is_always_equal::value);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 02:40:47 +08:00
|
|
|
void __move_assign(basic_string& __str, true_type)
|
2015-08-19 02:57:00 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
_NOEXCEPT;
|
|
|
|
#else
|
2011-06-04 02:40:47 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
|
2015-08-19 02:57:00 +08:00
|
|
|
#endif
|
2010-11-18 01:55:08 +08:00
|
|
|
#endif
|
|
|
|
|
2011-08-18 04:36:18 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void
|
2011-09-03 04:42:31 +08:00
|
|
|
__move_assign_alloc(basic_string& __str)
|
2011-08-18 04:36:18 +08:00
|
|
|
_NOEXCEPT_(
|
|
|
|
!__alloc_traits::propagate_on_container_move_assignment::value ||
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value)
|
|
|
|
{__move_assign_alloc(__str, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_move_assignment::value>());}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-09-03 04:42:31 +08:00
|
|
|
void __move_assign_alloc(basic_string& __c, true_type)
|
2011-08-18 04:36:18 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
|
|
|
{
|
|
|
|
__alloc() = _VSTD::move(__c.__alloc());
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-02 04:21:04 +08:00
|
|
|
void __move_assign_alloc(basic_string&, false_type)
|
2011-08-18 04:36:18 +08:00
|
|
|
_NOEXCEPT
|
|
|
|
{}
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
|
|
|
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
friend basic_string operator+<>(const basic_string&, const basic_string&);
|
|
|
|
friend basic_string operator+<>(const value_type*, const basic_string&);
|
|
|
|
friend basic_string operator+<>(value_type, const basic_string&);
|
|
|
|
friend basic_string operator+<>(const basic_string&, const value_type*);
|
|
|
|
friend basic_string operator+<>(const basic_string&, value_type);
|
|
|
|
};
|
|
|
|
|
2020-03-05 02:54:04 +08:00
|
|
|
// These declarations must appear before any functions are implicitly used
|
|
|
|
// so that they have the correct visibility specifier.
|
|
|
|
#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
|
|
|
|
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char)
|
|
|
|
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
|
|
|
|
#else
|
|
|
|
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char)
|
|
|
|
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2018-02-08 14:34:03 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
|
|
|
template<class _InputIterator,
|
|
|
|
class _CharT = typename iterator_traits<_InputIterator>::value_type,
|
|
|
|
class _Allocator = allocator<_CharT>,
|
2020-01-16 05:57:08 +08:00
|
|
|
class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>,
|
|
|
|
class = _EnableIf<__is_allocator<_Allocator>::value>
|
2018-02-08 14:34:03 +08:00
|
|
|
>
|
|
|
|
basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
|
|
|
|
-> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
|
2018-07-03 02:41:15 +08:00
|
|
|
|
|
|
|
template<class _CharT,
|
|
|
|
class _Traits,
|
|
|
|
class _Allocator = allocator<_CharT>,
|
2020-01-16 05:57:08 +08:00
|
|
|
class = _EnableIf<__is_allocator<_Allocator>::value>
|
2018-07-03 02:41:15 +08:00
|
|
|
>
|
|
|
|
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>,
|
2020-01-16 05:57:08 +08:00
|
|
|
class = _EnableIf<__is_allocator<_Allocator>::value>,
|
2018-07-03 02:41:15 +08:00
|
|
|
class _Sz = typename allocator_traits<_Allocator>::size_type
|
|
|
|
>
|
|
|
|
basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
|
|
|
|
-> basic_string<_CharT, _Traits, _Allocator>;
|
2018-02-08 14:34:03 +08:00
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__invalidate_all(this);
|
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
2011-12-02 04:21:04 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-12-02 04:21:04 +08:00
|
|
|
__pos
|
|
|
|
#endif
|
|
|
|
)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__c_node* __c = __get_db()->__find_c_and_lock(this);
|
|
|
|
if (__c)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
const_pointer __new_last = __get_pointer() + __pos;
|
|
|
|
for (__i_node** __p = __c->end_; __p != __c->beg_; )
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
--__p;
|
|
|
|
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
|
|
|
if (__i->base() > __new_last)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
(*__p)->__c_ = nullptr;
|
|
|
|
if (--__c->end_ != __p)
|
|
|
|
memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
2013-08-24 01:37:05 +08:00
|
|
|
__get_db()->unlock();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2013-08-24 01:37:05 +08:00
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string()
|
2015-06-04 10:05:41 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __default_init_tag())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
__zero();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
|
2015-07-19 04:40:46 +08:00
|
|
|
#if _LIBCPP_STD_VER <= 14
|
|
|
|
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
|
|
|
|
#else
|
|
|
|
_NOEXCEPT
|
|
|
|
#endif
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
__zero();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
[libc++] Add _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY to support GCC ABI compatibility
Summary:
GCC and Clang handle visibility attributes on the out-of-line definition of externally instantiated templates differently. For example in the reproducer below Clang will emit both 'foo' and 'bar' with default visibility while GCC only emits a non-hidden 'foo'.
```
// RUN: g++ -std=c++11 -shared -O3 test.cpp && sym_extract.py a.out
// RUN: clang++ -std=c++11 -shared -O3 test.cpp && sym_extract.py a.out
#define INLINE_VISIBILITY __attribute__((visibility("hidden"), always_inline))
template <class T>
struct Foo {
void foo();
void bar();
};
template <class T>
void Foo<T>::foo() {}
template <class T>
inline INLINE_VISIBILITY
void Foo<T>::bar() {}
template struct Foo<int>;
```
This difference creates ABI incompatibilities between Clang and GCC built dylibs. Specifically GCC built dylibs lack definitions for various member functions of `basic_string`, `basic_istream`, `basic_ostream`, `basic_iostream`, and `basic_streambuf` (All of these types are externally instantiated).
Surprisingly these missing symbols don't cause many problems because the functions are marked `always_inline` therefore the dylib definition is rarely needed. However when an out-of-line definition is required then GCC built dylibs will fail to link. For example [GCC built dylibs cannot build Clang](http://stackoverflow.com/questions/39454262/clang-build-errors).
This patch works around this issue by adding `_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY` which is used to mark externally instantiated member functions as always inline. When building the library `_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY` sets the symbol's visibility to "default" instead of "hidden", otherwise it acts exactly the same as `_LIBCPP_INLINE_VISIBILITY`.
After applying this patch GCC dylibs now contain:
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE7sungetcEv`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5gbumpEi`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE7sungetcEv`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE9sputbackcEc`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE3getERNS_15basic_streambufIwS2_EE`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEElsEPFRNS_9basic_iosIwS2_EES6_E`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE4setpEPcS4_`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEEC1EPNS_15basic_streambufIwS2_EE`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE6snextcEv`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE4swapERS3_`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE4swapERS3_`
* `_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsEPFRNS_8ios_baseES5_E`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE9pubsetbufEPcl`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE10pubseekoffExNS_8ios_base7seekdirEj`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPFRNS_9basic_iosIwS2_EES6_E`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5pbumpEi`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5seekpENS_4fposI11__mbstate_tEE`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE7getlineEPcl`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sgetcEv`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getERNS_15basic_streambufIcS2_EE`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRNS_8ios_baseES5_E`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE8in_availEv`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPFRNS_8ios_baseES5_E`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE6sbumpcEv`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRNS_9basic_iosIcS2_EES6_E`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getERc`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE6snextcEv`
* `_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initEmw`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE7getlineEPwl`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5tellpEv`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE3getERw`
* `_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE7pubsyncEv`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getEPcl`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsEPFRNS_9basic_iosIcS2_EES6_E`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE7pubsyncEv`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputcEc`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE5seekpExNS_8ios_base7seekdirE`
* `_ZNKSt3__115basic_streambufIcNS_11char_traitsIcEEE6getlocEv`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5gbumpEi`
* `_ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEE4swapERS3_`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE5seekpENS_4fposI11__mbstate_tEE`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE5tellpEv`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEElsEPFRS3_S4_E`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE3getEPwl`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEEC2EPNS_15basic_streambufIwS2_EE`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE4setgEPcS4_S4_`
* `_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initEPKwmm`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE4setgEPwS4_S4_`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEEC1EPNS_15basic_streambufIwS2_EE`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE8pubimbueERKNS_6localeE`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE4swapERS3_`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEEC2EPNS_15basic_streambufIwS2_EE`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE10pubseekposENS_4fposI11__mbstate_tEEj`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5pbumpEi`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sgetcEv`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE4swapERS3_`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE10pubseekposENS_4fposI11__mbstate_tEEj`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputnEPKcl`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5seekpExNS_8ios_base7seekdirE`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sgetnEPwl`
* `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEElsEPFRNS_8ios_baseES5_E`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE4setpEPwS4_`
* `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sgetnEPcl`
* `_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv`
* `_ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE8pubimbueERKNS_6localeE`
* `_ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE8in_availEv`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE`
* `_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcmm`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE6sbumpcEv`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE10pubseekoffExNS_8ios_base7seekdirEj`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE`
* `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPFRS3_S4_E`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE9sputbackcEw`
* `_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initEPKwm`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sputnEPKwl`
* `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsEPFRS3_S4_E`
* `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE9pubsetbufEPwl`
* `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sputcEw`
This patch has no effect on Clang based builds.
Reviewers: mclow.lists, eugenis, danalbert, jroelofs, EricWF
Subscribers: beanz, cfe-commits, mgorny
Differential Revision: https://reviews.llvm.org/D24600
llvm-svn: 281681
2016-09-16 08:00:48 +08:00
|
|
|
void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
|
|
|
|
size_type __sz,
|
|
|
|
size_type __reserve)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__reserve > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
pointer __p;
|
|
|
|
if (__reserve < __min_cap)
|
|
|
|
{
|
|
|
|
__set_short_size(__sz);
|
|
|
|
__p = __get_short_pointer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __cap = __recommend(__reserve);
|
2010-11-18 01:55:08 +08:00
|
|
|
__p = __alloc_traits::allocate(__alloc(), __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap+1);
|
|
|
|
__set_long_size(__sz);
|
|
|
|
}
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p), __s, __sz);
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__sz > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
pointer __p;
|
|
|
|
if (__sz < __min_cap)
|
|
|
|
{
|
|
|
|
__set_short_size(__sz);
|
|
|
|
__p = __get_short_pointer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __cap = __recommend(__sz);
|
2010-11-18 01:55:08 +08:00
|
|
|
__p = __alloc_traits::allocate(__alloc(), __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap+1);
|
|
|
|
__set_long_size(__sz);
|
|
|
|
}
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p), __s, __sz);
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class>
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
__init(__s, traits_type::length(__s));
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __default_init_tag())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
__init(__s, __n);
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
__init(__s, __n);
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (!__str.__is_long())
|
|
|
|
__r_.first().__r = __str.__r_.first().__r;
|
|
|
|
else
|
2020-03-05 06:52:46 +08:00
|
|
|
__init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()),
|
|
|
|
__str.__get_long_size());
|
|
|
|
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(
|
|
|
|
const basic_string& __str, const allocator_type& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (!__str.__is_long())
|
|
|
|
__r_.first().__r = __str.__r_.first().__r;
|
|
|
|
else
|
2020-03-05 06:52:46 +08:00
|
|
|
__init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()),
|
|
|
|
__str.__get_long_size());
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2020-03-05 06:52:46 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
|
|
|
|
const value_type* __s, size_type __sz) {
|
|
|
|
pointer __p;
|
|
|
|
if (__sz < __min_cap) {
|
|
|
|
__p = __get_short_pointer();
|
|
|
|
__set_short_size(__sz);
|
|
|
|
} else {
|
|
|
|
if (__sz > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
size_t __cap = __recommend(__sz);
|
|
|
|
__p = __alloc_traits::allocate(__alloc(), __cap + 1);
|
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap + 1);
|
|
|
|
__set_long_size(__sz);
|
|
|
|
}
|
|
|
|
traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1);
|
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
|
2015-06-04 03:56:43 +08:00
|
|
|
#if _LIBCPP_STD_VER <= 14
|
2011-06-04 02:40:47 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
2015-06-04 03:56:43 +08:00
|
|
|
#else
|
|
|
|
_NOEXCEPT
|
|
|
|
#endif
|
2011-07-01 05:18:19 +08:00
|
|
|
: __r_(_VSTD::move(__str.__r_))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__str.__zero();
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
if (__is_long())
|
|
|
|
__get_db()->swap(this, &__str);
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-07-17 23:32:20 +08:00
|
|
|
if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
|
2019-11-17 06:13:26 +08:00
|
|
|
__init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
|
2014-07-17 23:32:20 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
__r_.first().__r = __str.__r_.first().__r;
|
|
|
|
__str.__zero();
|
|
|
|
}
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
if (__is_long())
|
|
|
|
__get_db()->swap(this, &__str);
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
|
|
|
|
{
|
|
|
|
if (__n > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
pointer __p;
|
|
|
|
if (__n < __min_cap)
|
|
|
|
{
|
|
|
|
__set_short_size(__n);
|
|
|
|
__p = __get_short_pointer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __cap = __recommend(__n);
|
2010-11-18 01:55:08 +08:00
|
|
|
__p = __alloc_traits::allocate(__alloc(), __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap+1);
|
|
|
|
__set_long_size(__n);
|
|
|
|
}
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::assign(_VSTD::__to_address(__p), __n, __c);
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::assign(__p[__n], value_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __default_init_tag())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__init(__n, __c);
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class>
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__init(__n, __c);
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
|
|
|
|
size_type __pos, size_type __n,
|
|
|
|
const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_type __str_sz = __str.size();
|
|
|
|
if (__pos > __str_sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
__init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-04-08 02:13:41 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2016-04-08 02:13:41 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
|
2017-02-17 09:17:10 +08:00
|
|
|
const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2016-04-08 02:13:41 +08:00
|
|
|
{
|
|
|
|
size_type __str_sz = __str.size();
|
|
|
|
if (__pos > __str_sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
__init(__str.data() + __pos, __str_sz - __pos);
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-15 02:22:19 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp, class>
|
2016-11-15 02:22:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(
|
2018-07-03 02:41:15 +08:00
|
|
|
const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2016-11-15 02:22:19 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv0 = __t;
|
|
|
|
__self_view __sv = __sv0.substr(__pos, __n);
|
2016-11-15 02:22:19 +08:00
|
|
|
__init(__sv.data(), __sv.size());
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
2017-02-17 09:17:10 +08:00
|
|
|
#endif
|
2016-11-15 02:22:19 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp, class>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __default_init_tag())
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
__init(__sv.data(), __sv.size());
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp, class>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
__init(__sv.data(), __sv.size());
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template <class _InputIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
|
|
|
__zero();
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
try
|
|
|
|
{
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
for (; __first != __last; ++__first)
|
|
|
|
push_back(*__first);
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
if (__is_long())
|
2010-11-18 01:55:08 +08:00
|
|
|
__alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
|
2010-05-12 03:42:16 +08:00
|
|
|
throw;
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__sz > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
pointer __p;
|
|
|
|
if (__sz < __min_cap)
|
|
|
|
{
|
|
|
|
__set_short_size(__sz);
|
|
|
|
__p = __get_short_pointer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __cap = __recommend(__sz);
|
2010-11-18 01:55:08 +08:00
|
|
|
__p = __alloc_traits::allocate(__alloc(), __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap+1);
|
|
|
|
__set_long_size(__sz);
|
|
|
|
}
|
2014-10-28 03:28:20 +08:00
|
|
|
for (; __first != __last; ++__first, (void) ++__p)
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::assign(*__p, *__first);
|
|
|
|
traits_type::assign(*__p, value_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2019-03-14 20:31:10 +08:00
|
|
|
template<class _InputIterator, class>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __default_init_tag())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__init(__first, __last);
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2019-03-14 20:31:10 +08:00
|
|
|
template<class _InputIterator, class>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
|
|
|
|
const allocator_type& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__init(__first, __last);
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-08-13 05:56:02 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(
|
|
|
|
initializer_list<_CharT> __il)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __default_init_tag())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__init(__il.begin(), __il.end());
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2017-04-13 07:45:53 +08:00
|
|
|
|
2017-02-17 09:17:10 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(
|
|
|
|
initializer_list<_CharT> __il, const _Allocator& __a)
|
[libc++] Add __default_init_tag to basic_string constructors
This removes unneeded zero initialization of string data.
For example, given the below code:
void Init(void *mem) {
new (mem) std::string("Hello World");
}
Assembly before:
Init(void*):
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Assembly after:
Init():
mov byte ptr [rdi], 22
movabs rax, 8022916924116329800
mov qword ptr [rdi + 1], rax
mov dword ptr [rdi + 8], 1684828783
mov byte ptr [rdi + 12], 0
ret
Patch by Martijn Vels (mvels@google.com)
Reviewed as https://reviews.llvm.org/D70621
2019-12-17 08:03:23 +08:00
|
|
|
: __r_(__default_init_tag(), __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__init(__il.begin(), __il.end());
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2011-08-13 05:56:02 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::~basic_string()
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__erase_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__is_long())
|
2010-11-18 01:55:08 +08:00
|
|
|
__alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
|
|
|
|
(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
|
2013-06-29 00:59:19 +08:00
|
|
|
size_type __n_copy, size_type __n_del, size_type __n_add, const value_type* __p_new_stuff)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_type __ms = max_size();
|
|
|
|
if (__delta_cap > __ms - __old_cap - 1)
|
|
|
|
this->__throw_length_error();
|
|
|
|
pointer __old_p = __get_pointer();
|
|
|
|
size_type __cap = __old_cap < __ms / 2 - __alignment ?
|
2011-07-01 05:18:19 +08:00
|
|
|
__recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
|
2010-05-12 03:42:16 +08:00
|
|
|
__ms - 1;
|
2010-11-18 01:55:08 +08:00
|
|
|
pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__invalidate_all_iterators();
|
|
|
|
if (__n_copy != 0)
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p),
|
|
|
|
_VSTD::__to_address(__old_p), __n_copy);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n_add != 0)
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
|
|
|
|
if (__sec_cp_sz != 0)
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add,
|
|
|
|
_VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__old_cap+1 != __min_cap)
|
2010-11-18 01:55:08 +08:00
|
|
|
__alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap+1);
|
|
|
|
__old_sz = __n_copy + __n_add + __sec_cp_sz;
|
|
|
|
__set_long_size(__old_sz);
|
|
|
|
traits_type::assign(__p[__old_sz], value_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
|
|
|
|
size_type __n_copy, size_type __n_del, size_type __n_add)
|
|
|
|
{
|
|
|
|
size_type __ms = max_size();
|
2013-11-06 22:24:38 +08:00
|
|
|
if (__delta_cap > __ms - __old_cap)
|
2010-05-12 03:42:16 +08:00
|
|
|
this->__throw_length_error();
|
|
|
|
pointer __old_p = __get_pointer();
|
|
|
|
size_type __cap = __old_cap < __ms / 2 - __alignment ?
|
2011-07-01 05:18:19 +08:00
|
|
|
__recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
|
2010-05-12 03:42:16 +08:00
|
|
|
__ms - 1;
|
2010-11-18 01:55:08 +08:00
|
|
|
pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__invalidate_all_iterators();
|
|
|
|
if (__n_copy != 0)
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p),
|
|
|
|
_VSTD::__to_address(__old_p), __n_copy);
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
|
|
|
|
if (__sec_cp_sz != 0)
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add,
|
|
|
|
_VSTD::__to_address(__old_p) + __n_copy + __n_del,
|
2013-06-29 00:59:19 +08:00
|
|
|
__sec_cp_sz);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__old_cap+1 != __min_cap)
|
2010-11-18 01:55:08 +08:00
|
|
|
__alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
__set_long_pointer(__p);
|
|
|
|
__set_long_cap(__cap+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// assign
|
|
|
|
|
2020-02-27 04:55:49 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template <bool __is_short>
|
2020-04-11 06:36:31 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
|
2020-02-27 04:55:49 +08:00
|
|
|
const value_type* __s, size_type __n) {
|
|
|
|
size_type __cap = __is_short ? __min_cap : __get_long_cap();
|
|
|
|
if (__n < __cap) {
|
|
|
|
pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
|
|
|
|
__is_short ? __set_short_size(__n) : __set_long_size(__n);
|
|
|
|
traits_type::copy(_VSTD::__to_address(__p), __s, __n);
|
|
|
|
traits_type::assign(__p[__n], value_type());
|
|
|
|
__invalidate_iterators_past(__n);
|
|
|
|
} else {
|
|
|
|
size_type __sz = __is_short ? __get_short_size() : __get_long_size();
|
|
|
|
__grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
|
|
|
|
}
|
2020-04-11 06:36:31 +08:00
|
|
|
return *this;
|
2020-02-27 04:55:49 +08:00
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __cap = capacity();
|
|
|
|
if (__cap >= __n)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* __p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::move(__p, __s, __n);
|
|
|
|
traits_type::assign(__p[__n], value_type());
|
|
|
|
__set_size(__n);
|
|
|
|
__invalidate_iterators_past(__n);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
__grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
|
|
|
|
{
|
|
|
|
size_type __cap = capacity();
|
|
|
|
if (__cap < __n)
|
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
__grow_by(__cap, __n - __cap, __sz, 0, __sz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__invalidate_iterators_past(__n);
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* __p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::assign(__p, __n, __c);
|
|
|
|
traits_type::assign(__p[__n], value_type());
|
|
|
|
__set_size(__n);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
|
|
|
|
{
|
|
|
|
pointer __p;
|
|
|
|
if (__is_long())
|
|
|
|
{
|
|
|
|
__p = __get_long_pointer();
|
|
|
|
__set_long_size(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__p = __get_short_pointer();
|
|
|
|
__set_short_size(1);
|
|
|
|
}
|
|
|
|
traits_type::assign(*__p, __c);
|
|
|
|
traits_type::assign(*++__p, value_type());
|
|
|
|
__invalidate_iterators_past(1);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2010-11-18 01:55:08 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
|
|
|
|
{
|
2020-02-27 04:55:49 +08:00
|
|
|
if (this != &__str) {
|
|
|
|
__copy_assign_alloc(__str);
|
|
|
|
if (!__is_long()) {
|
|
|
|
if (!__str.__is_long()) {
|
2020-01-16 06:27:10 +08:00
|
|
|
__r_.first().__r = __str.__r_.first().__r;
|
2020-02-27 04:55:49 +08:00
|
|
|
} else {
|
2020-04-11 06:36:31 +08:00
|
|
|
return __assign_no_alias<true>(__str.data(), __str.size());
|
2020-02-27 04:55:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
2020-04-11 06:36:31 +08:00
|
|
|
return __assign_no_alias<false>(__str.data(), __str.size());
|
2010-11-18 01:55:08 +08:00
|
|
|
}
|
2020-02-27 04:55:49 +08:00
|
|
|
}
|
|
|
|
return *this;
|
2010-11-18 01:55:08 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-11-18 01:55:08 +08:00
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-11-18 01:55:08 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_(__alloc_traits::is_always_equal::value)
|
2010-11-18 01:55:08 +08:00
|
|
|
{
|
|
|
|
if (__alloc() != __str.__alloc())
|
|
|
|
assign(__str);
|
|
|
|
else
|
|
|
|
__move_assign(__str, true_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-11-18 01:55:08 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
|
2015-08-19 02:57:00 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
_NOEXCEPT
|
|
|
|
#else
|
2011-06-04 02:40:47 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2015-08-19 02:57:00 +08:00
|
|
|
#endif
|
2010-11-18 01:55:08 +08:00
|
|
|
{
|
2019-11-27 23:13:00 +08:00
|
|
|
if (__is_long()) {
|
|
|
|
__alloc_traits::deallocate(__alloc(), __get_long_pointer(),
|
|
|
|
__get_long_cap());
|
|
|
|
#if _LIBCPP_STD_VER <= 14
|
|
|
|
if (!is_nothrow_move_assignable<allocator_type>::value) {
|
|
|
|
__set_short_size(0);
|
|
|
|
traits_type::assign(__get_short_pointer()[0], value_type());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
__move_assign_alloc(__str);
|
|
|
|
__r_.first() = __str.__r_.first();
|
|
|
|
__str.__set_short_size(0);
|
|
|
|
traits_type::assign(__str.__get_short_pointer()[0], value_type());
|
2010-11-18 01:55:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-11-18 01:55:08 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
|
2010-11-18 01:55:08 +08:00
|
|
|
{
|
|
|
|
__move_assign(__str, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_move_assignment::value>());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template<class _InputIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_exactly_cpp17_input_iterator <_InputIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
2016-09-05 09:54:30 +08:00
|
|
|
const basic_string __temp(__first, __last, __alloc());
|
2016-01-14 05:54:34 +08:00
|
|
|
assign(__temp.data(), __temp.size());
|
2012-10-13 10:03:45 +08:00
|
|
|
return *this;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template<class _ForwardIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __cap = capacity();
|
|
|
|
if (__cap < __n)
|
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
__grow_by(__cap, __n - __cap, __sz, 0, __sz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__invalidate_iterators_past(__n);
|
|
|
|
pointer __p = __get_pointer();
|
|
|
|
for (; __first != __last; ++__first, ++__p)
|
|
|
|
traits_type::assign(*__p, *__first);
|
|
|
|
traits_type::assign(*__p, value_type());
|
|
|
|
__set_size(__n);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
|
|
|
|
{
|
|
|
|
size_type __sz = __str.size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
|
|
|
|
&& !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
|
2017-11-16 04:02:27 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2016-09-25 06:45:42 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __sz = __sv.size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
return assign(__s, traits_type::length(__s));
|
|
|
|
}
|
|
|
|
|
|
|
|
// append
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __cap = capacity();
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__cap - __sz >= __n)
|
|
|
|
{
|
|
|
|
if (__n)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* __p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::copy(__p + __sz, __s, __n);
|
|
|
|
__sz += __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
|
|
|
|
{
|
|
|
|
if (__n)
|
|
|
|
{
|
|
|
|
size_type __cap = capacity();
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__cap - __sz < __n)
|
|
|
|
__grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
|
|
|
|
pointer __p = __get_pointer();
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c);
|
2010-05-12 03:42:16 +08:00
|
|
|
__sz += __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-11-27 04:15:38 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
inline void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n)
|
|
|
|
{
|
|
|
|
size_type __cap = capacity();
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__cap - __sz < __n)
|
|
|
|
__grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
|
|
|
|
pointer __p = __get_pointer();
|
|
|
|
__sz += __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
|
|
|
|
{
|
2013-05-01 05:44:48 +08:00
|
|
|
bool __is_short = !__is_long();
|
|
|
|
size_type __cap;
|
|
|
|
size_type __sz;
|
|
|
|
if (__is_short)
|
|
|
|
{
|
|
|
|
__cap = __min_cap - 1;
|
|
|
|
__sz = __get_short_size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__cap = __get_long_cap() - 1;
|
|
|
|
__sz = __get_long_size();
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__sz == __cap)
|
2013-05-01 05:44:48 +08:00
|
|
|
{
|
2010-05-12 03:42:16 +08:00
|
|
|
__grow_by(__cap, 1, __sz, __sz, 0);
|
2013-05-01 05:44:48 +08:00
|
|
|
__is_short = !__is_long();
|
|
|
|
}
|
|
|
|
pointer __p;
|
|
|
|
if (__is_short)
|
|
|
|
{
|
|
|
|
__p = __get_short_pointer() + __sz;
|
|
|
|
__set_short_size(__sz+1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__p = __get_long_pointer() + __sz;
|
|
|
|
__set_long_size(__sz+1);
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::assign(*__p, __c);
|
|
|
|
traits_type::assign(*++__p, value_type());
|
|
|
|
}
|
|
|
|
|
2016-09-07 11:32:06 +08:00
|
|
|
template <class _Tp>
|
2016-09-05 09:54:30 +08:00
|
|
|
bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last)
|
|
|
|
{
|
|
|
|
return __first <= __p && __p < __last;
|
|
|
|
}
|
|
|
|
|
2016-09-07 11:32:06 +08:00
|
|
|
template <class _Tp1, class _Tp2>
|
2016-12-24 07:37:52 +08:00
|
|
|
bool __ptr_in_range (const _Tp1*, const _Tp2*, const _Tp2*)
|
2016-09-07 11:32:06 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template<class _ForwardIterator>
|
2016-10-31 10:46:25 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
|
|
|
|
_ForwardIterator __first, _ForwardIterator __last)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2019-11-18 14:46:58 +08:00
|
|
|
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
|
2016-10-31 10:46:25 +08:00
|
|
|
"function requires a ForwardIterator");
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __sz = size();
|
|
|
|
size_type __cap = capacity();
|
2011-07-01 05:18:19 +08:00
|
|
|
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n)
|
|
|
|
{
|
2017-04-15 14:49:02 +08:00
|
|
|
typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
|
|
|
|
_CharRef __tmp_ref = *__first;
|
|
|
|
if (__ptr_in_range(_VSTD::addressof(__tmp_ref), data(), data() + size()))
|
2016-09-05 09:54:30 +08:00
|
|
|
{
|
|
|
|
const basic_string __temp (__first, __last, __alloc());
|
|
|
|
append(__temp.data(), __temp.size());
|
|
|
|
}
|
2019-05-30 00:01:36 +08:00
|
|
|
else
|
2016-09-05 09:54:30 +08:00
|
|
|
{
|
|
|
|
if (__cap - __sz < __n)
|
|
|
|
__grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
|
|
|
|
pointer __p = __get_pointer() + __sz;
|
|
|
|
for (; __first != __last; ++__p, ++__first)
|
|
|
|
traits_type::assign(*__p, *__first);
|
|
|
|
traits_type::assign(*__p, value_type());
|
|
|
|
__set_size(__sz + __n);
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
|
|
|
|
{
|
|
|
|
return append(__str.data(), __str.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
|
|
|
|
{
|
|
|
|
size_type __sz = __str.size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2016-10-04 07:40:48 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2016-09-25 06:45:42 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __sz = __sv.size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos));
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
return append(__s, traits_type::length(__s));
|
|
|
|
}
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __sz = size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
size_type __cap = capacity();
|
|
|
|
if (__cap - __sz >= __n)
|
|
|
|
{
|
|
|
|
if (__n)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* __p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n_move = __sz - __pos;
|
|
|
|
if (__n_move != 0)
|
|
|
|
{
|
|
|
|
if (__p + __pos <= __s && __s < __p + __sz)
|
|
|
|
__s += __n;
|
|
|
|
traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
|
|
|
|
}
|
|
|
|
traits_type::move(__p + __pos, __s, __n);
|
|
|
|
__sz += __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
|
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
if (__n)
|
|
|
|
{
|
|
|
|
size_type __cap = capacity();
|
2013-06-29 00:59:19 +08:00
|
|
|
value_type* __p;
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__cap - __sz >= __n)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n_move = __sz - __pos;
|
|
|
|
if (__n_move != 0)
|
|
|
|
traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_long_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
traits_type::assign(__p + __pos, __n, __c);
|
|
|
|
__sz += __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template<class _InputIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
|
|
|
|
"string::insert(iterator, range) called with an iterator not"
|
|
|
|
" referring to this string");
|
|
|
|
#endif
|
2016-09-05 09:54:30 +08:00
|
|
|
const basic_string __temp(__first, __last, __alloc());
|
2016-01-14 05:54:34 +08:00
|
|
|
return insert(__pos, __temp.data(), __temp.data() + __temp.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template<class _ForwardIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_forward_iterator<_ForwardIterator>::value
|
2016-01-14 05:54:34 +08:00
|
|
|
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
|
|
|
|
"string::insert(iterator, range) called with an iterator not"
|
|
|
|
" referring to this string");
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __ip = static_cast<size_type>(__pos - begin());
|
2011-07-01 05:18:19 +08:00
|
|
|
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n)
|
|
|
|
{
|
2017-04-15 14:49:02 +08:00
|
|
|
typedef typename iterator_traits<_ForwardIterator>::reference _CharRef;
|
|
|
|
_CharRef __tmp_char = *__first;
|
|
|
|
if (__ptr_in_range(_VSTD::addressof(__tmp_char), data(), data() + size()))
|
2016-09-05 09:54:30 +08:00
|
|
|
{
|
|
|
|
const basic_string __temp(__first, __last, __alloc());
|
|
|
|
return insert(__pos, __temp.data(), __temp.data() + __temp.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
size_type __sz = size();
|
|
|
|
size_type __cap = capacity();
|
2013-06-29 00:59:19 +08:00
|
|
|
value_type* __p;
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__cap - __sz >= __n)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n_move = __sz - __ip;
|
|
|
|
if (__n_move != 0)
|
|
|
|
traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_long_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
__sz += __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
for (__p += __ip; __first != __last; ++__p, ++__first)
|
|
|
|
traits_type::assign(*__p, *__first);
|
|
|
|
}
|
|
|
|
return begin() + __ip;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
|
|
|
|
{
|
|
|
|
return insert(__pos1, __str.data(), __str.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
|
|
|
|
size_type __pos2, size_type __n)
|
|
|
|
{
|
|
|
|
size_type __str_sz = __str.size();
|
|
|
|
if (__pos2 > __str_sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
|
2017-11-16 04:02:27 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __pos2, size_type __n)
|
|
|
|
{
|
2016-09-25 06:45:42 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __str_sz = __sv.size();
|
|
|
|
if (__pos2 > __str_sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
return insert(__pos, __s, traits_type::length(__s));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
|
|
|
|
{
|
|
|
|
size_type __ip = static_cast<size_type>(__pos - begin());
|
|
|
|
size_type __sz = size();
|
|
|
|
size_type __cap = capacity();
|
2013-06-29 00:59:19 +08:00
|
|
|
value_type* __p;
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__cap == __sz)
|
|
|
|
{
|
|
|
|
__grow_by(__cap, 1, __sz, __ip, 0, 1);
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_long_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n_move = __sz - __ip;
|
|
|
|
if (__n_move != 0)
|
|
|
|
traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
|
|
|
|
}
|
|
|
|
traits_type::assign(__p[__ip], __c);
|
|
|
|
traits_type::assign(__p[++__sz], value_type());
|
|
|
|
__set_size(__sz);
|
|
|
|
return begin() + static_cast<difference_type>(__ip);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
|
|
|
|
"string::insert(iterator, n, value) called with an iterator not"
|
|
|
|
" referring to this string");
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
difference_type __p = __pos - begin();
|
|
|
|
insert(static_cast<size_type>(__p), __n, __c);
|
|
|
|
return begin() + __p;
|
|
|
|
}
|
|
|
|
|
|
|
|
// replace
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
|
2017-03-09 09:54:13 +08:00
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __sz = size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
__n1 = _VSTD::min(__n1, __sz - __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __cap = capacity();
|
|
|
|
if (__cap - __sz + __n1 >= __n2)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* __p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n1 != __n2)
|
|
|
|
{
|
|
|
|
size_type __n_move = __sz - __pos - __n1;
|
|
|
|
if (__n_move != 0)
|
|
|
|
{
|
|
|
|
if (__n1 > __n2)
|
|
|
|
{
|
|
|
|
traits_type::move(__p + __pos, __s, __n2);
|
|
|
|
traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
|
|
|
|
goto __finish;
|
|
|
|
}
|
|
|
|
if (__p + __pos < __s && __s < __p + __sz)
|
|
|
|
{
|
|
|
|
if (__p + __pos + __n1 <= __s)
|
|
|
|
__s += __n2 - __n1;
|
|
|
|
else // __p + __pos < __s < __p + __pos + __n1
|
|
|
|
{
|
|
|
|
traits_type::move(__p + __pos, __s, __n1);
|
|
|
|
__pos += __n1;
|
|
|
|
__s += __n2;
|
|
|
|
__n2 -= __n1;
|
|
|
|
__n1 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
traits_type::move(__p + __pos, __s, __n2);
|
|
|
|
__finish:
|
2020-01-29 02:43:19 +08:00
|
|
|
// __sz += __n2 - __n1; in this and the below function below can cause unsigned
|
|
|
|
// integer overflow, but this is a safe operation, so we disable the check.
|
2010-05-12 03:42:16 +08:00
|
|
|
__sz += __n2 - __n1;
|
|
|
|
__set_size(__sz);
|
|
|
|
__invalidate_iterators_past(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
|
2017-03-09 09:54:13 +08:00
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
__n1 = _VSTD::min(__n1, __sz - __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __cap = capacity();
|
2013-06-29 00:59:19 +08:00
|
|
|
value_type* __p;
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__cap - __sz + __n1 >= __n2)
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n1 != __n2)
|
|
|
|
{
|
|
|
|
size_type __n_move = __sz - __pos - __n1;
|
|
|
|
if (__n_move != 0)
|
|
|
|
traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
|
2019-11-17 06:13:26 +08:00
|
|
|
__p = _VSTD::__to_address(__get_long_pointer());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
traits_type::assign(__p + __pos, __n2, __c);
|
|
|
|
__sz += __n2 - __n1;
|
|
|
|
__set_size(__sz);
|
|
|
|
__invalidate_iterators_past(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
template<class _InputIterator>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
2019-11-18 14:46:58 +08:00
|
|
|
__is_cpp17_input_iterator<_InputIterator>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
|
2010-05-12 03:42:16 +08:00
|
|
|
_InputIterator __j1, _InputIterator __j2)
|
|
|
|
{
|
2016-09-05 09:54:30 +08:00
|
|
|
const basic_string __temp(__j1, __j2, __alloc());
|
2016-01-14 05:54:34 +08:00
|
|
|
return this->replace(__i1, __i2, __temp);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
|
|
|
|
{
|
|
|
|
return replace(__pos1, __n1, __str.data(), __str.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
|
|
|
|
size_type __pos2, size_type __n2)
|
|
|
|
{
|
|
|
|
size_type __str_sz = __str.size();
|
|
|
|
if (__pos2 > __str_sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
|
2017-11-16 04:02:27 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-09-25 06:45:42 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __pos2, size_type __n2)
|
|
|
|
{
|
2016-09-25 06:45:42 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __str_sz = __sv.size();
|
|
|
|
if (__pos2 > __str_sz)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
return replace(__pos, __n1, __s, traits_type::length(__s));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),
|
|
|
|
__str.data(), __str.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
2010-11-18 05:11:40 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
|
|
|
|
}
|
|
|
|
|
|
|
|
// erase
|
|
|
|
|
Inline basic_string::erase for fastpath where __n == npos
Summary:
This change checks for the case where people want to erase a string to the end, i.e., __n == npos, and inlines the call if so.
This also demonstrates keeping the ABI intact for V1, but inlining the erase() method for unstable.
Reviewers: EricWF, mclow.lists, ldionne
Reviewed By: EricWF, ldionne
Subscribers: smeenai, dexonsmith, christof, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D73743
2020-02-27 02:25:43 +08:00
|
|
|
// 'externally instantiated' erase() implementation, called when __n != npos.
|
|
|
|
// Does not check __pos against size()
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
Inline basic_string::erase for fastpath where __n == npos
Summary:
This change checks for the case where people want to erase a string to the end, i.e., __n == npos, and inlines the call if so.
This also demonstrates keeping the ABI intact for V1, but inlining the erase() method for unstable.
Reviewers: EricWF, mclow.lists, ldionne
Reviewed By: EricWF, ldionne
Subscribers: smeenai, dexonsmith, christof, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D73743
2020-02-27 02:25:43 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
|
|
|
|
size_type __pos, size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__n)
|
|
|
|
{
|
Inline basic_string::erase for fastpath where __n == npos
Summary:
This change checks for the case where people want to erase a string to the end, i.e., __n == npos, and inlines the call if so.
This also demonstrates keeping the ABI intact for V1, but inlining the erase() method for unstable.
Reviewers: EricWF, mclow.lists, ldionne
Reviewed By: EricWF, ldionne
Subscribers: smeenai, dexonsmith, christof, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D73743
2020-02-27 02:25:43 +08:00
|
|
|
size_type __sz = size();
|
2019-11-17 06:13:26 +08:00
|
|
|
value_type* __p = _VSTD::__to_address(__get_pointer());
|
2011-07-01 05:18:19 +08:00
|
|
|
__n = _VSTD::min(__n, __sz - __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n_move = __sz - __pos - __n;
|
|
|
|
if (__n_move != 0)
|
|
|
|
traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
|
|
|
|
__sz -= __n;
|
|
|
|
__set_size(__sz);
|
|
|
|
__invalidate_iterators_past(__sz);
|
|
|
|
traits_type::assign(__p[__sz], value_type());
|
|
|
|
}
|
Inline basic_string::erase for fastpath where __n == npos
Summary:
This change checks for the case where people want to erase a string to the end, i.e., __n == npos, and inlines the call if so.
This also demonstrates keeping the ABI intact for V1, but inlining the erase() method for unstable.
Reviewers: EricWF, mclow.lists, ldionne
Reviewed By: EricWF, ldionne
Subscribers: smeenai, dexonsmith, christof, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D73743
2020-02-27 02:25:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>&
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
|
|
|
|
size_type __n) {
|
|
|
|
if (__pos > size()) this->__throw_out_of_range();
|
|
|
|
if (__n == npos) {
|
|
|
|
__erase_to_end(__pos);
|
|
|
|
} else {
|
|
|
|
__erase_external_with_move(__pos, __n);
|
|
|
|
}
|
|
|
|
return *this;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
|
|
|
|
"string::erase(iterator) called with an iterator not"
|
|
|
|
" referring to this string");
|
|
|
|
#endif
|
|
|
|
_LIBCPP_ASSERT(__pos != end(),
|
|
|
|
"string::erase(iterator) called with a non-dereferenceable iterator");
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator __b = begin();
|
|
|
|
size_type __r = static_cast<size_type>(__pos - __b);
|
|
|
|
erase(__r, 1);
|
2011-12-02 04:21:04 +08:00
|
|
|
return __b + static_cast<difference_type>(__r);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
|
|
|
|
"string::erase(iterator, iterator) called with an iterator not"
|
|
|
|
" referring to this string");
|
|
|
|
#endif
|
|
|
|
_LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator __b = begin();
|
|
|
|
size_type __r = static_cast<size_type>(__first - __b);
|
|
|
|
erase(__r, static_cast<size_type>(__last - __first));
|
2011-12-02 04:21:04 +08:00
|
|
|
return __b + static_cast<difference_type>(__r);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::pop_back()
|
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __sz;
|
|
|
|
if (__is_long())
|
|
|
|
{
|
|
|
|
__sz = __get_long_size() - 1;
|
|
|
|
__set_long_size(__sz);
|
|
|
|
traits_type::assign(*(__get_long_pointer() + __sz), value_type());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__sz = __get_short_size() - 1;
|
|
|
|
__set_short_size(__sz);
|
|
|
|
traits_type::assign(*(__get_short_pointer() + __sz), value_type());
|
|
|
|
}
|
|
|
|
__invalidate_iterators_past(__sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__invalidate_all_iterators();
|
|
|
|
if (__is_long())
|
|
|
|
{
|
|
|
|
traits_type::assign(*__get_long_pointer(), value_type());
|
|
|
|
__set_long_size(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
traits_type::assign(*__get_short_pointer(), value_type());
|
|
|
|
__set_short_size(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
|
|
|
|
{
|
|
|
|
if (__is_long())
|
|
|
|
{
|
|
|
|
traits_type::assign(*(__get_long_pointer() + __pos), value_type());
|
|
|
|
__set_long_size(__pos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
traits_type::assign(*(__get_short_pointer() + __pos), value_type());
|
|
|
|
__set_short_size(__pos);
|
|
|
|
}
|
|
|
|
__invalidate_iterators_past(__pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
|
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__n > __sz)
|
|
|
|
append(__n - __sz, __c);
|
|
|
|
else
|
|
|
|
__erase_to_end(__n);
|
|
|
|
}
|
|
|
|
|
2018-11-27 04:15:38 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
inline void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
|
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__n > __sz) {
|
|
|
|
__append_default_init(__n - __sz);
|
|
|
|
} else
|
|
|
|
__erase_to_end(__n);
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2010-11-18 01:55:08 +08:00
|
|
|
size_type __m = __alloc_traits::max_size(__alloc());
|
2017-10-17 21:16:01 +08:00
|
|
|
#ifdef _LIBCPP_BIG_ENDIAN
|
2013-11-01 01:23:08 +08:00
|
|
|
return (__m <= ~__long_mask ? __m : __m/2) - __alignment;
|
2010-05-12 03:42:16 +08:00
|
|
|
#else
|
2013-11-01 01:23:08 +08:00
|
|
|
return __m - __alignment;
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)
|
|
|
|
{
|
|
|
|
if (__res_arg > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
size_type __cap = capacity();
|
|
|
|
size_type __sz = size();
|
2011-07-01 05:18:19 +08:00
|
|
|
__res_arg = _VSTD::max(__res_arg, __sz);
|
2010-05-12 03:42:16 +08:00
|
|
|
__res_arg = __recommend(__res_arg);
|
|
|
|
if (__res_arg != __cap)
|
|
|
|
{
|
|
|
|
pointer __new_data, __p;
|
|
|
|
bool __was_long, __now_long;
|
|
|
|
if (__res_arg == __min_cap - 1)
|
|
|
|
{
|
|
|
|
__was_long = true;
|
|
|
|
__now_long = false;
|
|
|
|
__new_data = __get_short_pointer();
|
|
|
|
__p = __get_long_pointer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (__res_arg > __cap)
|
2010-11-18 01:55:08 +08:00
|
|
|
__new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
try
|
|
|
|
{
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-11-18 01:55:08 +08:00
|
|
|
__new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#else // _LIBCPP_NO_EXCEPTIONS
|
2013-06-29 00:59:19 +08:00
|
|
|
if (__new_data == nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
return;
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
__now_long = true;
|
|
|
|
__was_long = __is_long();
|
|
|
|
__p = __get_pointer();
|
|
|
|
}
|
2019-11-17 06:13:26 +08:00
|
|
|
traits_type::copy(_VSTD::__to_address(__new_data),
|
|
|
|
_VSTD::__to_address(__p), size()+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__was_long)
|
2010-11-18 01:55:08 +08:00
|
|
|
__alloc_traits::deallocate(__alloc(), __p, __cap+1);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__now_long)
|
|
|
|
{
|
|
|
|
__set_long_cap(__res_arg+1);
|
|
|
|
__set_long_size(__sz);
|
|
|
|
__set_long_pointer(__new_data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__set_short_size(__sz);
|
|
|
|
__invalidate_all_iterators();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
|
2016-07-21 13:31:24 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
|
2010-05-12 03:42:16 +08:00
|
|
|
return *(data() + __pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::reference
|
2016-07-21 13:31:24 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
|
2010-05-12 03:42:16 +08:00
|
|
|
return *(__get_pointer() + __pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
|
|
|
|
{
|
|
|
|
if (__n >= size())
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return (*this)[__n];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::reference
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n >= size())
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return (*this)[__n];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::reference
|
2019-03-19 11:30:07 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
|
2010-05-12 03:42:16 +08:00
|
|
|
return *__get_pointer();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
|
2019-03-19 11:30:07 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
|
2010-05-12 03:42:16 +08:00
|
|
|
return *data();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::reference
|
2019-03-19 11:30:07 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
|
2010-05-12 03:42:16 +08:00
|
|
|
return *(__get_pointer() + size() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
|
2019-03-19 11:30:07 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
_LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
|
2010-05-12 03:42:16 +08:00
|
|
|
return *(data() + size() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__pos > __sz)
|
|
|
|
this->__throw_out_of_range();
|
2011-07-01 05:18:19 +08:00
|
|
|
size_type __rlen = _VSTD::min(__n, __sz - __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
traits_type::copy(__s, data() + __pos, __rlen);
|
|
|
|
return __rlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
|
|
|
|
{
|
|
|
|
return basic_string(*this, __pos, __n, __alloc());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
|
2015-07-14 04:04:56 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_NOEXCEPT
|
2015-07-14 04:04:56 +08:00
|
|
|
#else
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
|
2015-07-14 04:04:56 +08:00
|
|
|
__is_nothrow_swappable<allocator_type>::value)
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
if (!__is_long())
|
|
|
|
__get_db()->__invalidate_all(this);
|
|
|
|
if (!__str.__is_long())
|
|
|
|
__get_db()->__invalidate_all(&__str);
|
|
|
|
__get_db()->swap(this, &__str);
|
|
|
|
#endif
|
2016-12-28 13:53:01 +08:00
|
|
|
_LIBCPP_ASSERT(
|
|
|
|
__alloc_traits::propagate_on_container_swap::value ||
|
|
|
|
__alloc_traits::is_always_equal::value ||
|
|
|
|
__alloc() == __str.__alloc(), "swapping non-equal allocators");
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(__r_.first(), __str.__r_.first());
|
2015-07-14 04:04:56 +08:00
|
|
|
__swap_allocator(__alloc(), __str.__alloc());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// find
|
|
|
|
|
|
|
|
template <class _Traits>
|
|
|
|
struct _LIBCPP_HIDDEN __traits_eq
|
|
|
|
{
|
|
|
|
typedef typename _Traits::char_type char_type;
|
2011-05-30 03:57:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
|
|
|
|
{return _Traits::eq(__x, __y);}
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos,
|
|
|
|
size_type __n) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __s, __pos, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __str.data(), __pos, __str.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
|
|
|
|
size_type __pos) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find<value_type, size_type, traits_type, npos>
|
|
|
|
(data(), size(), __sv.data(), __pos, __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __s, __pos, traits_type::length(__s));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __c, __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// rfind
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos,
|
|
|
|
size_type __n) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_rfind<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __s, __pos, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_rfind<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __str.data(), __pos, __str.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
|
|
|
|
size_type __pos) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_rfind<value_type, size_type, traits_type, npos>
|
|
|
|
(data(), size(), __sv.data(), __pos, __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_rfind<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __s, __pos, traits_type::length(__s));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_rfind<value_type, size_type, traits_type, npos>
|
2014-06-02 10:22:49 +08:00
|
|
|
(data(), size(), __c, __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// find_first_of
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos,
|
|
|
|
size_type __n) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __str.data(), __pos, __str.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
|
|
|
|
size_type __pos) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_of<value_type, size_type, traits_type, npos>
|
|
|
|
(data(), size(), __sv.data(), __pos, __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, traits_type::length(__s));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return find(__c, __pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// find_last_of
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos,
|
|
|
|
size_type __n) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __str.data(), __pos, __str.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
|
|
|
|
size_type __pos) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_of<value_type, size_type, traits_type, npos>
|
|
|
|
(data(), size(), __sv.data(), __pos, __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, traits_type::length(__s));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return rfind(__c, __pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// find_first_not_of
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos,
|
|
|
|
size_type __n) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __str.data(), __pos, __str.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
|
|
|
|
size_type __pos) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_not_of<value_type, size_type, traits_type, npos>
|
|
|
|
(data(), size(), __sv.data(), __pos, __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, traits_type::length(__s));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_first_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __c, __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// find_last_not_of
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos,
|
|
|
|
size_type __n) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __str.data(), __pos, __str.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
|
|
|
|
size_type __pos) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_not_of<value_type, size_type, traits_type, npos>
|
|
|
|
(data(), size(), __sv.data(), __pos, __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
|
2011-05-30 03:57:12 +08:00
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __s, __pos, traits_type::length(__s));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
|
|
|
|
size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return __str_find_last_not_of<value_type, size_type, traits_type, npos>
|
2014-02-16 09:57:26 +08:00
|
|
|
(data(), size(), __c, __pos);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// compare
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
int
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2018-07-03 02:41:15 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2011-07-25 05:45:06 +08:00
|
|
|
size_t __lhs_sz = size();
|
2016-07-21 13:31:24 +08:00
|
|
|
size_t __rhs_sz = __sv.size();
|
|
|
|
int __result = traits_type::compare(data(), __sv.data(),
|
2011-07-25 05:45:06 +08:00
|
|
|
_VSTD::min(__lhs_sz, __rhs_sz));
|
|
|
|
if (__result != 0)
|
|
|
|
return __result;
|
|
|
|
if (__lhs_sz < __rhs_sz)
|
|
|
|
return -1;
|
|
|
|
if (__lhs_sz > __rhs_sz)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2016-07-21 13:31:24 +08:00
|
|
|
int
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
return compare(__self_view(__str));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
int
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
|
|
|
|
size_type __n1,
|
|
|
|
const value_type* __s,
|
|
|
|
size_type __n2) const
|
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
|
|
|
|
size_type __sz = size();
|
|
|
|
if (__pos1 > __sz || __n2 == npos)
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
size_type __rlen = _VSTD::min(__n1, __sz - __pos1);
|
|
|
|
int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2));
|
|
|
|
if (__r == 0)
|
|
|
|
{
|
|
|
|
if (__rlen < __n2)
|
|
|
|
__r = -1;
|
|
|
|
else if (__rlen > __n2)
|
|
|
|
__r = 1;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-07-03 02:41:15 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2018-07-03 02:41:15 +08:00
|
|
|
<
|
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
|
|
|
|
int
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-07-21 13:31:24 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
|
|
|
|
size_type __n1,
|
2018-07-03 02:41:15 +08:00
|
|
|
const _Tp& __t) const
|
2016-07-21 13:31:24 +08:00
|
|
|
{
|
2018-07-03 02:41:15 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return compare(__pos1, __n1, __sv.data(), __sv.size());
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
int
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
|
|
|
|
size_type __n1,
|
|
|
|
const basic_string& __str) const
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return compare(__pos1, __n1, __str.data(), __str.size());
|
|
|
|
}
|
|
|
|
|
2016-07-21 13:31:24 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
2016-09-25 06:45:42 +08:00
|
|
|
template <class _Tp>
|
2020-01-16 05:57:08 +08:00
|
|
|
_EnableIf
|
2016-09-25 06:45:42 +08:00
|
|
|
<
|
2020-01-16 05:57:08 +08:00
|
|
|
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
|
|
|
|
&& !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
|
2017-11-16 04:02:27 +08:00
|
|
|
int
|
2020-01-16 05:57:08 +08:00
|
|
|
>
|
2016-07-21 13:31:24 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
|
|
|
|
size_type __n1,
|
2016-09-25 06:45:42 +08:00
|
|
|
const _Tp& __t,
|
2016-07-21 13:31:24 +08:00
|
|
|
size_type __pos2,
|
|
|
|
size_type __n2) const
|
|
|
|
{
|
2016-09-25 06:45:42 +08:00
|
|
|
__self_view __sv = __t;
|
2016-07-21 13:31:24 +08:00
|
|
|
return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
int
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
|
|
|
|
size_type __n1,
|
|
|
|
const basic_string& __str,
|
|
|
|
size_type __pos2,
|
|
|
|
size_type __n2) const
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-07-21 13:31:24 +08:00
|
|
|
return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
int
|
2013-06-29 00:59:19 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
return compare(0, npos, __s, traits_type::length(__s));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _CharT, class _Traits, class _Allocator>
|
|
|
|
int
|
2011-05-30 03:57:12 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
|
|
|
|
size_type __n1,
|
2013-06-29 00:59:19 +08:00
|
|
|
const value_type* __s) const
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-05-15 19:27:39 +08:00
|
|
|
_LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
|
2010-05-12 03:42:16 +08:00
|
|
|
return compare(__pos1, __n1, __s, traits_type::length(__s));
|
|
|
|
}
|
|
|
|
|
|
|
|
// __invariants
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__invariants() const
|
|
|
|
{
|
|
|
|
if (size() > capacity())
|
|
|
|
return false;
|
|
|
|
if (capacity() < __min_cap - 1)
|
|
|
|
return false;
|
|
|
|
if (data() == 0)
|
|
|
|
return false;
|
|
|
|
if (data()[size()] != value_type(0))
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-03-09 05:15:26 +08:00
|
|
|
// __clear_and_shrink
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2019-05-30 00:01:36 +08:00
|
|
|
void
|
2018-05-30 01:04:37 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
|
2018-03-09 05:15:26 +08:00
|
|
|
{
|
|
|
|
clear();
|
|
|
|
if(__is_long())
|
|
|
|
{
|
|
|
|
__alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
|
|
|
|
__set_long_cap(0);
|
|
|
|
__set_short_size(0);
|
|
|
|
}
|
2019-05-30 00:01:36 +08:00
|
|
|
}
|
2018-03-09 05:15:26 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
// operator==
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-04-23 07:55:13 +08:00
|
|
|
size_t __lhs_sz = __lhs.size();
|
|
|
|
return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
|
|
|
|
__rhs.data(),
|
|
|
|
__lhs_sz) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-04-23 07:55:13 +08:00
|
|
|
bool
|
|
|
|
operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
|
|
|
|
const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
|
|
|
|
{
|
|
|
|
size_t __lhs_sz = __lhs.size();
|
|
|
|
if (__lhs_sz != __rhs.size())
|
|
|
|
return false;
|
|
|
|
const char* __lp = __lhs.data();
|
|
|
|
const char* __rp = __rhs.data();
|
|
|
|
if (__lhs.__is_long())
|
|
|
|
return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
|
|
|
|
for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
|
|
|
|
if (*__lp != *__rp)
|
|
|
|
return false;
|
|
|
|
return true;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator==(const _CharT* __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2015-08-28 11:02:37 +08:00
|
|
|
typedef basic_string<_CharT, _Traits, _Allocator> _String;
|
|
|
|
_LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
|
|
|
|
size_t __lhs_len = _Traits::length(__lhs);
|
|
|
|
if (__lhs_len != __rhs.size()) return false;
|
|
|
|
return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
|
|
|
|
const _CharT* __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2015-08-28 11:02:37 +08:00
|
|
|
typedef basic_string<_CharT, _Traits, _Allocator> _String;
|
|
|
|
_LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
|
|
|
|
size_t __rhs_len = _Traits::length(__rhs);
|
|
|
|
if (__rhs_len != __lhs.size()) return false;
|
|
|
|
return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__lhs == __rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator!=(const _CharT* __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__lhs == __rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|
|
|
const _CharT* __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__lhs == __rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
// operator<
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-07-24 23:07:21 +08:00
|
|
|
return __lhs.compare(__rhs) < 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|
|
|
const _CharT* __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-07-24 23:07:21 +08:00
|
|
|
return __lhs.compare(__rhs) < 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator< (const _CharT* __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __rhs.compare(__lhs) > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// operator>
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __rhs < __lhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|
|
|
const _CharT* __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __rhs < __lhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator> (const _CharT* __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __rhs < __lhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
// operator<=
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__rhs < __lhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|
|
|
const _CharT* __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__rhs < __lhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator<=(const _CharT* __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__rhs < __lhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
// operator>=
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
2011-05-30 03:57:12 +08:00
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__lhs < __rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|
|
|
const _CharT* __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__lhs < __rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
2011-05-30 03:57:12 +08:00
|
|
|
operator>=(const _CharT* __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return !(__lhs < __rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
// operator +
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
|
|
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
|
|
|
{
|
|
|
|
basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
|
|
|
|
__r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
|
|
|
|
__r.append(__rhs.data(), __rhs_sz);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
|
|
|
|
{
|
|
|
|
basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
|
|
|
|
__r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
|
|
|
|
__r.append(__rhs.data(), __rhs_sz);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
|
|
|
|
{
|
|
|
|
basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
|
|
|
|
__r.__init(&__lhs, 1, 1 + __rhs_sz);
|
|
|
|
__r.append(__rhs.data(), __rhs_sz);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2018-11-27 06:51:35 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
|
|
|
|
{
|
|
|
|
basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
|
|
|
|
__r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
|
|
|
|
__r.append(__rhs, __rhs_sz);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
|
|
|
|
{
|
|
|
|
basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
|
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
|
|
|
|
__r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
|
|
|
|
__r.push_back(__rhs);
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__lhs.append(__rhs));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__rhs.insert(0, __lhs));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__lhs.append(__rhs));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__rhs.insert(0, __lhs));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
|
|
|
|
{
|
|
|
|
__rhs.insert(__rhs.begin(), __lhs);
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__rhs);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__lhs.append(__rhs));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>
|
|
|
|
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
|
|
|
|
{
|
|
|
|
__lhs.push_back(__rhs);
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__lhs);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
// swap
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
2011-05-30 03:57:12 +08:00
|
|
|
swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
2011-06-04 02:40:47 +08:00
|
|
|
basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
|
|
|
_NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__lhs.swap(__rhs);
|
|
|
|
}
|
|
|
|
|
2018-12-11 12:35:44 +08:00
|
|
|
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
|
|
|
typedef basic_string<char8_t> u8string;
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-12-11 12:35:44 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef basic_string<char16_t> u16string;
|
|
|
|
typedef basic_string<char32_t> u32string;
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-08-13 02:38:34 +08:00
|
|
|
_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
|
|
|
|
_LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = 0);
|
|
|
|
_LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = 0);
|
|
|
|
_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0);
|
|
|
|
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(int __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(unsigned __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(long __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(long long __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(float __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(double __val);
|
|
|
|
_LIBCPP_FUNC_VIS string to_string(long double __val);
|
|
|
|
|
|
|
|
_LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
|
|
|
|
|
|
|
|
_LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = 0);
|
|
|
|
_LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = 0);
|
|
|
|
_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0);
|
|
|
|
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
|
|
|
|
_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
|
2010-06-03 02:20:39 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
2020-01-16 06:02:17 +08:00
|
|
|
_LIBCPP_FUNC_VIS
|
|
|
|
const typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::npos;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2019-05-21 05:56:51 +08:00
|
|
|
template <class _CharT, class _Allocator>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS
|
|
|
|
hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> >
|
|
|
|
: public unary_function<
|
|
|
|
basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_t
|
2019-05-21 05:56:51 +08:00
|
|
|
operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
|
|
|
|
{ return __do_string_hash(__val.data(), __val.data() + __val.size()); }
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-07-18 23:51:59 +08:00
|
|
|
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>&
|
|
|
|
operator>>(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, _CharT __dlm);
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_istream<_CharT, _Traits>&
|
|
|
|
getline(basic_istream<_CharT, _Traits>& __is,
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>& __str);
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-07-18 23:51:59 +08:00
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_istream<_CharT, _Traits>&
|
|
|
|
getline(basic_istream<_CharT, _Traits>&& __is,
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_istream<_CharT, _Traits>&
|
|
|
|
getline(basic_istream<_CharT, _Traits>&& __is,
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>& __str);
|
|
|
|
|
2017-04-19 08:28:44 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2011-07-18 23:51:59 +08:00
|
|
|
|
2018-12-15 02:49:35 +08:00
|
|
|
#if _LIBCPP_STD_VER > 17
|
2020-05-02 19:58:03 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator, class _Up>
|
2018-12-15 02:49:35 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2020-05-02 19:58:03 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
|
|
|
erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
|
|
|
|
auto __old_size = __str.size();
|
|
|
|
__str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end());
|
|
|
|
return __old_size - __str.size();
|
|
|
|
}
|
2018-12-15 02:49:35 +08:00
|
|
|
|
2020-05-02 19:58:03 +08:00
|
|
|
template <class _CharT, class _Traits, class _Allocator, class _Predicate>
|
2018-12-15 02:49:35 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2020-05-02 19:58:03 +08:00
|
|
|
typename basic_string<_CharT, _Traits, _Allocator>::size_type
|
|
|
|
erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
|
|
|
|
_Predicate __pred) {
|
|
|
|
auto __old_size = __str.size();
|
|
|
|
__str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred),
|
|
|
|
__str.end());
|
|
|
|
return __old_size - __str.size();
|
|
|
|
}
|
2018-12-15 02:49:35 +08:00
|
|
|
#endif
|
|
|
|
|
2013-08-24 01:37:05 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
bool
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
return this->data() <= _VSTD::__to_address(__i->base()) &&
|
|
|
|
_VSTD::__to_address(__i->base()) < this->data() + this->size();
|
2013-08-24 01:37:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
bool
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
return this->data() < _VSTD::__to_address(__i->base()) &&
|
|
|
|
_VSTD::__to_address(__i->base()) <= this->data() + this->size();
|
2013-08-24 01:37:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
bool
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
const value_type* __p = _VSTD::__to_address(__i->base()) + __n;
|
2013-08-24 01:37:05 +08:00
|
|
|
return this->data() <= __p && __p <= this->data() + this->size();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
|
|
bool
|
|
|
|
basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
|
|
|
|
{
|
2019-11-17 06:13:26 +08:00
|
|
|
const value_type* __p = _VSTD::__to_address(__i->base()) + __n;
|
2013-08-24 01:37:05 +08:00
|
|
|
return this->data() <= __p && __p < this->data() + this->size();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
|
2019-05-30 00:01:36 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
2013-07-24 01:05:24 +08:00
|
|
|
// Literal suffixes for basic_string [basic.string.literals]
|
2013-10-06 05:18:32 +08:00
|
|
|
inline namespace literals
|
2013-07-24 01:05:24 +08:00
|
|
|
{
|
|
|
|
inline namespace string_literals
|
|
|
|
{
|
2013-08-08 03:39:48 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string<char> operator "" s( const char *__str, size_t __len )
|
|
|
|
{
|
|
|
|
return basic_string<char> (__str, __len);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
|
|
|
|
{
|
|
|
|
return basic_string<wchar_t> (__str, __len);
|
|
|
|
}
|
|
|
|
|
2018-12-11 12:35:44 +08:00
|
|
|
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT
|
|
|
|
{
|
|
|
|
return basic_string<char8_t> (__str, __len);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-08-08 03:39:48 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
|
|
|
|
{
|
|
|
|
return basic_string<char16_t> (__str, __len);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
|
|
|
|
{
|
|
|
|
return basic_string<char32_t> (__str, __len);
|
|
|
|
}
|
2013-07-24 01:05:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
2017-06-01 06:07:49 +08:00
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif // _LIBCPP_STRING
|