llvm-project/libcxx/include/vector

3402 lines
109 KiB
Plaintext
Raw Normal View History

2010-05-12 03:42:16 +08:00
// -*- C++ -*-
//===------------------------------ vector --------------------------------===//
//
// 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
{
template <class T, class Allocator = allocator<T> >
2010-05-12 03:42:16 +08:00
class vector
{
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;
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);
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);
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);
vector& operator=(vector&& x)
noexcept(
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);
allocator_type get_allocator() const noexcept;
2010-05-12 03:42:16 +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
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
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
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);
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;
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>
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);
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);
void swap(vector&)
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-05-12 03:42:16 +08:00
template <class Allocator = allocator<T> >
2010-05-12 03:42:16 +08:00
class vector<bool, Allocator>
{
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:
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:
const_reference(const reference&) noexcept;
operator bool() const noexcept;
const_iterator operator&() const noexcept;
2010-05-12 03:42:16 +08:00
};
vector()
noexcept(is_nothrow_default_constructible<allocator_type>::value);
explicit vector(const allocator_type&);
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);
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);
vector& operator=(vector&& x)
noexcept(
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);
allocator_type get_allocator() const noexcept;
2010-05-12 03:42:16 +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
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
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
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);
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);
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();
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);
void clear() noexcept;
2010-05-12 03:42:16 +08:00
void resize(size_type sz);
void resize(size_type sz, value_type x);
void swap(vector&)
noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
allocator_traits<allocator_type>::is_always_equal::value); // C++17
void flip() noexcept;
2010-05-12 03:42:16 +08:00
bool __invariants() const;
};
2010-05-12 03:42:16 +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);
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>
#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>
#include <version>
2010-05-12 03:42:16 +08:00
#include <__split_buffer>
#include <__functional_base>
#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
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2010-05-12 03:42:16 +08:00
#pragma GCC system_header
#endif
2010-05-12 03:42:16 +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:
_LIBCPP_INLINE_VISIBILITY __vector_base_common() {}
_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
{
_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
{
_VSTD::__throw_out_of_range("vector");
2010-05-12 03:42:16 +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>
{
public:
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;
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_;
_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
_LIBCPP_INLINE_VISIBILITY
__vector_base()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
_LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT;
#endif
2010-05-12 03:42:16 +08:00
~__vector_base();
_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
_LIBCPP_INLINE_VISIBILITY
void __destruct_at_end(pointer __new_last) _NOEXCEPT;
2010-05-12 03:42:16 +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>());}
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void __move_assign_alloc(__vector_base& __c)
_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:
_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();
}
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __vector_base&, false_type)
2010-05-12 03:42:16 +08:00
{}
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__vector_base& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2010-05-12 03:42:16 +08:00
{
__alloc() = _VSTD::move(__c.__alloc());
2010-05-12 03:42:16 +08:00
}
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__vector_base&, false_type)
_NOEXCEPT
2010-05-12 03:42:16 +08:00
{}
};
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void
__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
2010-05-12 03:42:16 +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>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
__vector_base<_Tp, _Allocator>::__vector_base()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
: __begin_(nullptr),
__end_(nullptr),
__end_cap_(nullptr)
2010-05-12 03:42:16 +08:00
{
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
__vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
: __begin_(nullptr),
__end_(nullptr),
__end_cap_(nullptr, __a)
2010-05-12 03:42:16 +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()
{
if (__begin_ != nullptr)
2010-05-12 03:42:16 +08:00
{
clear();
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
}
}
template <class _Tp, class _Allocator /* = allocator<_Tp> */>
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;
typedef allocator<_Tp> __default_allocator_type;
public:
2010-05-12 03:42:16 +08:00
typedef vector __self;
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;
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
2010-05-12 03:42:16 +08:00
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
_LIBCPP_INLINE_VISIBILITY
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
}
_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
: __base(__a)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
}
2010-05-12 03:42:16 +08:00
explicit vector(size_type __n);
#if _LIBCPP_STD_VER > 11
explicit vector(size_type __n, const allocator_type& __a);
#endif
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>
vector(_InputIterator __first,
2010-05-12 03:42:16 +08:00
typename enable_if<__is_input_iterator <_InputIterator>::value &&
!__is_forward_iterator<_InputIterator>::value &&
is_constructible<
value_type,
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 &&
!__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>
vector(_ForwardIterator __first,
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
is_constructible<
value_type,
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,
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
_LIBCPP_INLINE_VISIBILITY
~vector()
{
__annotate_delete();
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__erase_c(this);
2010-05-12 03:42:16 +08:00
#endif
}
2010-05-12 03:42:16 +08:00
vector(const vector& __x);
vector(const vector& __x, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector& operator=(const vector& __x);
#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);
_LIBCPP_INLINE_VISIBILITY
vector(vector&& __x)
#if _LIBCPP_STD_VER > 14
_NOEXCEPT;
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
#endif
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector(vector&& __x, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __x)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
_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;}
#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 &&
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
<
__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);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void assign(initializer_list<value_type> __il)
{assign(__il.begin(), __il.end());}
#endif
2010-05-12 03:42:16 +08:00
_LIBCPP_INLINE_VISIBILITY
allocator_type get_allocator() const _NOEXCEPT
{return this->__alloc();}
2010-05-12 03:42:16 +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
_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
_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
_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();}
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
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);
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;
_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
_LIBCPP_INLINE_VISIBILITY
value_type* data() _NOEXCEPT
{return _VSTD::__to_raw_pointer(this->__begin_);}
_LIBCPP_INLINE_VISIBILITY
const value_type* data() const _NOEXCEPT
{return _VSTD::__to_raw_pointer(this->__begin_);}
2010-05-12 03:42:16 +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
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
2010-05-12 03:42:16 +08:00
template <class... _Args>
_LIBCPP_INLINE_VISIBILITY
#if _LIBCPP_STD_VER > 14
reference emplace_back(_Args&&... __args);
#else
void emplace_back(_Args&&... __args);
#endif
#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void pop_back();
iterator insert(const_iterator __position, const_reference __x);
#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);
#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 &&
!__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
<
__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);
#ifndef _LIBCPP_CXX03_LANG
_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());}
#endif
2010-05-12 03:42:16 +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);
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT
{
size_type __old_size = size();
__base::clear();
__annotate_shrink(__old_size);
__invalidate_all_iterators();
}
2010-05-12 03:42:16 +08:00
void resize(size_type __sz);
void resize(size_type __sz, const_reference __x);
void swap(vector&)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT_DEBUG;
#else
_NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);
#endif
2010-05-12 03:42:16 +08:00
bool __invariants() const;
#if _LIBCPP_DEBUG_LEVEL >= 2
bool __dereferenceable(const const_iterator* __i) const;
bool __decrementable(const const_iterator* __i) const;
bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
#endif // _LIBCPP_DEBUG_LEVEL >= 2
2010-05-12 03:42:16 +08:00
private:
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last);
void __vallocate(size_type __n);
void __vdeallocate() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
void __construct_at_end(size_type __n);
_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
__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);
_LIBCPP_INLINE_VISIBILITY
iterator __make_iter(pointer __p) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
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);
void __move_assign(vector& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
void __move_assign(vector& __c, false_type)
_NOEXCEPT_(__alloc_traits::is_always_equal::value);
_LIBCPP_INLINE_VISIBILITY
void __destruct_at_end(pointer __new_last) _NOEXCEPT
{
__invalidate_iterators_past(__new_last);
size_type __old_size = size();
__base::__destruct_at_end(__new_last);
__annotate_shrink(__old_size);
}
#ifndef _LIBCPP_CXX03_LANG
template <class _Up> void __push_back_slow_path(_Up&& __x);
template <class... _Args>
void __emplace_back_slow_path(_Args&&... __args);
#else
template <class _Up> void __push_back_slow_path(_Up& __x);
#endif
// 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
void __annotate_contiguous_container(const void *__beg, const void *__end,
const void *__old_mid,
const void *__new_mid) const
{
if (__beg && is_same<allocator_type, __default_allocator_type>::value)
__sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
}
#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 {
__annotate_contiguous_container(data(), data() + capacity(),
data() + capacity(), data() + __current_size);
}
_LIBCPP_INLINE_VISIBILITY
void __annotate_delete() const {
__annotate_contiguous_container(data(), data() + capacity(),
data() + size(), data() + capacity());
}
_LIBCPP_INLINE_VISIBILITY
void __annotate_increase(size_type __n) const
{
__annotate_contiguous_container(data(), data() + capacity(),
data() + size(), data() + size() + __n);
}
_LIBCPP_INLINE_VISIBILITY
void __annotate_shrink(size_type __old_size) const
{
__annotate_contiguous_container(data(), data() + capacity(),
data() + __old_size, data() + size());
}
#ifndef _LIBCPP_HAS_NO_ASAN
// 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)
: __commit(false), __v(__v), __old_size(__v.size() + __n) {
__v.__annotate_increase(__n);
}
void __done() { __commit = true; }
~__RAII_IncreaseAnnotator() {
if (__commit) return;
__v.__annotate_shrink(__old_size);
}
bool __commit;
const vector &__v;
size_type __old_size;
};
#else
struct __RAII_IncreaseAnnotator {
_LIBCPP_INLINE_VISIBILITY
__RAII_IncreaseAnnotator(const vector &, size_type = 1) {}
_LIBCPP_INLINE_VISIBILITY void __done() {}
};
#endif
2010-05-12 03:42:16 +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)
{
__annotate_delete();
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
_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_;
__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)
{
__annotate_delete();
2010-05-12 03:42:16 +08:00
pointer __r = __v.__begin_;
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);
__alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);
_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_;
__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
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;
__annotate_new(0);
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
void
vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
if (this->__begin_ != nullptr)
2010-05-12 03:42:16 +08:00
{
clear();
__alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
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
vector<_Tp, _Allocator>::max_size() const _NOEXCEPT
2010-05-12 03:42:16 +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>
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;
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
{
__RAII_IncreaseAnnotator __annotator(*this);
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
2010-05-12 03:42:16 +08:00
++this->__end_;
--__n;
__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>
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
{
__RAII_IncreaseAnnotator __annotator(*this);
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
2010-05-12 03:42:16 +08:00
++this->__end_;
--__n;
__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
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();
__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
// 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
// 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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__vallocate(__n);
2010-05-12 03:42:16 +08:00
__construct_at_end(__n);
}
}
#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)
{
__vallocate(__n);
__construct_at_end(__n);
}
}
#endif
2010-05-12 03:42:16 +08:00
template <class _Tp, class _Allocator>
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
2010-05-12 03:42:16 +08:00
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__vallocate(__n);
2010-05-12 03:42:16 +08:00
__construct_at_end(__n, __x);
}
}
template <class _Tp, class _Allocator>
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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__vallocate(__n);
2010-05-12 03:42:16 +08:00
__construct_at_end(__n, __x);
}
}
template <class _Tp, class _Allocator>
template <class _InputIterator>
vector<_Tp, _Allocator>::vector(_InputIterator __first,
2010-05-12 03:42:16 +08:00
typename enable_if<__is_input_iterator <_InputIterator>::value &&
!__is_forward_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value,
_InputIterator>::type __last)
2010-05-12 03:42:16 +08:00
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
for (; __first != __last; ++__first)
__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 &&
!__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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
for (; __first != __last; ++__first)
__emplace_back(*__first);
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
template <class _ForwardIterator>
vector<_Tp, _Allocator>::vector(_ForwardIterator __first,
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_ForwardIterator>::reference>::value,
_ForwardIterator>::type __last)
2010-05-12 03:42:16 +08:00
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__vallocate(__n);
__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,
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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__vallocate(__n);
__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()))
{
#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)
{
__vallocate(__n);
__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)
{
#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)
{
__vallocate(__n);
__construct_at_end(__x.__begin_, __x.__end_, __n);
2010-05-12 03:42:16 +08:00
}
}
#ifndef _LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<_Tp, _Allocator>::vector(vector&& __x)
#if _LIBCPP_STD_VER > 14
_NOEXCEPT
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
#endif
: __base(_VSTD::move(__x.__alloc()))
2010-05-12 03:42:16 +08:00
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
__get_db()->swap(this, &__x);
#endif
this->__begin_ = __x.__begin_;
this->__end_ = __x.__end_;
this->__end_cap() = __x.__end_cap();
__x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)
: __base(__a)
{
#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;
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->swap(this, &__x);
#endif
2010-05-12 03:42:16 +08:00
}
else
{
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>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
2010-05-12 03:42:16 +08:00
if (__il.size() > 0)
{
__vallocate(__il.size());
__construct_at_end(__il.begin(), __il.end(), __il.size());
2010-05-12 03:42:16 +08:00
}
}
template <class _Tp, class _Allocator>
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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
2010-05-12 03:42:16 +08:00
if (__il.size() > 0)
{
__vallocate(__il.size());
__construct_at_end(__il.begin(), __il.end(), __il.size());
2010-05-12 03:42:16 +08:00
}
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<_Tp, _Allocator>&
vector<_Tp, _Allocator>::operator=(vector&& __x)
_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)
_NOEXCEPT_(__alloc_traits::is_always_equal::value)
2010-05-12 03:42:16 +08:00
{
if (__base::__alloc() != __c.__alloc())
{
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)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2010-05-12 03:42:16 +08:00
{
__vdeallocate();
__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;
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->swap(this, &__c);
#endif
2010-05-12 03:42:16 +08:00
}
#endif // !_LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Tp, class _Allocator>
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 &&
!__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)
__emplace_back(*__first);
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
template <class _ForwardIterator>
typename enable_if
<
__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)
{
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;
if (__new_size > size())
2010-05-12 03:42:16 +08:00
{
__growing = true;
__mid = __first;
_VSTD::advance(__mid, size());
2010-05-12 03:42:16 +08:00
}
pointer __m = _VSTD::copy(__first, __mid, this->__begin_);
2010-05-12 03:42:16 +08:00
if (__growing)
__construct_at_end(__mid, __last, __new_size - size());
2010-05-12 03:42:16 +08:00
else
this->__destruct_at_end(__m);
}
else
{
__vdeallocate();
__vallocate(__recommend(__new_size));
__construct_at_end(__first, __last, __new_size);
2010-05-12 03:42:16 +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();
_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
this->__destruct_at_end(this->__begin_ + __n);
2010-05-12 03:42:16 +08:00
}
else
{
__vdeallocate();
__vallocate(__recommend(static_cast<size_type>(__n)));
2010-05-12 03:42:16 +08:00
__construct_at_end(__n, __u);
}
__invalidate_all_iterators();
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
#if _LIBCPP_DEBUG_LEVEL >= 2
2010-05-12 03:42:16 +08:00
return iterator(this, __p);
#else
return iterator(__p);
#endif
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::const_iterator
vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
2010-05-12 03:42:16 +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
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::begin() _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
return __make_iter(this->__begin_);
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::const_iterator
vector<_Tp, _Allocator>::begin() const _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
return __make_iter(this->__begin_);
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::end() _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
return __make_iter(this->__end_);
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::const_iterator
vector<_Tp, _Allocator>::end() const _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
return __make_iter(this->__end_);
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::reference
vector<_Tp, _Allocator>::operator[](size_type __n)
{
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
2010-05-12 03:42:16 +08:00
return this->__begin_[__n];
}
template <class _Tp, class _Allocator>
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
{
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
2010-05-12 03:42:16 +08:00
return this->__begin_[__n];
}
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];
}
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();
__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
vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
2010-05-12 03:42:16 +08:00
{
if (capacity() > size())
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +08:00
allocator_type& __a = this->__alloc();
__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 (...)
{
}
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +08:00
}
}
template <class _Tp, class _Allocator>
template <class _Up>
void
#ifndef _LIBCPP_CXX03_LANG
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));
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Up>(__x));
__v.__end_++;
__swap_out_circular_buffer(__v);
}
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void
vector<_Tp, _Allocator>::push_back(const_reference __x)
{
if (this->__end_ != this->__end_cap())
2010-05-12 03:42:16 +08:00
{
__RAII_IncreaseAnnotator __annotator(*this);
2010-05-12 03:42:16 +08:00
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_), __x);
__annotator.__done();
2010-05-12 03:42:16 +08:00
++this->__end_;
}
else
__push_back_slow_path(__x);
2010-05-12 03:42:16 +08:00
}
#ifndef _LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Tp, class _Allocator>
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())
{
__RAII_IncreaseAnnotator __annotator(*this);
2010-05-12 03:42:16 +08:00
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_),
_VSTD::move(__x));
__annotator.__done();
2010-05-12 03:42:16 +08:00
++this->__end_;
}
else
__push_back_slow_path(_VSTD::move(__x));
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
template <class... _Args>
void
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)...);
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Args>(__args)...);
__v.__end_++;
__swap_out_circular_buffer(__v);
}
template <class _Tp, class _Allocator>
template <class... _Args>
inline
#if _LIBCPP_STD_VER > 14
typename vector<_Tp, _Allocator>::reference
#else
void
#endif
2010-05-12 03:42:16 +08:00
vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
{
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
2010-05-12 03:42:16 +08:00
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_),
_VSTD::forward<_Args>(__args)...);
__annotator.__done();
2010-05-12 03:42:16 +08:00
++this->__end_;
}
else
__emplace_back_slow_path(_VSTD::forward<_Args>(__args)...);
#if _LIBCPP_STD_VER > 14
return this->back();
#endif
2010-05-12 03:42:16 +08:00
}
#endif // !_LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Tp, class _Allocator>
inline
2010-05-12 03:42:16 +08:00
void
vector<_Tp, _Allocator>::pop_back()
{
_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>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __position)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
"vector::erase(iterator) called with an iterator not"
" referring to this vector");
#endif
_LIBCPP_ASSERT(__position != end(),
"vector::erase(iterator) called with a non-dereferenceable iterator");
difference_type __ps = __position - cbegin();
pointer __p = this->__begin_ + __ps;
this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
"vector::erase(iterator, iterator) called with an iterator not"
" referring to this vector");
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
"vector::erase(iterator, iterator) called with an iterator not"
" referring to this vector");
#endif
_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());
if (__first != __last) {
this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
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(),
_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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
"vector::insert(iterator, x) called with an iterator not"
" referring to this vector");
#endif
2010-05-12 03:42:16 +08:00
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
2010-05-12 03:42:16 +08:00
if (__p == this->__end_)
{
__alloc_traits::construct(this->__alloc(),
_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;
}
__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);
}
#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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
"vector::insert(iterator, x) called with an iterator not"
" referring to this vector");
#endif
2010-05-12 03:42:16 +08:00
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
2010-05-12 03:42:16 +08:00
if (__p == this->__end_)
{
__alloc_traits::construct(this->__alloc(),
_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);
*__p = _VSTD::move(__x);
2010-05-12 03:42:16 +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(_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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
"vector::emplace(iterator, x) called with an iterator not"
" referring to this vector");
#endif
2010-05-12 03:42:16 +08:00
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
2010-05-12 03:42:16 +08:00
if (__p == this->__end_)
{
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_),
_VSTD::forward<_Args>(__args)...);
2010-05-12 03:42:16 +08:00
++this->__end_;
}
else
{
__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);
*__p = _VSTD::move(__tmp.get());
2010-05-12 03:42:16 +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.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);
}
#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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_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");
#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)
{
__RAII_IncreaseAnnotator __annotator(*this, __n);
2010-05-12 03:42:16 +08:00
__move_range(__p, __old_last, __p + __old_n);
__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;
_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 &&
!__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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
"vector::insert(iterator, range) called with an iterator not"
" referring to this vector");
#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)
{
__RAII_IncreaseAnnotator __annotator(*this);
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
2010-05-12 03:42:16 +08:00
*__first);
++this->__end_;
__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
{
#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;
}
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +08:00
}
__p = _VSTD::rotate(__p, __old_last, this->__end_);
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
<
__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)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
"vector::insert(iterator, range) called with an iterator not"
" referring to this vector");
#endif
2010-05-12 03:42:16 +08:00
pointer __p = this->__begin_ + (__position - begin());
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;
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)
{
__RAII_IncreaseAnnotator __annotator(*this, __n);
2010-05-12 03:42:16 +08:00
__move_range(__p, __old_last, __p + __old_n);
__annotator.__done();
_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)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT_DEBUG
#else
_NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
#endif
2010-05-12 03:42:16 +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");
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__end_, __x.__end_);
_VSTD::swap(this->__end_cap(), __x.__end_cap());
__swap_allocator(this->__alloc(), __x.__alloc(),
integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->swap(this, &__x);
#endif // _LIBCPP_DEBUG_LEVEL >= 2
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
2010-05-12 03:42:16 +08:00
bool
vector<_Tp, _Allocator>::__invariants() const
{
if (this->__begin_ == nullptr)
2010-05-12 03:42:16 +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;
}
#if _LIBCPP_DEBUG_LEVEL >= 2
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_;
}
#endif // _LIBCPP_DEBUG_LEVEL >= 2
2010-05-12 03:42:16 +08:00
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void
vector<_Tp, _Allocator>::__invalidate_all_iterators()
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__invalidate_all(this);
#endif // _LIBCPP_DEBUG_LEVEL >= 2
2010-05-12 03:42:16 +08:00
}
template <class _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> >;
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>
class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator>
2010-05-12 03:42:16 +08:00
: private __vector_base_common<true>
{
public:
typedef vector __self;
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;
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;
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:
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_;
public:
typedef __bit_reference<vector> reference;
typedef __bit_const_reference<vector> const_reference;
private:
_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);
_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;}
_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:
_LIBCPP_INLINE_VISIBILITY
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
_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);
#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);
#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);
_LIBCPP_INLINE_VISIBILITY
vector(vector&& __v)
#if _LIBCPP_STD_VER > 14
_NOEXCEPT;
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
#endif
2010-05-12 03:42:16 +08:00
vector(vector&& __v, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __v)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
_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;}
#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);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void assign(initializer_list<value_type> __il)
{assign(__il.begin(), __il.end());}
#endif
2010-05-12 03:42:16 +08:00
_LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT
2010-05-12 03:42:16 +08:00
{return allocator_type(this->__alloc());}
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_;}
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
bool empty() const _NOEXCEPT
{return __size_ == 0;}
2010-05-12 03:42:16 +08:00
void reserve(size_type __n);
void shrink_to_fit() _NOEXCEPT;
2010-05-12 03:42:16 +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
_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
_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);
#if _LIBCPP_STD_VER > 11
template <class... _Args>
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY reference emplace_back(_Args&&... __args)
#else
_LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args)
#endif
{
push_back ( value_type ( _VSTD::forward<_Args>(__args)... ));
#if _LIBCPP_STD_VER > 14
return this->back();
#endif
}
#endif
2010-05-12 03:42:16 +08:00
_LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;}
#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);
#ifndef _LIBCPP_CXX03_LANG
_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());}
#endif
2010-05-12 03:42:16 +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);
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__size_ = 0;}
2010-05-12 03:42:16 +08:00
void swap(vector&)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT;
#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);
#endif
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);
void flip() _NOEXCEPT;
2010-05-12 03:42:16 +08:00
bool __invariants() const;
private:
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
void __vallocate(size_type __n);
void __vdeallocate() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static size_type __align_it(size_type __new_size) _NOEXCEPT
{return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);}
_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);
_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);}
_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);}
_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));}
_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));}
_LIBCPP_INLINE_VISIBILITY
iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT
{return begin() + (__p - cbegin());}
2010-05-12 03:42:16 +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>());}
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void __copy_assign_alloc(const vector& __c, true_type)
{
if (__alloc() != __c.__alloc())
__vdeallocate();
2010-05-12 03:42:16 +08:00
__alloc() = __c.__alloc();
}
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const vector&, false_type)
2010-05-12 03:42:16 +08:00
{}
void __move_assign(vector& __c, false_type);
void __move_assign(vector& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
_LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void __move_assign_alloc(vector& __c)
_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>());}
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(vector& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2010-05-12 03:42:16 +08:00
{
__alloc() = _VSTD::move(__c.__alloc());
2010-05-12 03:42:16 +08:00
}
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(vector&, false_type)
_NOEXCEPT
2010-05-12 03:42:16 +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>;
friend struct __bit_array<vector>;
friend struct _LIBCPP_TEMPLATE_VIS hash<vector>;
2010-05-12 03:42:16 +08:00
};
template <class _Allocator>
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
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
vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT
2010-05-12 03:42:16 +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();
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
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>
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;
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>
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;
_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_;
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>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<bool, _Allocator>::vector()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0)
{
}
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<bool, _Allocator>::vector(const allocator_type& __a)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
#else
_NOEXCEPT
#endif
: __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)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0)
{
if (__n > 0)
{
__vallocate(__n);
2010-05-12 03:42:16 +08:00
__construct_at_end(__n, false);
}
}
#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)
{
__vallocate(__n);
__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)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0)
{
if (__n > 0)
{
__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)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
{
if (__n > 0)
{
__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*)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +08:00
for (; __first != __last; ++__first)
push_back(*__first);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
if (__begin_ != nullptr)
2010-05-12 03:42:16 +08:00
__storage_traits::deallocate(__alloc(), __begin_, __cap());
__invalidate_all_iterators();
throw;
}
#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*)
: __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
{
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +08:00
for (; __first != __last; ++__first)
push_back(*__first);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
if (__begin_ != nullptr)
2010-05-12 03:42:16 +08:00
__storage_traits::deallocate(__alloc(), __begin_, __cap());
__invalidate_all_iterators();
throw;
}
#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*)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0)
{
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__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*)
: __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>(_VSTD::distance(__first, __last));
2010-05-12 03:42:16 +08:00
if (__n > 0)
{
__vallocate(__n);
2010-05-12 03:42:16 +08:00
__construct_at_end(__first, __last);
}
}
#ifndef _LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Allocator>
vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
: __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)
{
__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)
: __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)
{
__vallocate(__n);
2010-05-12 03:42:16 +08:00
__construct_at_end(__il.begin(), __il.end());
}
}
#endif // _LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Allocator>
vector<bool, _Allocator>::~vector()
{
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)
: __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)
{
__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)
: __begin_(nullptr),
2010-05-12 03:42:16 +08:00
__size_(0),
__cap_alloc_(0, __a)
{
if (__v.size() > 0)
{
__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())
{
__vdeallocate();
__vallocate(__v.__size_);
2010-05-12 03:42:16 +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;
}
#ifndef _LIBCPP_CXX03_LANG
2010-05-12 03:42:16 +08:00
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v)
#if _LIBCPP_STD_VER > 14
_NOEXCEPT
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
#endif
2010-05-12 03:42:16 +08:00
: __begin_(__v.__begin_),
__size_(__v.__size_),
__cap_alloc_(std::move(__v.__cap_alloc_)) {
__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)
: __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)
{
__vallocate(__v.size());
2010-05-12 03:42:16 +08:00
__construct_at_end(__v.begin(), __v.end());
}
}
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
vector<bool, _Allocator>&
vector<bool, _Allocator>::operator=(vector&& __v)
_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>());
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)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
2010-05-12 03:42:16 +08:00
{
__vdeallocate();
__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;
}
#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);
}
_VSTD::fill_n(begin(), __n, __x);
2010-05-12 03:42:16 +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();
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())
{
__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());
__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
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
{
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +08:00
vector(*this, allocator_type(__alloc())).swap(*this);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
}
#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_;
_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;
__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;
_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;
__r = _VSTD::copy(cbegin(), __position, __v.begin());
_VSTD::copy_backward(__position, cend(), __v.end());
2010-05-12 03:42:16 +08:00
swap(__v);
}
_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
{
#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;
}
#endif // _LIBCPP_NO_EXCEPTIONS
2010-05-12 03:42:16 +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)
{
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;
_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;
__r = _VSTD::copy(cbegin(), __position, __v.begin());
_VSTD::copy_backward(__position, cend(), __v.end());
2010-05-12 03:42:16 +08:00
swap(__v);
}
_VSTD::copy(__first, __last, __r);
2010-05-12 03:42:16 +08:00
return __r;
}
template <class _Allocator>
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);
_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;
_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)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT
#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
#endif
2010-05-12 03:42:16 +08:00
{
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__size_, __x.__size_);
_VSTD::swap(this->__cap(), __x.__cap());
__swap_allocator(this->__alloc(), __x.__alloc(),
integral_constant<bool, __alloc_traits::propagate_on_container_swap::value>());
2010-05-12 03:42:16 +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;
__r = _VSTD::copy(cbegin(), cend(), __v.begin());
2010-05-12 03:42:16 +08:00
swap(__v);
}
_VSTD::fill_n(__r, __n, __x);
2010-05-12 03:42:16 +08:00
}
else
__size_ = __sz;
}
template <class _Allocator>
2010-05-12 03:42:16 +08:00
void
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;
}
}
template <class _Allocator>
2010-05-12 03:42:16 +08:00
bool
vector<bool, _Allocator>::__invariants() const
{
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;
}
template <class _Allocator>
2010-05-12 03:42:16 +08:00
size_t
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>
struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> >
2010-05-12 03:42:16 +08:00
: public unary_function<vector<bool, _Allocator>, size_t>
{
_LIBCPP_INLINE_VISIBILITY
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>
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();
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>
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>
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 _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2010-05-12 03:42:16 +08:00
}
template <class _Tp, class _Allocator>
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>
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>
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>
inline _LIBCPP_INLINE_VISIBILITY
2010-05-12 03:42:16 +08:00
void
swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2010-05-12 03:42:16 +08:00
{
__x.swap(__y);
}
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
2010-05-12 03:42:16 +08:00
#endif // _LIBCPP_VECTOR