2010-05-12 03:42:16 +08:00
|
|
|
// -*- C++ -*-
|
|
|
|
//===------------------------------ vector --------------------------------===//
|
|
|
|
//
|
2010-05-12 05:36:01 +08:00
|
|
|
// The LLVM Compiler Infrastructure
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
2010-11-17 06:09:02 +08:00
|
|
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
|
|
|
// Source Licenses. See LICENSE.TXT for details.
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_VECTOR
|
|
|
|
#define _LIBCPP_VECTOR
|
|
|
|
|
|
|
|
/*
|
|
|
|
vector synopsis
|
|
|
|
|
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class T, class Allocator = allocator<T> >
|
2010-05-12 03:42:16 +08:00
|
|
|
class vector
|
2010-08-22 08:02:43 +08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef T value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef Allocator allocator_type;
|
|
|
|
typedef typename allocator_type::reference reference;
|
|
|
|
typedef typename allocator_type::const_reference const_reference;
|
|
|
|
typedef implementation-defined iterator;
|
|
|
|
typedef implementation-defined const_iterator;
|
|
|
|
typedef typename allocator_type::size_type size_type;
|
|
|
|
typedef typename allocator_type::difference_type difference_type;
|
|
|
|
typedef typename allocator_type::pointer pointer;
|
|
|
|
typedef typename allocator_type::const_pointer const_pointer;
|
|
|
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
|
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
vector()
|
|
|
|
noexcept(is_nothrow_default_constructible<allocator_type>::value);
|
|
|
|
explicit vector(const allocator_type&);
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit vector(size_type n);
|
2013-09-14 08:47:59 +08:00
|
|
|
explicit vector(size_type n, const allocator_type&); // C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
|
|
|
|
template <class InputIterator>
|
|
|
|
vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
|
|
|
|
vector(const vector& x);
|
2011-06-04 03:40:40 +08:00
|
|
|
vector(vector&& x)
|
|
|
|
noexcept(is_nothrow_move_constructible<allocator_type>::value);
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(initializer_list<value_type> il);
|
|
|
|
vector(initializer_list<value_type> il, const allocator_type& a);
|
|
|
|
~vector();
|
|
|
|
vector& operator=(const vector& x);
|
2011-06-04 03:40:40 +08:00
|
|
|
vector& operator=(vector&& x)
|
|
|
|
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
|
2010-05-12 03:42:16 +08:00
|
|
|
vector& operator=(initializer_list<value_type> il);
|
|
|
|
template <class InputIterator>
|
|
|
|
void assign(InputIterator first, InputIterator last);
|
|
|
|
void assign(size_type n, const value_type& u);
|
|
|
|
void assign(initializer_list<value_type> il);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
allocator_type get_allocator() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +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-06-04 03:40:40 +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-06-04 03:40:40 +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-06-04 03:40:40 +08:00
|
|
|
size_type size() const noexcept;
|
|
|
|
size_type max_size() const noexcept;
|
|
|
|
size_type capacity() const noexcept;
|
|
|
|
bool empty() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
void reserve(size_type n);
|
2011-06-04 03:40:40 +08:00
|
|
|
void shrink_to_fit() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
reference operator[](size_type n);
|
|
|
|
const_reference operator[](size_type n) const;
|
|
|
|
reference at(size_type n);
|
|
|
|
const_reference at(size_type n) const;
|
|
|
|
|
|
|
|
reference front();
|
|
|
|
const_reference front() const;
|
|
|
|
reference back();
|
|
|
|
const_reference back() const;
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
value_type* data() noexcept;
|
|
|
|
const value_type* data() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void push_back(const value_type& x);
|
|
|
|
void push_back(value_type&& x);
|
|
|
|
template <class... Args>
|
2017-01-25 07:09:12 +08:00
|
|
|
reference emplace_back(Args&&... args); // reference in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
void pop_back();
|
|
|
|
|
|
|
|
template <class... Args> iterator emplace(const_iterator position, Args&&... args);
|
|
|
|
iterator insert(const_iterator position, const value_type& x);
|
|
|
|
iterator insert(const_iterator position, value_type&& x);
|
|
|
|
iterator insert(const_iterator position, size_type n, const value_type& x);
|
|
|
|
template <class InputIterator>
|
|
|
|
iterator insert(const_iterator position, InputIterator first, InputIterator last);
|
|
|
|
iterator insert(const_iterator position, initializer_list<value_type> il);
|
|
|
|
|
|
|
|
iterator erase(const_iterator position);
|
|
|
|
iterator erase(const_iterator first, const_iterator last);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
void clear() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void resize(size_type sz);
|
|
|
|
void resize(size_type sz, const value_type& c);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
void swap(vector&)
|
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
|
|
|
|
|
|
|
bool __invariants() const;
|
2010-08-22 08:02:43 +08:00
|
|
|
};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class Allocator = allocator<T> >
|
2010-05-12 03:42:16 +08:00
|
|
|
class vector<bool, Allocator>
|
2010-08-22 08:02:43 +08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef bool value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef Allocator allocator_type;
|
|
|
|
typedef implementation-defined iterator;
|
|
|
|
typedef implementation-defined const_iterator;
|
|
|
|
typedef typename allocator_type::size_type size_type;
|
|
|
|
typedef typename allocator_type::difference_type difference_type;
|
|
|
|
typedef iterator pointer;
|
|
|
|
typedef const_iterator const_pointer;
|
|
|
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
|
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
|
|
|
|
|
|
class reference
|
|
|
|
{
|
|
|
|
public:
|
2011-06-04 03:40:40 +08:00
|
|
|
reference(const reference&) noexcept;
|
|
|
|
operator bool() const noexcept;
|
|
|
|
reference& operator=(const bool x) noexcept;
|
|
|
|
reference& operator=(const reference& x) noexcept;
|
|
|
|
iterator operator&() const noexcept;
|
|
|
|
void flip() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class const_reference
|
|
|
|
{
|
|
|
|
public:
|
2011-06-04 03:40:40 +08:00
|
|
|
const_reference(const reference&) noexcept;
|
|
|
|
operator bool() const noexcept;
|
|
|
|
const_iterator operator&() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
vector()
|
|
|
|
noexcept(is_nothrow_default_constructible<allocator_type>::value);
|
2011-09-03 04:42:31 +08:00
|
|
|
explicit vector(const allocator_type&);
|
2013-09-14 08:47:59 +08:00
|
|
|
explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14
|
|
|
|
vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class InputIterator>
|
|
|
|
vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
|
|
|
|
vector(const vector& x);
|
2011-06-04 03:40:40 +08:00
|
|
|
vector(vector&& x)
|
|
|
|
noexcept(is_nothrow_move_constructible<allocator_type>::value);
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(initializer_list<value_type> il);
|
|
|
|
vector(initializer_list<value_type> il, const allocator_type& a);
|
|
|
|
~vector();
|
|
|
|
vector& operator=(const vector& x);
|
2011-06-04 03:40:40 +08:00
|
|
|
vector& operator=(vector&& x)
|
|
|
|
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
|
2010-05-12 03:42:16 +08:00
|
|
|
vector& operator=(initializer_list<value_type> il);
|
|
|
|
template <class InputIterator>
|
|
|
|
void assign(InputIterator first, InputIterator last);
|
|
|
|
void assign(size_type n, const value_type& u);
|
|
|
|
void assign(initializer_list<value_type> il);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
allocator_type get_allocator() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +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-06-04 03:40:40 +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-06-04 03:40:40 +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-06-04 03:40:40 +08:00
|
|
|
size_type size() const noexcept;
|
|
|
|
size_type max_size() const noexcept;
|
|
|
|
size_type capacity() const noexcept;
|
|
|
|
bool empty() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
void reserve(size_type n);
|
2011-06-04 03:40:40 +08:00
|
|
|
void shrink_to_fit() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
reference operator[](size_type n);
|
|
|
|
const_reference operator[](size_type n) const;
|
|
|
|
reference at(size_type n);
|
|
|
|
const_reference at(size_type n) const;
|
|
|
|
|
|
|
|
reference front();
|
|
|
|
const_reference front() const;
|
|
|
|
reference back();
|
|
|
|
const_reference back() const;
|
|
|
|
|
|
|
|
void push_back(const value_type& x);
|
2017-01-25 07:09:12 +08:00
|
|
|
template <class... Args> reference emplace_back(Args&&... args); // C++14; reference in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
void pop_back();
|
|
|
|
|
2013-08-14 07:54:12 +08:00
|
|
|
template <class... Args> iterator emplace(const_iterator position, Args&&... args); // C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator position, const value_type& x);
|
|
|
|
iterator insert(const_iterator position, size_type n, const value_type& x);
|
|
|
|
template <class InputIterator>
|
|
|
|
iterator insert(const_iterator position, InputIterator first, InputIterator last);
|
|
|
|
iterator insert(const_iterator position, initializer_list<value_type> il);
|
|
|
|
|
|
|
|
iterator erase(const_iterator position);
|
|
|
|
iterator erase(const_iterator first, const_iterator last);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
void clear() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void resize(size_type sz);
|
|
|
|
void resize(size_type sz, value_type x);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
void swap(vector&)
|
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
|
2011-06-04 03:40:40 +08:00
|
|
|
void flip() noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
bool __invariants() const;
|
2010-08-22 08:02:43 +08:00
|
|
|
};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-05-22 05:30:12 +08:00
|
|
|
template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
|
|
|
vector(InputIterator, InputIterator, Allocator = Allocator())
|
|
|
|
-> vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class Allocator> struct hash<std::vector<bool, Allocator>>;
|
|
|
|
|
|
|
|
template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
template <class T, class Allocator>
|
|
|
|
void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
|
|
|
|
noexcept(noexcept(x.swap(y)));
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <__config>
|
2016-02-20 08:19:45 +08:00
|
|
|
#include <iosfwd> // for forward declaration of vector
|
2010-05-12 03:42:16 +08:00
|
|
|
#include <__bit_reference>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <climits>
|
|
|
|
#include <limits>
|
|
|
|
#include <initializer_list>
|
|
|
|
#include <memory>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cstring>
|
2018-09-13 03:41:40 +08:00
|
|
|
#include <version>
|
2010-05-12 03:42:16 +08:00
|
|
|
#include <__split_buffer>
|
|
|
|
#include <__functional_base>
|
|
|
|
|
2014-08-11 07:53:08 +08:00
|
|
|
#include <__debug>
|
Ok, 3 major changes for debug mode in one commit:
1. I had been detecting and trapping iterator == and \!= among iterators
in different containers as an error. But the trapping itself is actually
an error.
Consider:
#include <iostream>
#include <vector>
#include <algorithm>
template <class C>
void
display(const C& c)
{
std::cout << "{";
bool first = true;
for (const auto& x : c)
{
if (\!first)
std::cout << ", ";
first = false;
std::cout << x;
}
std::cout << "}\n";
}
int
main()
{
typedef std::vector<int> V;
V v1 = {1, 3, 5};
V v2 = {2, 4, 6};
display(v1);
display(v2);
V::iterator i = std::find(v1.begin(), v1.end(), 1);
V::iterator j = std::find(v2.begin(), v2.end(), 2);
if (*i == *j)
i = j; // perfectly legal
// ...
if (i \!= j) // the only way to check
v2.push_back(*i);
display(v1);
display(v2);
}
It is legal to assign an iterator from one container to another of the
same type. This is required to work. One might want to test whether or
not such an assignment had been made. The way one performs such a check
is using the iterator's ==, \!= operator. This is a logical and necessary
function and does not constitute an error.
2. I had a header circular dependence bug when _LIBCPP_DEBUG2 is defined.
This caused a problem in several of the libc++ tests.
Fixed.
3. There is a serious problem when _LIBCPP_DEBUG2=1 at the moment in that
std::basic_string is inoperable. std::basic_string uses __wrap_iterator
to implement its iterators. __wrap_iterator has been rigged up in debug
mode to support vector. But string hasn't been rigged up yet. This means
that one gets false positives when using std::string in debug mode. I've
upped std::string's priority in www/debug_mode.html.
llvm-svn: 187636
2013-08-02 08:26:35 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
|
template <bool>
|
|
|
|
class __vector_base_common
|
|
|
|
{
|
|
|
|
protected:
|
2018-07-12 07:14:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY __vector_base_common() {}
|
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
|
|
|
|
__vector_base_common<__b>::__throw_length_error() const
|
|
|
|
{
|
2016-08-25 23:09:01 +08:00
|
|
|
_VSTD::__throw_length_error("vector");
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <bool __b>
|
|
|
|
void
|
|
|
|
__vector_base_common<__b>::__throw_out_of_range() const
|
|
|
|
{
|
2016-08-25 23:09:01 +08:00
|
|
|
_VSTD::__throw_out_of_range("vector");
|
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 __vector_base_common<true>)
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
class __vector_base
|
|
|
|
: protected __vector_base_common<true>
|
|
|
|
{
|
2018-05-22 05:30:12 +08:00
|
|
|
public:
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef _Allocator allocator_type;
|
|
|
|
typedef allocator_traits<allocator_type> __alloc_traits;
|
2018-05-22 05:30:12 +08:00
|
|
|
typedef typename __alloc_traits::size_type size_type;
|
|
|
|
protected:
|
|
|
|
typedef _Tp value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef value_type& reference;
|
|
|
|
typedef const value_type& const_reference;
|
|
|
|
typedef typename __alloc_traits::difference_type difference_type;
|
|
|
|
typedef typename __alloc_traits::pointer pointer;
|
|
|
|
typedef typename __alloc_traits::const_pointer const_pointer;
|
|
|
|
typedef pointer iterator;
|
|
|
|
typedef const_pointer const_iterator;
|
|
|
|
|
|
|
|
pointer __begin_;
|
|
|
|
pointer __end_;
|
|
|
|
__compressed_pair<pointer, allocator_type> __end_cap_;
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
allocator_type& __alloc() _NOEXCEPT
|
|
|
|
{return __end_cap_.second();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const allocator_type& __alloc() const _NOEXCEPT
|
|
|
|
{return __end_cap_.second();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pointer& __end_cap() _NOEXCEPT
|
|
|
|
{return __end_cap_.first();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const pointer& __end_cap() const _NOEXCEPT
|
|
|
|
{return __end_cap_.first();}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__vector_base()
|
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a);
|
2018-06-06 06:32:52 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT;
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
~__vector_base();
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void clear() _NOEXCEPT {__destruct_at_end(__begin_);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type capacity() const _NOEXCEPT
|
|
|
|
{return static_cast<size_type>(__end_cap() - __begin_);}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-28 03:35:32 +08:00
|
|
|
void __destruct_at_end(pointer __new_last) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __copy_assign_alloc(const __vector_base& __c)
|
|
|
|
{__copy_assign_alloc(__c, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_copy_assignment::value>());}
|
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __move_assign_alloc(__vector_base& __c)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(
|
|
|
|
!__alloc_traits::propagate_on_container_move_assignment::value ||
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{__move_assign_alloc(__c, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_move_assignment::value>());}
|
|
|
|
private:
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __copy_assign_alloc(const __vector_base& __c, true_type)
|
|
|
|
{
|
|
|
|
if (__alloc() != __c.__alloc())
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
|
|
|
|
__begin_ = __end_ = __end_cap() = nullptr;
|
|
|
|
}
|
|
|
|
__alloc() = __c.__alloc();
|
|
|
|
}
|
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-02 04:21:04 +08:00
|
|
|
void __copy_assign_alloc(const __vector_base&, false_type)
|
2010-05-12 03:42:16 +08:00
|
|
|
{}
|
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-09-03 04:42:31 +08:00
|
|
|
void __move_assign_alloc(__vector_base& __c, true_type)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
__alloc() = _VSTD::move(__c.__alloc());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-02 04:21:04 +08:00
|
|
|
void __move_assign_alloc(__vector_base&, false_type)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
2013-06-28 03:35:32 +08:00
|
|
|
__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
[libcxx] Improve code generation for vector::clear().
Summary:
By manipulating a local variable in the loop, when the loop can
be optimized away (due to no non-trivial destructors), this lets
it be fully optimized away and we modify the __end_ separately.
This results in a substantial improvement in the generated code.
Prior to this change, this would be generated (on x86_64):
movq (%rdi), %rdx
movq 8(%rdi), %rcx
cmpq %rdx, %rcx
je LBB2_2
leaq -12(%rcx), %rax
subq %rdx, %rax
movabsq $-6148914691236517205, %rdx ## imm = 0xAAAAAAAAAAAAAAAB
mulq %rdx
shrq $3, %rdx
notq %rdx
leaq (%rdx,%rdx,2), %rax
leaq (%rcx,%rax,4), %rax
movq %rax, 8(%rdi)
And after:
movq (%rdi), %rax
movq %rax, 8(%rdi)
This brings this in line with what other implementations do.
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D25241
llvm-svn: 298601
2017-03-23 22:39:23 +08:00
|
|
|
pointer __soon_to_be_end = __end_;
|
|
|
|
while (__new_last != __soon_to_be_end)
|
|
|
|
__alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end));
|
|
|
|
__end_ = __new_last;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
__vector_base<_Tp, _Allocator>::__vector_base()
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
|
|
|
__end_(nullptr),
|
|
|
|
__end_cap_(nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
__vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
|
|
|
__end_(nullptr),
|
|
|
|
__end_cap_(nullptr, __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-06-06 06:32:52 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
__vector_base<_Tp, _Allocator>::__vector_base(allocator_type&& __a) _NOEXCEPT
|
|
|
|
: __begin_(nullptr),
|
|
|
|
__end_(nullptr),
|
|
|
|
__end_cap_(nullptr, std::move(__a)) {}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
__vector_base<_Tp, _Allocator>::~__vector_base()
|
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (__begin_ != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
clear();
|
|
|
|
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-20 08:19:45 +08:00
|
|
|
template <class _Tp, class _Allocator /* = allocator<_Tp> */>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS vector
|
2010-05-12 03:42:16 +08:00
|
|
|
: private __vector_base<_Tp, _Allocator>
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
typedef __vector_base<_Tp, _Allocator> __base;
|
2014-05-08 22:14:06 +08:00
|
|
|
typedef allocator<_Tp> __default_allocator_type;
|
2010-08-22 08:02:43 +08:00
|
|
|
public:
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef vector __self;
|
2010-08-22 08:02:43 +08:00
|
|
|
typedef _Tp value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef _Allocator allocator_type;
|
|
|
|
typedef typename __base::__alloc_traits __alloc_traits;
|
|
|
|
typedef typename __base::reference reference;
|
|
|
|
typedef typename __base::const_reference const_reference;
|
|
|
|
typedef typename __base::size_type size_type;
|
|
|
|
typedef typename __base::difference_type difference_type;
|
|
|
|
typedef typename __base::pointer pointer;
|
|
|
|
typedef typename __base::const_pointer const_pointer;
|
|
|
|
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
|
|
|
|
2013-03-27 03:04:56 +08:00
|
|
|
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
|
|
|
|
"Allocator::value_type must be same type as value_type");
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2015-06-04 10:05:41 +08:00
|
|
|
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
|
2015-06-04 08:10:20 +08:00
|
|
|
#if _LIBCPP_STD_VER <= 14
|
|
|
|
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
|
|
|
|
#else
|
|
|
|
_NOEXCEPT
|
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
explicit vector(size_type __n);
|
2013-09-14 08:47:59 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
explicit vector(size_type __n, const allocator_type& __a);
|
|
|
|
#endif
|
2018-05-22 05:30:12 +08:00
|
|
|
vector(size_type __n, const value_type& __x);
|
|
|
|
vector(size_type __n, const value_type& __x, const allocator_type& __a);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _InputIterator>
|
2013-09-22 05:13:54 +08:00
|
|
|
vector(_InputIterator __first,
|
2010-05-12 03:42:16 +08:00
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
2013-09-22 05:13:54 +08:00
|
|
|
typename iterator_traits<_InputIterator>::reference>::value,
|
|
|
|
_InputIterator>::type __last);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _InputIterator>
|
|
|
|
vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
|
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _ForwardIterator>
|
2013-09-22 05:13:54 +08:00
|
|
|
vector(_ForwardIterator __first,
|
2013-03-29 01:44:32 +08:00
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
2013-09-22 05:13:54 +08:00
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value,
|
|
|
|
_ForwardIterator>::type __last);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _ForwardIterator>
|
|
|
|
vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
|
2013-03-29 01:44:32 +08:00
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-09-15 02:33:51 +08:00
|
|
|
~vector()
|
|
|
|
{
|
2018-09-07 23:47:59 +08:00
|
|
|
__annotate_delete();
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__erase_c(this);
|
2010-05-12 03:42:16 +08:00
|
|
|
#endif
|
2018-09-07 23:47:59 +08:00
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
vector(const vector& __x);
|
|
|
|
vector(const vector& __x, const allocator_type& __a);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector& operator=(const vector& __x);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
vector(initializer_list<value_type> __il);
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
vector(initializer_list<value_type> __il, const allocator_type& __a);
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
vector(vector&& __x)
|
2015-07-14 22:46:32 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
_NOEXCEPT;
|
|
|
|
#else
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
|
2015-07-14 22:46:32 +08:00
|
|
|
#endif
|
2017-04-16 10:40:45 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(vector&& __x, const allocator_type& __a);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
vector& operator=(vector&& __x)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
|
2017-04-16 10:40:45 +08:00
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector& operator=(initializer_list<value_type> __il)
|
|
|
|
{assign(__il.begin(), __il.end()); return *this;}
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_InputIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
>::type
|
|
|
|
assign(_InputIterator __first, _InputIterator __last);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
2013-03-29 01:44:32 +08:00
|
|
|
__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
>::type
|
|
|
|
assign(_ForwardIterator __first, _ForwardIterator __last);
|
|
|
|
|
|
|
|
void assign(size_type __n, const_reference __u);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void assign(initializer_list<value_type> __il)
|
|
|
|
{assign(__il.begin(), __il.end());}
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
allocator_type get_allocator() const _NOEXCEPT
|
|
|
|
{return this->__alloc();}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +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-06-04 03:40:40 +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-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type size() const _NOEXCEPT
|
|
|
|
{return static_cast<size_type>(this->__end_ - this->__begin_);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type capacity() const _NOEXCEPT
|
|
|
|
{return __base::capacity();}
|
2017-11-15 13:51:26 +08:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
bool empty() const _NOEXCEPT
|
|
|
|
{return this->__begin_ == this->__end_;}
|
|
|
|
size_type max_size() const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
void reserve(size_type __n);
|
2011-06-04 03:40:40 +08:00
|
|
|
void shrink_to_fit() _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n);
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const;
|
|
|
|
reference at(size_type __n);
|
|
|
|
const_reference at(size_type __n) const;
|
|
|
|
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY reference front()
|
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(!empty(), "front() called for empty vector");
|
|
|
|
return *this->__begin_;
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference front() const
|
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(!empty(), "front() called for empty vector");
|
|
|
|
return *this->__begin_;
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference back()
|
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(!empty(), "back() called for empty vector");
|
|
|
|
return *(this->__end_ - 1);
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference back() const
|
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(!empty(), "back() called for empty vector");
|
|
|
|
return *(this->__end_ - 1);
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
value_type* data() _NOEXCEPT
|
2011-07-01 05:18:19 +08:00
|
|
|
{return _VSTD::__to_raw_pointer(this->__begin_);}
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const value_type* data() const _NOEXCEPT
|
2011-07-01 05:18:19 +08:00
|
|
|
{return _VSTD::__to_raw_pointer(this->__begin_);}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-10-17 21:03:17 +08:00
|
|
|
#ifdef _LIBCPP_CXX03_LANG
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __emplace_back(const value_type& __x) { push_back(__x); }
|
|
|
|
#else
|
|
|
|
template <class _Arg>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __emplace_back(_Arg&& __arg) {
|
|
|
|
emplace_back(_VSTD::forward<_Arg>(__arg));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2012-02-15 08:41:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class... _Args>
|
2015-11-07 09:22:13 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-01-25 07:09:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 11:20:17 +08:00
|
|
|
reference emplace_back(_Args&&... __args);
|
2017-01-25 07:09:12 +08:00
|
|
|
#else
|
|
|
|
void emplace_back(_Args&&... __args);
|
|
|
|
#endif
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
|
|
|
|
2015-11-07 09:22:13 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void pop_back();
|
|
|
|
|
|
|
|
iterator insert(const_iterator __position, const_reference __x);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __position, value_type&& __x);
|
|
|
|
template <class... _Args>
|
|
|
|
iterator emplace(const_iterator __position, _Args&&... __args);
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __position, size_type __n, const_reference __x);
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_InputIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator
|
|
|
|
>::type
|
|
|
|
insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
2013-03-29 01:44:32 +08:00
|
|
|
__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator
|
|
|
|
>::type
|
|
|
|
insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __position, initializer_list<value_type> __il)
|
|
|
|
{return insert(__position, __il.begin(), __il.end());}
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position);
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator erase(const_iterator __first, const_iterator __last);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void clear() _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2014-05-08 22:14:06 +08:00
|
|
|
size_type __old_size = size();
|
2011-09-15 02:33:51 +08:00
|
|
|
__base::clear();
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_shrink(__old_size);
|
2011-09-15 02:33:51 +08:00
|
|
|
__invalidate_all_iterators();
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void resize(size_type __sz);
|
|
|
|
void resize(size_type __sz, const_reference __x);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
void swap(vector&)
|
2015-07-14 04:04:56 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
2016-12-28 14:06:09 +08:00
|
|
|
_NOEXCEPT_DEBUG;
|
2015-07-14 04:04:56 +08:00
|
|
|
#else
|
2016-12-28 14:06:09 +08:00
|
|
|
_NOEXCEPT_DEBUG_(!__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
|
|
|
|
|
|
|
bool __invariants() const;
|
|
|
|
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
private:
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
2016-12-28 14:06:09 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last);
|
2018-05-23 00:20:28 +08:00
|
|
|
void __vallocate(size_type __n);
|
|
|
|
void __vdeallocate() _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
|
2011-01-05 03:53:31 +08:00
|
|
|
void __construct_at_end(size_type __n);
|
2015-11-07 09:22:13 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __construct_at_end(size_type __n, const_reference __x);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
void __append(size_type __n);
|
|
|
|
void __append(size_type __n, const_reference __x);
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
iterator __make_iter(pointer __p) _NOEXCEPT;
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
const_iterator __make_iter(const_pointer __p) const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
void __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
|
|
|
|
pointer __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
|
|
|
|
void __move_range(pointer __from_s, pointer __from_e, pointer __to);
|
2011-06-04 03:40:40 +08:00
|
|
|
void __move_assign(vector& __c, true_type)
|
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
|
2015-08-19 02:57:00 +08:00
|
|
|
void __move_assign(vector& __c, false_type)
|
|
|
|
_NOEXCEPT_(__alloc_traits::is_always_equal::value);
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-06-28 03:35:32 +08:00
|
|
|
void __destruct_at_end(pointer __new_last) _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2016-12-28 14:06:09 +08:00
|
|
|
__invalidate_iterators_past(__new_last);
|
2014-05-08 22:14:06 +08:00
|
|
|
size_type __old_size = size();
|
2011-09-15 02:33:51 +08:00
|
|
|
__base::__destruct_at_end(__new_last);
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_shrink(__old_size);
|
2011-09-15 02:33:51 +08:00
|
|
|
}
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
|
|
template <class _Up> void __push_back_slow_path(_Up&& __x);
|
|
|
|
|
2012-02-26 23:30:12 +08:00
|
|
|
template <class... _Args>
|
2017-04-16 10:40:45 +08:00
|
|
|
void __emplace_back_slow_path(_Args&&... __args);
|
|
|
|
#else
|
|
|
|
template <class _Up> void __push_back_slow_path(_Up& __x);
|
2012-02-26 23:30:12 +08:00
|
|
|
#endif
|
2017-04-16 10:40:45 +08:00
|
|
|
|
2014-05-08 22:14:06 +08:00
|
|
|
// The following functions are no-ops outside of AddressSanitizer mode.
|
|
|
|
// We call annotatations only for the default Allocator because other allocators
|
|
|
|
// may not meet the AddressSanitizer alignment constraints.
|
|
|
|
// See the documentation for __sanitizer_annotate_contiguous_container for more details.
|
|
|
|
#ifndef _LIBCPP_HAS_NO_ASAN
|
2016-12-24 07:37:52 +08:00
|
|
|
void __annotate_contiguous_container(const void *__beg, const void *__end,
|
|
|
|
const void *__old_mid,
|
|
|
|
const void *__new_mid) const
|
|
|
|
{
|
|
|
|
|
2014-05-08 22:14:06 +08:00
|
|
|
if (__beg && is_same<allocator_type, __default_allocator_type>::value)
|
|
|
|
__sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
|
|
|
|
}
|
2016-12-24 07:37:52 +08:00
|
|
|
#else
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __annotate_contiguous_container(const void*, const void*, const void*,
|
|
|
|
const void*) const {}
|
|
|
|
#endif
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __annotate_new(size_type __current_size) const {
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_contiguous_container(data(), data() + capacity(),
|
|
|
|
data() + capacity(), data() + __current_size);
|
|
|
|
}
|
2016-12-24 07:37:52 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void __annotate_delete() const {
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_contiguous_container(data(), data() + capacity(),
|
|
|
|
data() + size(), data() + capacity());
|
|
|
|
}
|
2016-12-24 07:37:52 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2014-09-03 07:43:38 +08:00
|
|
|
void __annotate_increase(size_type __n) const
|
2014-05-08 22:14:06 +08:00
|
|
|
{
|
|
|
|
__annotate_contiguous_container(data(), data() + capacity(),
|
|
|
|
data() + size(), data() + size() + __n);
|
|
|
|
}
|
2016-12-24 07:37:52 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2014-09-03 07:43:38 +08:00
|
|
|
void __annotate_shrink(size_type __old_size) const
|
2014-05-08 22:14:06 +08:00
|
|
|
{
|
|
|
|
__annotate_contiguous_container(data(), data() + capacity(),
|
|
|
|
data() + __old_size, data() + size());
|
|
|
|
}
|
2014-09-04 05:37:43 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_ASAN
|
2014-09-03 07:43:38 +08:00
|
|
|
// The annotation for size increase should happen before the actual increase,
|
|
|
|
// but if an exception is thrown after that the annotation has to be undone.
|
|
|
|
struct __RAII_IncreaseAnnotator {
|
|
|
|
__RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)
|
2015-03-10 08:25:20 +08:00
|
|
|
: __commit(false), __v(__v), __old_size(__v.size() + __n) {
|
2014-09-03 07:43:38 +08:00
|
|
|
__v.__annotate_increase(__n);
|
|
|
|
}
|
|
|
|
void __done() { __commit = true; }
|
|
|
|
~__RAII_IncreaseAnnotator() {
|
|
|
|
if (__commit) return;
|
2015-03-10 08:25:20 +08:00
|
|
|
__v.__annotate_shrink(__old_size);
|
2014-09-03 07:43:38 +08:00
|
|
|
}
|
|
|
|
bool __commit;
|
|
|
|
const vector &__v;
|
2015-03-10 08:25:20 +08:00
|
|
|
size_type __old_size;
|
2014-09-03 07:43:38 +08:00
|
|
|
};
|
2014-09-04 05:37:43 +08:00
|
|
|
#else
|
|
|
|
struct __RAII_IncreaseAnnotator {
|
2016-12-24 07:37:52 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__RAII_IncreaseAnnotator(const vector &, size_type = 1) {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY void __done() {}
|
2014-09-04 05:37:43 +08:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
2018-05-22 05:30:12 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
|
|
|
template<class _InputIterator,
|
|
|
|
class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
|
|
|
|
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
|
|
|
>
|
|
|
|
vector(_InputIterator, _InputIterator)
|
|
|
|
-> vector<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
|
|
|
|
|
|
|
template<class _InputIterator,
|
|
|
|
class _Alloc,
|
|
|
|
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
|
|
|
>
|
|
|
|
vector(_InputIterator, _InputIterator, _Alloc)
|
|
|
|
-> vector<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
|
|
|
|
{
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_delete();
|
2012-02-15 08:41:34 +08:00
|
|
|
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(this->__begin_, __v.__begin_);
|
|
|
|
_VSTD::swap(this->__end_, __v.__end_);
|
|
|
|
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
2010-05-12 03:42:16 +08:00
|
|
|
__v.__first_ = __v.__begin_;
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_new(size());
|
2010-05-12 03:42:16 +08:00
|
|
|
__invalidate_all_iterators();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename vector<_Tp, _Allocator>::pointer
|
|
|
|
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p)
|
|
|
|
{
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_delete();
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __r = __v.__begin_;
|
2012-02-15 08:41:34 +08:00
|
|
|
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);
|
|
|
|
__alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(this->__begin_, __v.__begin_);
|
|
|
|
_VSTD::swap(this->__end_, __v.__end_);
|
|
|
|
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
2010-05-12 03:42:16 +08:00
|
|
|
__v.__first_ = __v.__begin_;
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_new(size());
|
2010-05-12 03:42:16 +08:00
|
|
|
__invalidate_all_iterators();
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allocate space for __n objects
|
|
|
|
// throws length_error if __n > max_size()
|
|
|
|
// throws (probably bad_alloc) if memory run out
|
|
|
|
// Precondition: __begin_ == __end_ == __end_cap() == 0
|
|
|
|
// Precondition: __n > 0
|
|
|
|
// Postcondition: capacity() == __n
|
|
|
|
// Postcondition: size() == 0
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
2018-05-23 00:20:28 +08:00
|
|
|
vector<_Tp, _Allocator>::__vallocate(size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__n > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);
|
|
|
|
this->__end_cap() = this->__begin_ + __n;
|
2014-05-08 22:14:06 +08:00
|
|
|
__annotate_new(0);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
2018-05-23 00:20:28 +08:00
|
|
|
vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (this->__begin_ != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
clear();
|
|
|
|
__alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
|
2013-06-28 03:35:32 +08:00
|
|
|
this->__begin_ = this->__end_ = this->__end_cap() = nullptr;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename vector<_Tp, _Allocator>::size_type
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::max_size() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2016-11-23 09:18:56 +08:00
|
|
|
return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()),
|
|
|
|
numeric_limits<difference_type>::max());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Precondition: __new_size > capacity()
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::size_type
|
|
|
|
vector<_Tp, _Allocator>::__recommend(size_type __new_size) const
|
|
|
|
{
|
|
|
|
const size_type __ms = max_size();
|
|
|
|
if (__new_size > __ms)
|
|
|
|
this->__throw_length_error();
|
|
|
|
const size_type __cap = capacity();
|
|
|
|
if (__cap >= __ms / 2)
|
|
|
|
return __ms;
|
2011-07-30 07:31:58 +08:00
|
|
|
return _VSTD::max<size_type>(2*__cap, __new_size);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Default constructs __n objects starting at __end_
|
|
|
|
// throws if construction throws
|
|
|
|
// Precondition: __n > 0
|
|
|
|
// Precondition: size() + __n <= capacity()
|
|
|
|
// Postcondition: size() == size() + __n
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
do
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2011-07-01 05:18:19 +08:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
--__n;
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
} while (__n > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy constructs __n objects starting at __end_ from __x
|
|
|
|
// throws if construction throws
|
|
|
|
// Precondition: __n > 0
|
|
|
|
// Precondition: size() + __n <= capacity()
|
|
|
|
// Postcondition: size() == old size() + __n
|
|
|
|
// Postcondition: [i] == __x for all i in [size() - __n, __n)
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 09:22:13 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
do
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2011-07-01 05:18:19 +08:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
--__n;
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
} while (__n > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this, __n);
|
|
|
|
__alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_);
|
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Default constructs __n objects starting at __end_
|
|
|
|
// throws if construction throws
|
|
|
|
// Postcondition: size() == size() + __n
|
2011-06-04 03:40:40 +08:00
|
|
|
// Exception safety: strong.
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__append(size_type __n)
|
|
|
|
{
|
|
|
|
if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n)
|
|
|
|
this->__construct_at_end(__n);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);
|
|
|
|
__v.__construct_at_end(__n);
|
|
|
|
__swap_out_circular_buffer(__v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default constructs __n objects starting at __end_
|
|
|
|
// throws if construction throws
|
|
|
|
// Postcondition: size() == size() + __n
|
2011-06-04 03:40:40 +08:00
|
|
|
// Exception safety: strong.
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x)
|
|
|
|
{
|
|
|
|
if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n)
|
|
|
|
this->__construct_at_end(__n, __x);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);
|
|
|
|
__v.__construct_at_end(__n, __x);
|
|
|
|
__swap_out_circular_buffer(__v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
vector<_Tp, _Allocator>::vector(size_type __n)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-14 08:47:59 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
|
|
|
|
: __base(__a)
|
|
|
|
{
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2013-09-14 08:47:59 +08:00
|
|
|
__construct_at_end(__n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2018-05-22 05:30:12 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n, __x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2018-05-22 05:30:12 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
|
2010-05-12 03:42:16 +08:00
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n, __x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIterator>
|
2013-09-22 05:13:54 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(_InputIterator __first,
|
2010-05-12 03:42:16 +08:00
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
2013-09-22 05:13:54 +08:00
|
|
|
typename iterator_traits<_InputIterator>::reference>::value,
|
|
|
|
_InputIterator>::type __last)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2011-09-17 02:41:29 +08:00
|
|
|
for (; __first != __last; ++__first)
|
2017-10-17 21:03:17 +08:00
|
|
|
__emplace_back(*__first);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
|
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_InputIterator>::reference>::value>::type*)
|
2010-05-12 03:42:16 +08:00
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2011-09-17 02:41:29 +08:00
|
|
|
for (; __first != __last; ++__first)
|
2017-10-17 21:03:17 +08:00
|
|
|
__emplace_back(*__first);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
2013-09-22 05:13:54 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(_ForwardIterator __first,
|
2013-03-29 01:44:32 +08:00
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
2013-09-22 05:13:54 +08:00
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value,
|
|
|
|
_ForwardIterator>::type __last)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
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 > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__first, __last, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
|
2013-03-29 01:44:32 +08:00
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
value_type,
|
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
|
2010-05-12 03:42:16 +08:00
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
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 > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__first, __last, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
vector<_Tp, _Allocator>::vector(const vector& __x)
|
|
|
|
: __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc()))
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n = __x.size();
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__x.__begin_, __x.__end_, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a)
|
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
size_type __n = __x.size();
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__x.__begin_, __x.__end_, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(vector&& __x)
|
2015-07-14 22:46:32 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
_NOEXCEPT
|
|
|
|
#else
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
2015-07-14 22:46:32 +08:00
|
|
|
#endif
|
2011-07-01 05:18:19 +08:00
|
|
|
: __base(_VSTD::move(__x.__alloc()))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__insert_c(this);
|
2011-09-20 00:34:29 +08:00
|
|
|
__get_db()->swap(this, &__x);
|
2011-09-15 02:33:51 +08:00
|
|
|
#endif
|
2011-09-17 02:41:29 +08:00
|
|
|
this->__begin_ = __x.__begin_;
|
|
|
|
this->__end_ = __x.__end_;
|
|
|
|
this->__end_cap() = __x.__end_cap();
|
2013-06-28 03:35:32 +08:00
|
|
|
__x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)
|
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__a == __x.__alloc())
|
|
|
|
{
|
|
|
|
this->__begin_ = __x.__begin_;
|
|
|
|
this->__end_ = __x.__end_;
|
|
|
|
this->__end_cap() = __x.__end_cap();
|
|
|
|
__x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
|
2011-09-20 00:34:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->swap(this, &__x);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-11-30 02:15:50 +08:00
|
|
|
typedef move_iterator<iterator> _Ip;
|
|
|
|
assign(_Ip(__x.begin()), _Ip(__x.end()));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__il.size() > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__il.size());
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__il.begin(), __il.end(), __il.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
|
|
|
|
: __base(__a)
|
|
|
|
{
|
2011-09-17 02:41:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_c(this);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__il.size() > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__il.size());
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__il.begin(), __il.end(), __il.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>&
|
|
|
|
vector<_Tp, _Allocator>::operator=(vector&& __x)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__move_assign(__x, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_move_assignment::value>());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_(__alloc_traits::is_always_equal::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__base::__alloc() != __c.__alloc())
|
|
|
|
{
|
2011-11-30 02:15:50 +08:00
|
|
|
typedef move_iterator<iterator> _Ip;
|
|
|
|
assign(_Ip(__c.begin()), _Ip(__c.end()));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
__move_assign(__c, true_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
2014-07-21 23:11:13 +08:00
|
|
|
__base::__move_assign_alloc(__c); // this can throw
|
2010-05-12 03:42:16 +08:00
|
|
|
this->__begin_ = __c.__begin_;
|
|
|
|
this->__end_ = __c.__end_;
|
|
|
|
this->__end_cap() = __c.__end_cap();
|
|
|
|
__c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
|
2011-09-20 00:34:29 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->swap(this, &__c);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>&
|
|
|
|
vector<_Tp, _Allocator>::operator=(const vector& __x)
|
|
|
|
{
|
|
|
|
if (this != &__x)
|
|
|
|
{
|
|
|
|
__base::__copy_assign_alloc(__x);
|
|
|
|
assign(__x.__begin_, __x.__end_);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
_Tp,
|
|
|
|
typename iterator_traits<_InputIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
>::type
|
|
|
|
vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
for (; __first != __last; ++__first)
|
2017-10-17 21:03:17 +08:00
|
|
|
__emplace_back(*__first);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
2013-03-29 01:44:32 +08:00
|
|
|
__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
_Tp,
|
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
>::type
|
|
|
|
vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
size_type __new_size = static_cast<size_type>(_VSTD::distance(__first, __last));
|
|
|
|
if (__new_size <= capacity())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
_ForwardIterator __mid = __last;
|
|
|
|
bool __growing = false;
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
if (__new_size > size())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__growing = true;
|
|
|
|
__mid = __first;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::advance(__mid, size());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
pointer __m = _VSTD::copy(__first, __mid, this->__begin_);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__growing)
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__mid, __last, __new_size - size());
|
2010-05-12 03:42:16 +08:00
|
|
|
else
|
|
|
|
this->__destruct_at_end(__m);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
|
|
|
__vallocate(__recommend(__new_size));
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
__construct_at_end(__first, __last, __new_size);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2016-12-28 14:06:09 +08:00
|
|
|
__invalidate_all_iterators();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
|
|
|
|
{
|
|
|
|
if (__n <= capacity())
|
|
|
|
{
|
|
|
|
size_type __s = size();
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::fill_n(this->__begin_, _VSTD::min(__n, __s), __u);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n > __s)
|
|
|
|
__construct_at_end(__n - __s, __u);
|
|
|
|
else
|
2010-05-25 01:49:41 +08:00
|
|
|
this->__destruct_at_end(this->__begin_ + __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
|
|
|
__vallocate(__recommend(static_cast<size_type>(__n)));
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n, __u);
|
|
|
|
}
|
2016-12-28 14:06:09 +08:00
|
|
|
__invalidate_all_iterators();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2010-05-12 03:42:16 +08:00
|
|
|
return iterator(this, __p);
|
|
|
|
#else
|
|
|
|
return iterator(__p);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::const_iterator
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2010-05-12 03:42:16 +08:00
|
|
|
return const_iterator(this, __p);
|
|
|
|
#else
|
|
|
|
return const_iterator(__p);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::begin() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __make_iter(this->__begin_);
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::const_iterator
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::begin() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __make_iter(this->__begin_);
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::end() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __make_iter(this->__end_);
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::const_iterator
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::end() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __make_iter(this->__end_);
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::reference
|
|
|
|
vector<_Tp, _Allocator>::operator[](size_type __n)
|
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
|
2010-05-12 03:42:16 +08:00
|
|
|
return this->__begin_[__n];
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::const_reference
|
|
|
|
vector<_Tp, _Allocator>::operator[](size_type __n) const
|
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
|
2010-05-12 03:42:16 +08:00
|
|
|
return this->__begin_[__n];
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::reference
|
|
|
|
vector<_Tp, _Allocator>::at(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n >= size())
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return this->__begin_[__n];
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::const_reference
|
|
|
|
vector<_Tp, _Allocator>::at(size_type __n) const
|
|
|
|
{
|
|
|
|
if (__n >= size())
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return this->__begin_[__n];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::reserve(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n > capacity())
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
2011-06-04 03:40:40 +08:00
|
|
|
__split_buffer<value_type, allocator_type&> __v(__n, size(), __a);
|
2010-05-12 03:42:16 +08:00
|
|
|
__swap_out_circular_buffer(__v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (capacity() > size())
|
|
|
|
{
|
|
|
|
#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
|
|
|
allocator_type& __a = this->__alloc();
|
2011-06-04 03:40:40 +08:00
|
|
|
__split_buffer<value_type, allocator_type&> __v(size(), size(), __a);
|
2010-05-12 03:42:16 +08:00
|
|
|
__swap_out_circular_buffer(__v);
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2012-02-15 08:41:34 +08:00
|
|
|
template <class _Up>
|
|
|
|
void
|
2017-04-16 10:40:45 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2012-02-15 08:41:34 +08:00
|
|
|
vector<_Tp, _Allocator>::__push_back_slow_path(_Up&& __x)
|
|
|
|
#else
|
|
|
|
vector<_Tp, _Allocator>::__push_back_slow_path(_Up& __x)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);
|
|
|
|
// __v.push_back(_VSTD::forward<_Up>(__x));
|
2013-01-12 04:36:59 +08:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Up>(__x));
|
|
|
|
__v.__end_++;
|
2012-02-15 08:41:34 +08:00
|
|
|
__swap_out_circular_buffer(__v);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::push_back(const_reference __x)
|
|
|
|
{
|
2012-02-15 08:41:34 +08:00
|
|
|
if (this->__end_ != this->__end_cap())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2010-05-12 03:42:16 +08:00
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_), __x);
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
}
|
|
|
|
else
|
2012-02-15 08:41:34 +08:00
|
|
|
__push_back_slow_path(__x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::push_back(value_type&& __x)
|
|
|
|
{
|
|
|
|
if (this->__end_ < this->__end_cap())
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2010-05-12 03:42:16 +08:00
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_),
|
|
|
|
_VSTD::move(__x));
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
}
|
|
|
|
else
|
2012-02-15 08:41:34 +08:00
|
|
|
__push_back_slow_path(_VSTD::move(__x));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class... _Args>
|
|
|
|
void
|
2012-02-26 23:30:12 +08:00
|
|
|
vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args)
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);
|
|
|
|
// __v.emplace_back(_VSTD::forward<_Args>(__args)...);
|
2013-01-12 04:36:59 +08:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Args>(__args)...);
|
|
|
|
__v.__end_++;
|
2012-02-26 23:30:12 +08:00
|
|
|
__swap_out_circular_buffer(__v);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class... _Args>
|
2015-11-07 09:22:13 +08:00
|
|
|
inline
|
2017-01-25 07:09:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 11:20:17 +08:00
|
|
|
typename vector<_Tp, _Allocator>::reference
|
2017-01-25 07:09:12 +08:00
|
|
|
#else
|
|
|
|
void
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
|
|
|
|
{
|
|
|
|
if (this->__end_ < this->__end_cap())
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2010-05-12 03:42:16 +08:00
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_),
|
|
|
|
_VSTD::forward<_Args>(__args)...);
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
}
|
|
|
|
else
|
2012-02-26 23:30:12 +08:00
|
|
|
__emplace_back_slow_path(_VSTD::forward<_Args>(__args)...);
|
2017-01-25 07:09:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 11:20:17 +08:00
|
|
|
return this->back();
|
2017-01-25 07:09:12 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 09:22:13 +08:00
|
|
|
inline
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::pop_back()
|
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(!empty(), "vector::pop_back called for empty vector");
|
2010-05-12 03:42:16 +08:00
|
|
|
this->__destruct_at_end(this->__end_ - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
vector<_Tp, _Allocator>::erase(const_iterator __position)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::erase(iterator) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2013-03-26 06:12:26 +08:00
|
|
|
_LIBCPP_ASSERT(__position != end(),
|
|
|
|
"vector::erase(iterator) called with a non-dereferenceable iterator");
|
2013-06-28 03:35:32 +08:00
|
|
|
difference_type __ps = __position - cbegin();
|
|
|
|
pointer __p = this->__begin_ + __ps;
|
2011-07-01 05:18:19 +08:00
|
|
|
this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
|
2016-12-28 14:06:09 +08:00
|
|
|
this->__invalidate_iterators_past(__p-1);
|
|
|
|
iterator __r = __make_iter(__p);
|
2010-05-12 03:42:16 +08:00
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
|
|
|
|
"vector::erase(iterator, iterator) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2016-12-28 14:06:09 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
|
|
|
|
"vector::erase(iterator, iterator) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __p = this->__begin_ + (__first - begin());
|
2016-12-28 14:06:09 +08:00
|
|
|
if (__first != __last) {
|
2013-04-18 23:02:57 +08:00
|
|
|
this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
|
2016-12-28 14:06:09 +08:00
|
|
|
this->__invalidate_iterators_past(__p - 1);
|
|
|
|
}
|
|
|
|
iterator __r = __make_iter(__p);
|
2010-05-12 03:42:16 +08:00
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to)
|
|
|
|
{
|
|
|
|
pointer __old_last = this->__end_;
|
|
|
|
difference_type __n = __old_last - __to;
|
|
|
|
for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_)
|
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_),
|
|
|
|
_VSTD::move(*__i));
|
|
|
|
_VSTD::move_backward(__from_s, __from_s + __n, __old_last);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::insert(iterator, x) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __p = this->__begin_ + (__position - begin());
|
|
|
|
if (this->__end_ < this->__end_cap())
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__p == this->__end_)
|
|
|
|
{
|
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_), __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__move_range(__p, this->__end_, __p + 1);
|
|
|
|
const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
|
|
|
|
if (__p <= __xr && __xr < this->__end_)
|
|
|
|
++__xr;
|
|
|
|
*__p = *__xr;
|
|
|
|
}
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
|
|
|
|
__v.push_back(__x);
|
|
|
|
__p = __swap_out_circular_buffer(__v, __p);
|
|
|
|
}
|
|
|
|
return __make_iter(__p);
|
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::insert(iterator, x) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __p = this->__begin_ + (__position - begin());
|
|
|
|
if (this->__end_ < this->__end_cap())
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__p == this->__end_)
|
|
|
|
{
|
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_),
|
|
|
|
_VSTD::move(__x));
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__move_range(__p, this->__end_, __p + 1);
|
2011-07-01 05:18:19 +08:00
|
|
|
*__p = _VSTD::move(__x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
|
2011-07-01 05:18:19 +08:00
|
|
|
__v.push_back(_VSTD::move(__x));
|
2010-05-12 03:42:16 +08:00
|
|
|
__p = __swap_out_circular_buffer(__v, __p);
|
|
|
|
}
|
|
|
|
return __make_iter(__p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class... _Args>
|
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::emplace(iterator, x) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __p = this->__begin_ + (__position - begin());
|
|
|
|
if (this->__end_ < this->__end_cap())
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__p == this->__end_)
|
|
|
|
{
|
|
|
|
__alloc_traits::construct(this->__alloc(),
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::__to_raw_pointer(this->__end_),
|
|
|
|
_VSTD::forward<_Args>(__args)...);
|
2010-05-12 03:42:16 +08:00
|
|
|
++this->__end_;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-07-12 05:38:08 +08:00
|
|
|
__temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
|
2010-05-12 03:42:16 +08:00
|
|
|
__move_range(__p, this->__end_, __p + 1);
|
2016-07-12 05:38:08 +08:00
|
|
|
*__p = _VSTD::move(__tmp.get());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
|
2011-07-01 05:18:19 +08:00
|
|
|
__v.emplace_back(_VSTD::forward<_Args>(__args)...);
|
2010-05-12 03:42:16 +08:00
|
|
|
__p = __swap_out_circular_buffer(__v, __p);
|
|
|
|
}
|
|
|
|
return __make_iter(__p);
|
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::insert(iterator, n, x) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __p = this->__begin_ + (__position - begin());
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
if (__n <= static_cast<size_type>(this->__end_cap() - this->__end_))
|
|
|
|
{
|
|
|
|
size_type __old_n = __n;
|
|
|
|
pointer __old_last = this->__end_;
|
|
|
|
if (__n > static_cast<size_type>(this->__end_ - __p))
|
|
|
|
{
|
|
|
|
size_type __cx = __n - (this->__end_ - __p);
|
|
|
|
__construct_at_end(__cx, __x);
|
|
|
|
__n -= __cx;
|
|
|
|
}
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2014-11-15 02:28:36 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__move_range(__p, __old_last, __p + __old_n);
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
|
|
|
|
if (__p <= __xr && __xr < this->__end_)
|
|
|
|
__xr += __old_n;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::fill_n(__p, __n, *__xr);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);
|
|
|
|
__v.__construct_at_end(__n, __x);
|
|
|
|
__p = __swap_out_circular_buffer(__v, __p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return __make_iter(__p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator <_InputIterator>::value &&
|
2013-03-29 01:44:32 +08:00
|
|
|
!__is_forward_iterator<_InputIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
_Tp,
|
|
|
|
typename iterator_traits<_InputIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
>::type
|
|
|
|
vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::insert(iterator, range) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
difference_type __off = __position - begin();
|
|
|
|
pointer __p = this->__begin_ + __off;
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
pointer __old_last = this->__end_;
|
|
|
|
for (; this->__end_ != this->__end_cap() && __first != __last; ++__first)
|
|
|
|
{
|
2015-07-19 02:22:12 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this);
|
2011-07-01 05:18:19 +08:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
|
2010-05-12 03:42:16 +08:00
|
|
|
*__first);
|
|
|
|
++this->__end_;
|
2015-07-19 02:22:12 +08:00
|
|
|
__annotator.__done();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__a);
|
|
|
|
if (__first != __last)
|
|
|
|
{
|
|
|
|
#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
|
|
|
__v.__construct_at_end(__first, __last);
|
|
|
|
difference_type __old_size = __old_last - this->__begin_;
|
|
|
|
difference_type __old_p = __p - this->__begin_;
|
|
|
|
reserve(__recommend(size() + __v.size()));
|
|
|
|
__p = this->__begin_ + __old_p;
|
|
|
|
__old_last = this->__begin_ + __old_size;
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
erase(__make_iter(__old_last), end());
|
|
|
|
throw;
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
__p = _VSTD::rotate(__p, __old_last, this->__end_);
|
2011-09-17 02:41:29 +08:00
|
|
|
insert(__make_iter(__p), make_move_iterator(__v.begin()),
|
|
|
|
make_move_iterator(__v.end()));
|
2010-05-12 03:42:16 +08:00
|
|
|
return begin() + __off;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
2013-03-29 01:44:32 +08:00
|
|
|
__is_forward_iterator<_ForwardIterator>::value &&
|
|
|
|
is_constructible<
|
|
|
|
_Tp,
|
|
|
|
typename iterator_traits<_ForwardIterator>::reference>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<_Tp, _Allocator>::iterator
|
|
|
|
>::type
|
|
|
|
vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
|
|
|
|
"vector::insert(iterator, range) called with an iterator not"
|
|
|
|
" referring to this vector");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
pointer __p = this->__begin_ + (__position - begin());
|
2011-07-01 05:18:19 +08:00
|
|
|
difference_type __n = _VSTD::distance(__first, __last);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
if (__n <= this->__end_cap() - this->__end_)
|
|
|
|
{
|
|
|
|
size_type __old_n = __n;
|
|
|
|
pointer __old_last = this->__end_;
|
|
|
|
_ForwardIterator __m = __last;
|
|
|
|
difference_type __dx = this->__end_ - __p;
|
|
|
|
if (__n > __dx)
|
|
|
|
{
|
|
|
|
__m = __first;
|
[libcxx] Optimize vectors uninitialized construction of trivial types from an iterator range.
Summary:
In certain cases vector can use memcpy to construct a range of elements at the back of the vector. We currently don't do this resulting in terrible code gen in non-optimized mode and a
very large slowdown compared to libstdc++.
This patch adds a `__construct_forward_range(Allocator, Iter, Iter, _Ptr&)` and `__construct_forward_range(Allocator, Tp*, Tp*, Tp*&)` functions to `allocator_traits` which act similarly to the existing `__construct_forward(...)` functions.
This patch also changes vectors `__construct_at_end(Iter, Iter)` to be `__construct_at_end(Iter, Iter, SizeType)` where SizeType is the size of the range. `__construct_at_end(Iter, Iter, SizeType)` now calls `allocator_traits<Tp>::__construct_forward_range(...)`.
This patch is based off the design of `__swap_out_circular_buffer(...)` which uses `allocator_traits<Tp>::__construct_forward(...)`.
On my machine this code performs 4x better than the current implementation when tested against `std::vector<int>`.
Reviewers: howard.hinnant, titus, kcc, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8109
llvm-svn: 233711
2015-04-01 00:54:19 +08:00
|
|
|
difference_type __diff = this->__end_ - __p;
|
|
|
|
_VSTD::advance(__m, __diff);
|
|
|
|
__construct_at_end(__m, __last, __n - __diff);
|
2010-05-12 03:42:16 +08:00
|
|
|
__n = __dx;
|
|
|
|
}
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2014-09-03 07:43:38 +08:00
|
|
|
__RAII_IncreaseAnnotator __annotator(*this, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__move_range(__p, __old_last, __p + __old_n);
|
2014-09-03 07:43:38 +08:00
|
|
|
__annotator.__done();
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy(__first, __m, __p);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_type& __a = this->__alloc();
|
|
|
|
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);
|
|
|
|
__v.__construct_at_end(__first, __last);
|
|
|
|
__p = __swap_out_circular_buffer(__v, __p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return __make_iter(__p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::resize(size_type __sz)
|
|
|
|
{
|
|
|
|
size_type __cs = size();
|
|
|
|
if (__cs < __sz)
|
|
|
|
this->__append(__sz - __cs);
|
|
|
|
else if (__cs > __sz)
|
|
|
|
this->__destruct_at_end(this->__begin_ + __sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x)
|
|
|
|
{
|
|
|
|
size_type __cs = size();
|
|
|
|
if (__cs < __sz)
|
|
|
|
this->__append(__sz - __cs, __x);
|
|
|
|
else if (__cs > __sz)
|
|
|
|
this->__destruct_at_end(this->__begin_ + __sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::swap(vector& __x)
|
2015-07-14 04:04:56 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
2016-12-28 14:06:09 +08:00
|
|
|
_NOEXCEPT_DEBUG
|
2015-07-14 04:04:56 +08:00
|
|
|
#else
|
2016-12-28 14:06:09 +08:00
|
|
|
_NOEXCEPT_DEBUG_(!__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-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
|
|
|
|
this->__alloc() == __x.__alloc(),
|
|
|
|
"vector::swap: Either propagate_on_container_swap must be true"
|
|
|
|
" or the allocators must compare equal");
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(this->__begin_, __x.__begin_);
|
|
|
|
_VSTD::swap(this->__end_, __x.__end_);
|
|
|
|
_VSTD::swap(this->__end_cap(), __x.__end_cap());
|
2017-04-16 10:40:45 +08:00
|
|
|
__swap_allocator(this->__alloc(), __x.__alloc(),
|
2015-07-14 04:04:56 +08:00
|
|
|
integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->swap(this, &__x);
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
vector<_Tp, _Allocator>::__invariants() const
|
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (this->__begin_ == nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (this->__end_ != nullptr || this->__end_cap() != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this->__begin_ > this->__end_)
|
|
|
|
return false;
|
|
|
|
if (this->__begin_ == this->__end_cap())
|
|
|
|
return false;
|
|
|
|
if (this->__end_ > this->__end_cap())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
bool
|
|
|
|
vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const
|
|
|
|
{
|
|
|
|
return this->__begin_ <= __i->base() && __i->base() < this->__end_;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
bool
|
|
|
|
vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const
|
|
|
|
{
|
|
|
|
return this->__begin_ < __i->base() && __i->base() <= this->__end_;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
bool
|
|
|
|
vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
|
|
|
|
{
|
|
|
|
const_pointer __p = __i->base() + __n;
|
|
|
|
return this->__begin_ <= __p && __p <= this->__end_;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
bool
|
|
|
|
vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
|
|
|
|
{
|
|
|
|
const_pointer __p = __i->base() + __n;
|
|
|
|
return this->__begin_ <= __p && __p < this->__end_;
|
|
|
|
}
|
|
|
|
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__invalidate_all_iterators()
|
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__invalidate_all(this);
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 14:06:09 +08:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
void
|
|
|
|
vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) {
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__c_node* __c = __get_db()->__find_c_and_lock(this);
|
|
|
|
for (__i_node** __p = __c->end_; __p != __c->beg_; ) {
|
|
|
|
--__p;
|
|
|
|
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
|
|
|
if (__i->base() > __new_last) {
|
|
|
|
(*__p)->__c_ = nullptr;
|
|
|
|
if (--__c->end_ != __p)
|
|
|
|
memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
__get_db()->unlock();
|
|
|
|
#else
|
|
|
|
((void)__new_last);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
// vector<bool>
|
|
|
|
|
|
|
|
template <class _Allocator> class vector<bool, _Allocator>;
|
|
|
|
|
|
|
|
template <class _Allocator> struct hash<vector<bool, _Allocator> >;
|
|
|
|
|
2011-07-03 04:33:23 +08:00
|
|
|
template <class _Allocator>
|
|
|
|
struct __has_storage_type<vector<bool, _Allocator> >
|
|
|
|
{
|
|
|
|
static const bool value = true;
|
|
|
|
};
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Allocator>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
: private __vector_base_common<true>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef vector __self;
|
2010-08-22 08:02:43 +08:00
|
|
|
typedef bool value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef _Allocator allocator_type;
|
|
|
|
typedef allocator_traits<allocator_type> __alloc_traits;
|
|
|
|
typedef typename __alloc_traits::size_type size_type;
|
|
|
|
typedef typename __alloc_traits::difference_type difference_type;
|
2012-05-08 00:50:38 +08:00
|
|
|
typedef size_type __storage_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef __bit_iterator<vector, false> pointer;
|
|
|
|
typedef __bit_iterator<vector, true> const_pointer;
|
|
|
|
typedef pointer iterator;
|
|
|
|
typedef 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:
|
2015-04-07 13:21:38 +08:00
|
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __storage_type>::type __storage_allocator;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef allocator_traits<__storage_allocator> __storage_traits;
|
|
|
|
typedef typename __storage_traits::pointer __storage_pointer;
|
|
|
|
typedef typename __storage_traits::const_pointer __const_storage_pointer;
|
|
|
|
|
|
|
|
__storage_pointer __begin_;
|
|
|
|
size_type __size_;
|
|
|
|
__compressed_pair<size_type, __storage_allocator> __cap_alloc_;
|
2011-07-09 23:50:42 +08:00
|
|
|
public:
|
2011-07-03 04:33:23 +08:00
|
|
|
typedef __bit_reference<vector> reference;
|
|
|
|
typedef __bit_const_reference<vector> const_reference;
|
2011-07-09 23:50:42 +08:00
|
|
|
private:
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type& __cap() _NOEXCEPT
|
|
|
|
{return __cap_alloc_.first();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const size_type& __cap() const _NOEXCEPT
|
|
|
|
{return __cap_alloc_.first();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__storage_allocator& __alloc() _NOEXCEPT
|
|
|
|
{return __cap_alloc_.second();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const __storage_allocator& __alloc() const _NOEXCEPT
|
|
|
|
{return __cap_alloc_.second();}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
static size_type __internal_cap_to_external(size_type __n) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __n * __bits_per_word;}
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
static size_type __external_cap_to_internal(size_type __n) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return (__n - 1) / __bits_per_word + 1;}
|
|
|
|
|
|
|
|
public:
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2015-06-04 10:05:41 +08:00
|
|
|
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
|
2015-06-04 08:10:20 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit vector(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
|
|
|
~vector();
|
|
|
|
explicit vector(size_type __n);
|
2013-09-14 08:47:59 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
explicit vector(size_type __n, const allocator_type& __a);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(size_type __n, const value_type& __v);
|
|
|
|
vector(size_type __n, const value_type& __v, const allocator_type& __a);
|
|
|
|
template <class _InputIterator>
|
|
|
|
vector(_InputIterator __first, _InputIterator __last,
|
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value>::type* = 0);
|
|
|
|
template <class _InputIterator>
|
|
|
|
vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
|
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value>::type* = 0);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
vector(_ForwardIterator __first, _ForwardIterator __last,
|
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
|
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);
|
|
|
|
|
|
|
|
vector(const vector& __v);
|
|
|
|
vector(const vector& __v, const allocator_type& __a);
|
|
|
|
vector& operator=(const vector& __v);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(initializer_list<value_type> __il);
|
|
|
|
vector(initializer_list<value_type> __il, const allocator_type& __a);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
vector(vector&& __v)
|
2015-07-14 22:46:32 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
_NOEXCEPT;
|
|
|
|
#else
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
|
2015-07-14 22:46:32 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
vector(vector&& __v, const allocator_type& __a);
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
vector& operator=(vector&& __v)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
|
2017-04-16 10:40:45 +08:00
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector& operator=(initializer_list<value_type> __il)
|
|
|
|
{assign(__il.begin(), __il.end()); return *this;}
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator<_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
|
|
|
assign(_InputIterator __first, _InputIterator __last);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
|
|
|
assign(_ForwardIterator __first, _ForwardIterator __last);
|
|
|
|
|
|
|
|
void assign(size_type __n, const value_type& __x);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void assign(initializer_list<value_type> __il)
|
|
|
|
{assign(__il.begin(), __il.end());}
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return allocator_type(this->__alloc());}
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
size_type max_size() const _NOEXCEPT;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type capacity() const _NOEXCEPT
|
|
|
|
{return __internal_cap_to_external(__cap());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type size() const _NOEXCEPT
|
|
|
|
{return __size_;}
|
2017-11-15 13:51:26 +08:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
bool empty() const _NOEXCEPT
|
|
|
|
{return __size_ == 0;}
|
2010-05-12 03:42:16 +08:00
|
|
|
void reserve(size_type __n);
|
2011-06-04 03:40:40 +08:00
|
|
|
void shrink_to_fit() _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator begin() _NOEXCEPT
|
|
|
|
{return __make_iter(0);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator begin() const _NOEXCEPT
|
|
|
|
{return __make_iter(0);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator end() _NOEXCEPT
|
|
|
|
{return __make_iter(__size_);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator end() const _NOEXCEPT
|
|
|
|
{return __make_iter(__size_);}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +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-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator cbegin() const _NOEXCEPT
|
|
|
|
{return __make_iter(0);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator cend() const _NOEXCEPT
|
|
|
|
{return __make_iter(__size_);}
|
|
|
|
_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
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __make_ref(__n);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __make_ref(__n);}
|
|
|
|
reference at(size_type __n);
|
|
|
|
const_reference at(size_type __n) const;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference front() {return __make_ref(0);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference front() const {return __make_ref(0);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference back() {return __make_ref(__size_ - 1);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const_reference back() const {return __make_ref(__size_ - 1);}
|
|
|
|
|
|
|
|
void push_back(const value_type& __x);
|
2013-08-14 07:54:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class... _Args>
|
2017-01-25 07:09:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference emplace_back(_Args&&... __args)
|
|
|
|
#else
|
|
|
|
_LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args)
|
|
|
|
#endif
|
|
|
|
{
|
2016-07-21 11:20:17 +08:00
|
|
|
push_back ( value_type ( _VSTD::forward<_Args>(__args)... ));
|
2017-01-25 07:09:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 11:20:17 +08:00
|
|
|
return this->back();
|
2017-01-25 07:09:12 +08:00
|
|
|
#endif
|
2016-07-21 11:20:17 +08:00
|
|
|
}
|
2013-08-14 07:54:12 +08:00
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;}
|
|
|
|
|
2013-08-14 07:54:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class... _Args>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY iterator emplace(const_iterator position, _Args&&... __args)
|
|
|
|
{ return insert ( position, value_type ( _VSTD::forward<_Args>(__args)... )); }
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __position, const value_type& __x);
|
|
|
|
iterator insert(const_iterator __position, size_type __n, const value_type& __x);
|
|
|
|
iterator insert(const_iterator __position, size_type __n, const_reference __x);
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator <_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value,
|
|
|
|
iterator
|
|
|
|
>::type
|
|
|
|
insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
iterator
|
|
|
|
>::type
|
|
|
|
insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
|
2017-04-16 10:40:45 +08:00
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator insert(const_iterator __position, initializer_list<value_type> __il)
|
|
|
|
{return insert(__position, __il.begin(), __il.end());}
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position);
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator erase(const_iterator __first, const_iterator __last);
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void clear() _NOEXCEPT {__size_ = 0;}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
void swap(vector&)
|
2015-07-14 04:04:56 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
|
|
|
_NOEXCEPT;
|
|
|
|
#else
|
2016-12-28 14:06:09 +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
|
2016-04-07 22:20:31 +08:00
|
|
|
static void swap(reference __x, reference __y) _NOEXCEPT { _VSTD::swap(__x, __y); }
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
void resize(size_type __sz, value_type __x = false);
|
2011-06-04 03:40:40 +08:00
|
|
|
void flip() _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
bool __invariants() const;
|
|
|
|
|
|
|
|
private:
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
2018-05-23 00:20:28 +08:00
|
|
|
void __vallocate(size_type __n);
|
|
|
|
void __vdeallocate() _NOEXCEPT;
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2013-08-15 02:00:20 +08:00
|
|
|
static size_type __align_it(size_type __new_size) _NOEXCEPT
|
2018-10-01 09:59:37 +08:00
|
|
|
{return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);}
|
2010-12-17 22:46:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
|
|
|
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
|
|
|
|
void __append(size_type __n, const_reference __x);
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
reference __make_ref(size_type __pos) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_reference __make_ref(size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator __make_iter(size_type __pos) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const_iterator __make_iter(size_type __pos) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
|
2011-06-04 03:40:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT
|
2013-06-28 03:35:32 +08:00
|
|
|
{return begin() + (__p - cbegin());}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __copy_assign_alloc(const vector& __v)
|
|
|
|
{__copy_assign_alloc(__v, integral_constant<bool,
|
|
|
|
__storage_traits::propagate_on_container_copy_assignment::value>());}
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __copy_assign_alloc(const vector& __c, true_type)
|
|
|
|
{
|
|
|
|
if (__alloc() != __c.__alloc())
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
2010-05-12 03:42:16 +08:00
|
|
|
__alloc() = __c.__alloc();
|
|
|
|
}
|
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-02 04:21:04 +08:00
|
|
|
void __copy_assign_alloc(const vector&, false_type)
|
2010-05-12 03:42:16 +08:00
|
|
|
{}
|
|
|
|
|
|
|
|
void __move_assign(vector& __c, false_type);
|
2011-06-04 03:40:40 +08:00
|
|
|
void __move_assign(vector& __c, true_type)
|
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void __move_assign_alloc(vector& __c)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(
|
|
|
|
!__storage_traits::propagate_on_container_move_assignment::value ||
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{__move_assign_alloc(__c, integral_constant<bool,
|
|
|
|
__storage_traits::propagate_on_container_move_assignment::value>());}
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-09-03 04:42:31 +08:00
|
|
|
void __move_assign_alloc(vector& __c, true_type)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
__alloc() = _VSTD::move(__c.__alloc());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-02 04:21:04 +08:00
|
|
|
void __move_assign_alloc(vector&, false_type)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{}
|
|
|
|
|
2011-06-04 03:40:40 +08:00
|
|
|
size_t __hash_code() const _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
friend class __bit_reference<vector>;
|
|
|
|
friend class __bit_const_reference<vector>;
|
|
|
|
friend class __bit_iterator<vector, false>;
|
|
|
|
friend class __bit_iterator<vector, true>;
|
2012-08-18 01:10:18 +08:00
|
|
|
friend struct __bit_array<vector>;
|
2017-01-05 07:56:00 +08:00
|
|
|
friend struct _LIBCPP_TEMPLATE_VIS hash<vector>;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::__invalidate_all_iterators()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allocate space for __n objects
|
|
|
|
// throws length_error if __n > max_size()
|
|
|
|
// throws (probably bad_alloc) if memory run out
|
|
|
|
// Precondition: __begin_ == __end_ == __cap() == 0
|
|
|
|
// Precondition: __n > 0
|
|
|
|
// Postcondition: capacity() == __n
|
|
|
|
// Postcondition: size() == 0
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
2018-05-23 00:20:28 +08:00
|
|
|
vector<bool, _Allocator>::__vallocate(size_type __n)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__n > max_size())
|
|
|
|
this->__throw_length_error();
|
|
|
|
__n = __external_cap_to_internal(__n);
|
|
|
|
this->__begin_ = __storage_traits::allocate(this->__alloc(), __n);
|
|
|
|
this->__size_ = 0;
|
|
|
|
this->__cap() = __n;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
2018-05-23 00:20:28 +08:00
|
|
|
vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (this->__begin_ != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
|
|
|
|
__invalidate_all_iterators();
|
2013-06-28 03:35:32 +08:00
|
|
|
this->__begin_ = nullptr;
|
2010-05-12 03:42:16 +08:00
|
|
|
this->__size_ = this->__cap() = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
typename vector<bool, _Allocator>::size_type
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<bool, _Allocator>::max_size() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_type __amax = __storage_traits::max_size(__alloc());
|
|
|
|
size_type __nmax = numeric_limits<size_type>::max() / 2; // end() >= begin(), always
|
|
|
|
if (__nmax / __bits_per_word <= __amax)
|
|
|
|
return __nmax;
|
|
|
|
return __internal_cap_to_external(__amax);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Precondition: __new_size > capacity()
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<bool, _Allocator>::size_type
|
|
|
|
vector<bool, _Allocator>::__recommend(size_type __new_size) const
|
|
|
|
{
|
|
|
|
const size_type __ms = max_size();
|
|
|
|
if (__new_size > __ms)
|
|
|
|
this->__throw_length_error();
|
|
|
|
const size_type __cap = capacity();
|
|
|
|
if (__cap >= __ms / 2)
|
|
|
|
return __ms;
|
2013-08-15 02:00:20 +08:00
|
|
|
return _VSTD::max(2*__cap, __align_it(__new_size));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Default constructs __n objects starting at __end_
|
|
|
|
// Precondition: __n > 0
|
|
|
|
// Precondition: size() + __n <= capacity()
|
|
|
|
// Postcondition: size() == size() + __n
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)
|
|
|
|
{
|
|
|
|
size_type __old_size = this->__size_;
|
|
|
|
this->__size_ += __n;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::fill_n(__make_iter(__old_size), __n, __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
|
|
|
vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
|
|
|
size_type __old_size = this->__size_;
|
2011-07-01 05:18:19 +08:00
|
|
|
this->__size_ += _VSTD::distance(__first, __last);
|
|
|
|
_VSTD::copy(__first, __last, __make_iter(__old_size));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<bool, _Allocator>::vector()
|
2015-06-04 10:05:41 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<bool, _Allocator>::vector(const allocator_type& __a)
|
2015-06-04 08:10:20 +08:00
|
|
|
#if _LIBCPP_STD_VER <= 14
|
|
|
|
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
|
|
|
|
#else
|
|
|
|
_NOEXCEPT
|
|
|
|
#endif
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(size_type __n)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0)
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-14 08:47:59 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)
|
|
|
|
: __begin_(nullptr),
|
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2013-09-14 08:47:59 +08:00
|
|
|
__construct_at_end(__n, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(size_type __n, const value_type& __x)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0)
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n, __x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__n, __x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
|
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value>::type*)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0)
|
|
|
|
{
|
|
|
|
#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 (...)
|
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (__begin_ != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
__storage_traits::deallocate(__alloc(), __begin_, __cap());
|
|
|
|
__invalidate_all_iterators();
|
|
|
|
throw;
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
|
|
|
|
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value>::type*)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
|
|
|
|
{
|
|
|
|
#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 (...)
|
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (__begin_ != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
__storage_traits::deallocate(__alloc(), __begin_, __cap());
|
|
|
|
__invalidate_all_iterators();
|
|
|
|
throw;
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
|
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0)
|
|
|
|
{
|
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 > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__first, __last);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
|
|
|
|
typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
|
|
|
|
{
|
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 > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__first, __last);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-08-13 05:56:02 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0)
|
|
|
|
{
|
|
|
|
size_type __n = static_cast<size_type>(__il.size());
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__il.begin(), __il.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
|
|
|
|
{
|
|
|
|
size_type __n = static_cast<size_type>(__il.size());
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__il.begin(), __il.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2011-08-13 05:56:02 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::~vector()
|
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (__begin_ != nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
__storage_traits::deallocate(__alloc(), __begin_, __cap());
|
|
|
|
__invalidate_all_iterators();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(const vector& __v)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc()))
|
|
|
|
{
|
|
|
|
if (__v.size() > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__v.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__v.begin(), __v.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, __a)
|
|
|
|
{
|
|
|
|
if (__v.size() > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__v.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__v.begin(), __v.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>&
|
|
|
|
vector<bool, _Allocator>::operator=(const vector& __v)
|
|
|
|
{
|
|
|
|
if (this != &__v)
|
|
|
|
{
|
|
|
|
__copy_assign_alloc(__v);
|
|
|
|
if (__v.__size_)
|
|
|
|
{
|
|
|
|
if (__v.__size_ > capacity())
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
|
|
|
__vallocate(__v.__size_);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
__size_ = __v.__size_;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-09-05 07:28:19 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Allocator>
|
2018-06-06 06:32:52 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v)
|
2015-07-14 22:46:32 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2018-06-06 06:32:52 +08:00
|
|
|
_NOEXCEPT
|
2015-07-14 22:46:32 +08:00
|
|
|
#else
|
2018-06-06 06:32:52 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
2015-07-14 22:46:32 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
: __begin_(__v.__begin_),
|
|
|
|
__size_(__v.__size_),
|
2018-06-06 06:32:52 +08:00
|
|
|
__cap_alloc_(std::move(__v.__cap_alloc_)) {
|
2013-06-28 03:35:32 +08:00
|
|
|
__v.__begin_ = nullptr;
|
2010-05-12 03:42:16 +08:00
|
|
|
__v.__size_ = 0;
|
|
|
|
__v.__cap() = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
|
2013-06-28 03:35:32 +08:00
|
|
|
: __begin_(nullptr),
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_(0),
|
|
|
|
__cap_alloc_(0, __a)
|
|
|
|
{
|
|
|
|
if (__a == allocator_type(__v.__alloc()))
|
|
|
|
{
|
|
|
|
this->__begin_ = __v.__begin_;
|
|
|
|
this->__size_ = __v.__size_;
|
|
|
|
this->__cap() = __v.__cap();
|
|
|
|
__v.__begin_ = nullptr;
|
|
|
|
__v.__cap() = __v.__size_ = 0;
|
|
|
|
}
|
|
|
|
else if (__v.size() > 0)
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vallocate(__v.size());
|
2010-05-12 03:42:16 +08:00
|
|
|
__construct_at_end(__v.begin(), __v.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
vector<bool, _Allocator>&
|
|
|
|
vector<bool, _Allocator>::operator=(vector&& __v)
|
2015-08-19 02:57:00 +08:00
|
|
|
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__move_assign(__v, integral_constant<bool,
|
|
|
|
__storage_traits::propagate_on_container_move_assignment::value>());
|
2012-10-13 10:03:45 +08:00
|
|
|
return *this;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::__move_assign(vector& __c, false_type)
|
|
|
|
{
|
|
|
|
if (__alloc() != __c.__alloc())
|
|
|
|
assign(__c.begin(), __c.end());
|
|
|
|
else
|
|
|
|
__move_assign(__c, true_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::__move_assign(vector& __c, true_type)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
2014-07-21 23:15:15 +08:00
|
|
|
__move_assign_alloc(__c);
|
2010-05-12 03:42:16 +08:00
|
|
|
this->__begin_ = __c.__begin_;
|
|
|
|
this->__size_ = __c.__size_;
|
|
|
|
this->__cap() = __c.__cap();
|
|
|
|
__c.__begin_ = nullptr;
|
|
|
|
__c.__cap() = __c.__size_ = 0;
|
|
|
|
}
|
2010-09-05 07:28:19 +08:00
|
|
|
|
2017-04-16 10:40:45 +08:00
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
|
|
|
|
{
|
|
|
|
__size_ = 0;
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
size_type __c = capacity();
|
|
|
|
if (__n <= __c)
|
|
|
|
__size_ = __n;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector __v(__alloc());
|
|
|
|
__v.reserve(__recommend(__n));
|
|
|
|
__v.__size_ = __n;
|
|
|
|
swap(__v);
|
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::fill_n(begin(), __n, __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2016-12-28 14:06:09 +08:00
|
|
|
__invalidate_all_iterators();
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator<_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
|
|
|
vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
for (; __first != __last; ++__first)
|
|
|
|
push_back(*__first);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
void
|
|
|
|
>::type
|
|
|
|
vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
|
|
|
clear();
|
2016-12-24 07:37:52 +08:00
|
|
|
difference_type __ns = _VSTD::distance(__first, __last);
|
|
|
|
_LIBCPP_ASSERT(__ns >= 0, "invalid range specified");
|
|
|
|
const size_t __n = static_cast<size_type>(__ns);
|
2010-05-12 03:42:16 +08:00
|
|
|
if (__n)
|
|
|
|
{
|
|
|
|
if (__n > capacity())
|
|
|
|
{
|
2018-05-23 00:20:28 +08:00
|
|
|
__vdeallocate();
|
|
|
|
__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
__construct_at_end(__first, __last);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::reserve(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n > capacity())
|
|
|
|
{
|
|
|
|
vector __v(this->__alloc());
|
2018-05-23 00:20:28 +08:00
|
|
|
__v.__vallocate(__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
__v.__construct_at_end(this->begin(), this->end());
|
|
|
|
swap(__v);
|
|
|
|
__invalidate_all_iterators();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__external_cap_to_internal(size()) > __cap())
|
|
|
|
{
|
|
|
|
#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
|
|
|
vector(*this, allocator_type(__alloc())).swap(*this);
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
typename vector<bool, _Allocator>::reference
|
|
|
|
vector<bool, _Allocator>::at(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n >= size())
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return (*this)[__n];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
typename vector<bool, _Allocator>::const_reference
|
|
|
|
vector<bool, _Allocator>::at(size_type __n) const
|
|
|
|
{
|
|
|
|
if (__n >= size())
|
|
|
|
this->__throw_out_of_range();
|
|
|
|
return (*this)[__n];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::push_back(const value_type& __x)
|
|
|
|
{
|
|
|
|
if (this->__size_ == this->capacity())
|
|
|
|
reserve(__recommend(this->__size_ + 1));
|
|
|
|
++this->__size_;
|
|
|
|
back() = __x;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
typename vector<bool, _Allocator>::iterator
|
|
|
|
vector<bool, _Allocator>::insert(const_iterator __position, const value_type& __x)
|
|
|
|
{
|
|
|
|
iterator __r;
|
|
|
|
if (size() < capacity())
|
|
|
|
{
|
|
|
|
const_iterator __old_end = end();
|
|
|
|
++__size_;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy_backward(__position, __old_end, end());
|
2010-05-12 03:42:16 +08:00
|
|
|
__r = __const_iterator_cast(__position);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector __v(__alloc());
|
|
|
|
__v.reserve(__recommend(__size_ + 1));
|
|
|
|
__v.__size_ = __size_ + 1;
|
2011-07-01 05:18:19 +08:00
|
|
|
__r = _VSTD::copy(cbegin(), __position, __v.begin());
|
|
|
|
_VSTD::copy_backward(__position, cend(), __v.end());
|
2010-05-12 03:42:16 +08:00
|
|
|
swap(__v);
|
|
|
|
}
|
|
|
|
*__r = __x;
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
typename vector<bool, _Allocator>::iterator
|
|
|
|
vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const value_type& __x)
|
|
|
|
{
|
|
|
|
iterator __r;
|
|
|
|
size_type __c = capacity();
|
|
|
|
if (__n <= __c && size() <= __c - __n)
|
|
|
|
{
|
|
|
|
const_iterator __old_end = end();
|
|
|
|
__size_ += __n;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy_backward(__position, __old_end, end());
|
2010-05-12 03:42:16 +08:00
|
|
|
__r = __const_iterator_cast(__position);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector __v(__alloc());
|
|
|
|
__v.reserve(__recommend(__size_ + __n));
|
|
|
|
__v.__size_ = __size_ + __n;
|
2011-07-01 05:18:19 +08:00
|
|
|
__r = _VSTD::copy(cbegin(), __position, __v.begin());
|
|
|
|
_VSTD::copy_backward(__position, cend(), __v.end());
|
2010-05-12 03:42:16 +08:00
|
|
|
swap(__v);
|
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::fill_n(__r, __n, __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _InputIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_input_iterator <_InputIterator>::value &&
|
|
|
|
!__is_forward_iterator<_InputIterator>::value,
|
|
|
|
typename vector<bool, _Allocator>::iterator
|
|
|
|
>::type
|
|
|
|
vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
|
|
|
|
{
|
|
|
|
difference_type __off = __position - begin();
|
|
|
|
iterator __p = __const_iterator_cast(__position);
|
|
|
|
iterator __old_end = end();
|
|
|
|
for (; size() != capacity() && __first != __last; ++__first)
|
|
|
|
{
|
|
|
|
++this->__size_;
|
|
|
|
back() = *__first;
|
|
|
|
}
|
|
|
|
vector __v(__alloc());
|
|
|
|
if (__first != __last)
|
|
|
|
{
|
|
|
|
#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
|
|
|
__v.assign(__first, __last);
|
|
|
|
difference_type __old_size = static_cast<difference_type>(__old_end - begin());
|
|
|
|
difference_type __old_p = __p - begin();
|
|
|
|
reserve(__recommend(size() + __v.size()));
|
|
|
|
__p = begin() + __old_p;
|
|
|
|
__old_end = begin() + __old_size;
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
erase(__old_end, end());
|
|
|
|
throw;
|
|
|
|
}
|
2010-08-22 08:02:43 +08:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
__p = _VSTD::rotate(__p, __old_end, end());
|
2010-05-12 03:42:16 +08:00
|
|
|
insert(__p, __v.begin(), __v.end());
|
|
|
|
return begin() + __off;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_forward_iterator<_ForwardIterator>::value,
|
|
|
|
typename vector<bool, _Allocator>::iterator
|
|
|
|
>::type
|
|
|
|
vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
|
|
|
|
{
|
2016-12-11 13:31:00 +08:00
|
|
|
const difference_type __n_signed = _VSTD::distance(__first, __last);
|
|
|
|
_LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified");
|
|
|
|
const size_type __n = static_cast<size_type>(__n_signed);
|
2010-05-12 03:42:16 +08:00
|
|
|
iterator __r;
|
|
|
|
size_type __c = capacity();
|
|
|
|
if (__n <= __c && size() <= __c - __n)
|
|
|
|
{
|
|
|
|
const_iterator __old_end = end();
|
|
|
|
__size_ += __n;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy_backward(__position, __old_end, end());
|
2010-05-12 03:42:16 +08:00
|
|
|
__r = __const_iterator_cast(__position);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector __v(__alloc());
|
|
|
|
__v.reserve(__recommend(__size_ + __n));
|
|
|
|
__v.__size_ = __size_ + __n;
|
2011-07-01 05:18:19 +08:00
|
|
|
__r = _VSTD::copy(cbegin(), __position, __v.begin());
|
|
|
|
_VSTD::copy_backward(__position, cend(), __v.end());
|
2010-05-12 03:42:16 +08:00
|
|
|
swap(__v);
|
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy(__first, __last, __r);
|
2010-05-12 03:42:16 +08:00
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename vector<bool, _Allocator>::iterator
|
|
|
|
vector<bool, _Allocator>::erase(const_iterator __position)
|
|
|
|
{
|
|
|
|
iterator __r = __const_iterator_cast(__position);
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy(__position + 1, this->cend(), __r);
|
2010-05-12 03:42:16 +08:00
|
|
|
--__size_;
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
typename vector<bool, _Allocator>::iterator
|
|
|
|
vector<bool, _Allocator>::erase(const_iterator __first, const_iterator __last)
|
|
|
|
{
|
|
|
|
iterator __r = __const_iterator_cast(__first);
|
|
|
|
difference_type __d = __last - __first;
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::copy(__last, this->cend(), __r);
|
2010-05-12 03:42:16 +08:00
|
|
|
__size_ -= __d;
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::swap(vector& __x)
|
2015-07-14 04:04:56 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
|
|
|
_NOEXCEPT
|
|
|
|
#else
|
2016-12-28 14:06:09 +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-07-01 05:18:19 +08:00
|
|
|
_VSTD::swap(this->__begin_, __x.__begin_);
|
|
|
|
_VSTD::swap(this->__size_, __x.__size_);
|
|
|
|
_VSTD::swap(this->__cap(), __x.__cap());
|
2017-04-16 10:40:45 +08:00
|
|
|
__swap_allocator(this->__alloc(), __x.__alloc(),
|
2015-07-14 04:04:56 +08:00
|
|
|
integral_constant<bool, __alloc_traits::propagate_on_container_swap::value>());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
vector<bool, _Allocator>::resize(size_type __sz, value_type __x)
|
|
|
|
{
|
|
|
|
size_type __cs = size();
|
|
|
|
if (__cs < __sz)
|
|
|
|
{
|
|
|
|
iterator __r;
|
|
|
|
size_type __c = capacity();
|
|
|
|
size_type __n = __sz - __cs;
|
|
|
|
if (__n <= __c && __cs <= __c - __n)
|
|
|
|
{
|
|
|
|
__r = end();
|
|
|
|
__size_ += __n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector __v(__alloc());
|
|
|
|
__v.reserve(__recommend(__size_ + __n));
|
|
|
|
__v.__size_ = __size_ + __n;
|
2011-07-01 05:18:19 +08:00
|
|
|
__r = _VSTD::copy(cbegin(), cend(), __v.begin());
|
2010-05-12 03:42:16 +08:00
|
|
|
swap(__v);
|
|
|
|
}
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::fill_n(__r, __n, __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
__size_ = __sz;
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<bool, _Allocator>::flip() _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
// do middle whole words
|
|
|
|
size_type __n = __size_;
|
|
|
|
__storage_pointer __p = __begin_;
|
|
|
|
for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
|
|
|
|
*__p = ~*__p;
|
|
|
|
// do last partial word
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
|
|
|
|
__storage_type __b = *__p & __m;
|
|
|
|
*__p &= ~__m;
|
|
|
|
*__p |= ~__b & __m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
vector<bool, _Allocator>::__invariants() const
|
|
|
|
{
|
2013-06-28 03:35:32 +08:00
|
|
|
if (this->__begin_ == nullptr)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (this->__size_ != 0 || this->__cap() != 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this->__cap() == 0)
|
|
|
|
return false;
|
|
|
|
if (this->__size_ > this->capacity())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-08-22 08:02:43 +08:00
|
|
|
template <class _Allocator>
|
2010-05-12 03:42:16 +08:00
|
|
|
size_t
|
2011-06-04 03:40:40 +08:00
|
|
|
vector<bool, _Allocator>::__hash_code() const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
size_t __h = 0;
|
|
|
|
// do middle whole words
|
|
|
|
size_type __n = __size_;
|
|
|
|
__storage_pointer __p = __begin_;
|
|
|
|
for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
|
|
|
|
__h ^= *__p;
|
|
|
|
// do last partial word
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
const __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
|
|
|
|
__h ^= *__p & __m;
|
|
|
|
}
|
|
|
|
return __h;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Allocator>
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> >
|
2010-05-12 03:42:16 +08:00
|
|
|
: public unary_function<vector<bool, _Allocator>, size_t>
|
|
|
|
{
|
2010-09-24 02:58:28 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-04 03:40:40 +08:00
|
|
|
size_t operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{return __vec.__hash_code();}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp, 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 vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
const typename vector<_Tp, _Allocator>::size_type __sz = __x.size();
|
2011-07-01 05:18:19 +08:00
|
|
|
return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, 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 vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return !(__x == __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, 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 vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
|
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, 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 vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return __y < __x;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, 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 vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return !(__x < __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, 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 vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return !(__y < __x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
void
|
|
|
|
swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
|
2011-06-04 03:40:40 +08:00
|
|
|
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
_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_VECTOR
|