2010-05-11 19:42:16 +00:00
|
|
|
// -*- C++ -*-
|
2021-11-17 16:25:01 -05:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-05-11 19:42:16 +00:00
|
|
|
//
|
2019-01-19 10:56:40 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-05-11 19:42:16 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_DEQUE
|
|
|
|
#define _LIBCPP_DEQUE
|
|
|
|
|
|
|
|
/*
|
|
|
|
deque synopsis
|
|
|
|
|
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
|
|
|
|
template <class T, class Allocator = allocator<T> >
|
|
|
|
class deque
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// types:
|
|
|
|
typedef T value_type;
|
|
|
|
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;
|
|
|
|
|
|
|
|
// construct/copy/destroy:
|
2011-06-03 15:16:49 +00:00
|
|
|
deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
|
2010-05-11 19:42:16 +00:00
|
|
|
explicit deque(const allocator_type& a);
|
|
|
|
explicit deque(size_type n);
|
2013-09-09 18:19:45 +00:00
|
|
|
explicit deque(size_type n, const allocator_type& a); // C++14
|
2010-05-11 19:42:16 +00:00
|
|
|
deque(size_type n, const value_type& v);
|
|
|
|
deque(size_type n, const value_type& v, const allocator_type& a);
|
|
|
|
template <class InputIterator>
|
|
|
|
deque(InputIterator f, InputIterator l);
|
|
|
|
template <class InputIterator>
|
|
|
|
deque(InputIterator f, InputIterator l, const allocator_type& a);
|
|
|
|
deque(const deque& c);
|
2011-06-02 21:38:57 +00:00
|
|
|
deque(deque&& c)
|
|
|
|
noexcept(is_nothrow_move_constructible<allocator_type>::value);
|
2010-05-11 19:42:16 +00:00
|
|
|
deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
|
|
|
|
deque(const deque& c, const allocator_type& a);
|
|
|
|
deque(deque&& c, const allocator_type& a);
|
|
|
|
~deque();
|
|
|
|
|
|
|
|
deque& operator=(const deque& c);
|
2011-06-02 21:38:57 +00:00
|
|
|
deque& operator=(deque&& c)
|
|
|
|
noexcept(
|
|
|
|
allocator_type::propagate_on_container_move_assignment::value &&
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value);
|
2010-05-11 19:42:16 +00:00
|
|
|
deque& operator=(initializer_list<value_type> il);
|
|
|
|
|
|
|
|
template <class InputIterator>
|
|
|
|
void assign(InputIterator f, InputIterator l);
|
|
|
|
void assign(size_type n, const value_type& v);
|
|
|
|
void assign(initializer_list<value_type> il);
|
|
|
|
|
2011-06-02 16:10:22 +00:00
|
|
|
allocator_type get_allocator() const noexcept;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
// iterators:
|
|
|
|
|
2011-06-02 16:10:22 +00:00
|
|
|
iterator begin() noexcept;
|
|
|
|
const_iterator begin() const noexcept;
|
|
|
|
iterator end() noexcept;
|
|
|
|
const_iterator end() const noexcept;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2011-06-02 16:10:22 +00:00
|
|
|
reverse_iterator rbegin() noexcept;
|
|
|
|
const_reverse_iterator rbegin() const noexcept;
|
|
|
|
reverse_iterator rend() noexcept;
|
|
|
|
const_reverse_iterator rend() const noexcept;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2011-06-02 16:10:22 +00: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-11 19:42:16 +00:00
|
|
|
|
|
|
|
// capacity:
|
2011-06-02 16:10:22 +00:00
|
|
|
size_type size() const noexcept;
|
|
|
|
size_type max_size() const noexcept;
|
2010-05-11 19:42:16 +00:00
|
|
|
void resize(size_type n);
|
|
|
|
void resize(size_type n, const value_type& v);
|
|
|
|
void shrink_to_fit();
|
2011-06-02 16:10:22 +00:00
|
|
|
bool empty() const noexcept;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
// element access:
|
|
|
|
reference operator[](size_type i);
|
|
|
|
const_reference operator[](size_type i) const;
|
|
|
|
reference at(size_type i);
|
|
|
|
const_reference at(size_type i) const;
|
|
|
|
reference front();
|
|
|
|
const_reference front() const;
|
|
|
|
reference back();
|
|
|
|
const_reference back() const;
|
|
|
|
|
|
|
|
// modifiers:
|
|
|
|
void push_front(const value_type& v);
|
|
|
|
void push_front(value_type&& v);
|
|
|
|
void push_back(const value_type& v);
|
|
|
|
void push_back(value_type&& v);
|
2017-01-24 23:09:12 +00:00
|
|
|
template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
|
|
|
|
template <class... Args> reference emplace_back(Args&&... args); // reference in C++17
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class... Args> iterator emplace(const_iterator p, Args&&... args);
|
|
|
|
iterator insert(const_iterator p, const value_type& v);
|
|
|
|
iterator insert(const_iterator p, value_type&& v);
|
|
|
|
iterator insert(const_iterator p, size_type n, const value_type& v);
|
|
|
|
template <class InputIterator>
|
2015-01-22 18:33:29 +00:00
|
|
|
iterator insert(const_iterator p, InputIterator f, InputIterator l);
|
2010-05-11 19:42:16 +00:00
|
|
|
iterator insert(const_iterator p, initializer_list<value_type> il);
|
|
|
|
void pop_front();
|
|
|
|
void pop_back();
|
|
|
|
iterator erase(const_iterator p);
|
|
|
|
iterator erase(const_iterator f, const_iterator l);
|
2011-06-02 21:38:57 +00:00
|
|
|
void swap(deque& c)
|
2015-07-13 20:04:56 +00:00
|
|
|
noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
|
2011-06-02 16:10:22 +00:00
|
|
|
void clear() noexcept;
|
2010-05-11 19:42:16 +00:00
|
|
|
};
|
|
|
|
|
2018-05-18 23:44:13 +00:00
|
|
|
template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
|
|
|
deque(InputIterator, InputIterator, Allocator = Allocator())
|
2021-11-09 09:21:02 -08:00
|
|
|
-> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
|
2018-05-18 23:44:13 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class T, class Allocator>
|
|
|
|
bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator>
|
|
|
|
bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator>
|
|
|
|
bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator>
|
|
|
|
bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator>
|
|
|
|
bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
|
|
|
template <class T, class Allocator>
|
|
|
|
bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
|
|
|
|
|
|
|
// specialized algorithms:
|
|
|
|
template <class T, class Allocator>
|
2011-06-03 17:30:28 +00:00
|
|
|
void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
|
|
|
|
noexcept(noexcept(x.swap(y)));
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2018-12-14 18:49:35 +00:00
|
|
|
template <class T, class Allocator, class U>
|
2020-05-02 13:58:03 +02:00
|
|
|
typename deque<T, Allocator>::size_type
|
|
|
|
erase(deque<T, Allocator>& c, const U& value); // C++20
|
2018-12-14 18:49:35 +00:00
|
|
|
template <class T, class Allocator, class Predicate>
|
2020-05-02 13:58:03 +02:00
|
|
|
typename deque<T, Allocator>::size_type
|
|
|
|
erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
|
2018-12-14 18:49:35 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2022-02-15 18:18:08 +01:00
|
|
|
#include <__algorithm/copy.h>
|
|
|
|
#include <__algorithm/copy_backward.h>
|
|
|
|
#include <__algorithm/equal.h>
|
|
|
|
#include <__algorithm/fill_n.h>
|
|
|
|
#include <__algorithm/lexicographical_compare.h>
|
|
|
|
#include <__algorithm/min.h>
|
|
|
|
#include <__algorithm/remove.h>
|
|
|
|
#include <__algorithm/remove_if.h>
|
|
|
|
#include <__algorithm/unwrap_iter.h>
|
2022-03-25 12:55:36 -04:00
|
|
|
#include <__assert> // all public C++ headers provide the assertion handler
|
2010-05-11 19:42:16 +00:00
|
|
|
#include <__config>
|
2021-09-26 15:47:42 +02:00
|
|
|
#include <__format/enable_insertable.h>
|
2021-11-09 09:21:02 -08:00
|
|
|
#include <__iterator/iterator_traits.h>
|
2022-06-10 19:53:10 +02:00
|
|
|
#include <__iterator/next.h>
|
|
|
|
#include <__iterator/prev.h>
|
|
|
|
#include <__iterator/reverse_iterator.h>
|
2010-05-11 19:42:16 +00:00
|
|
|
#include <__split_buffer>
|
2021-06-05 02:47:47 +00:00
|
|
|
#include <__utility/forward.h>
|
2022-03-05 19:17:07 +01:00
|
|
|
#include <__utility/move.h>
|
|
|
|
#include <__utility/swap.h>
|
2021-06-09 23:10:17 +00:00
|
|
|
#include <limits>
|
2010-05-11 19:42:16 +00:00
|
|
|
#include <stdexcept>
|
2021-05-12 23:04:03 -04:00
|
|
|
#include <type_traits>
|
2018-09-12 19:41:40 +00:00
|
|
|
#include <version>
|
2010-05-11 19:42:16 +00:00
|
|
|
|
[libc++] Re-add transitive includes that had been removed since LLVM 14
This commit re-adds transitive includes that had been removed by
4cd04d1687f1, c36870c8e79c, a83f4b9cda57, 1458458b558d, 2e2f3158c604,
and 489637e66dd3. This should cover almost all the includes that had
been removed since LLVM 14 and that would contribute to breaking user
code when releasing LLVM 15.
It is possible to disable the inclusion of these headers by defining
_LIBCPP_REMOVE_TRANSITIVE_INCLUDES. The intent is that vendors will
enable that macro and start fixing downstream issues immediately. We
can then remove the macro (and the transitive includes) by default in
a future release. That way, we will break users only once by removing
transitive includes in bulk instead of doing it bit by bit a every
release, which is more disruptive for users.
Note 1: The set of headers to re-add was found by re-generating the
transitive include test on a checkout of release/14.x, which
provided the list of all transitive includes we used to provide.
Note 2: Several includes of <vector>, <optional>, <array> and <unordered_map>
have been added in this commit. These transitive inclusions were
added when we implemented boyer_moore_searcher in <functional>.
Note 3: This is a best effort patch to try and resolve downstream breakage
caused since branching LLVM 14. I wasn't able to perfectly mirror
transitive includes in LLVM 14 for a few headers, so I added a
release note explaining it. To summarize, adding boyer_moore_searcher
created a bunch of circular dependencies, so we have to break
backwards compatibility in a few cases.
Differential Revision: https://reviews.llvm.org/D128661
2022-06-27 15:53:41 -04:00
|
|
|
#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
|
|
|
|
# include <algorithm>
|
|
|
|
# include <functional>
|
|
|
|
# include <iterator>
|
|
|
|
#endif
|
|
|
|
|
2022-06-16 22:43:46 +02:00
|
|
|
// standard-mandated includes
|
|
|
|
|
|
|
|
// [iterator.range]
|
|
|
|
#include <__iterator/access.h>
|
|
|
|
#include <__iterator/data.h>
|
|
|
|
#include <__iterator/empty.h>
|
|
|
|
#include <__iterator/reverse_access.h>
|
|
|
|
#include <__iterator/size.h>
|
|
|
|
|
|
|
|
// [deque.syn]
|
|
|
|
#include <compare>
|
|
|
|
#include <initializer_list>
|
|
|
|
|
2017-05-31 22:07:49 +00:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2022-02-01 20:16:40 -05:00
|
|
|
# pragma GCC system_header
|
2017-05-31 22:07:49 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
_LIBCPP_PUSH_MACROS
|
|
|
|
#include <__undef_macros>
|
|
|
|
|
2011-11-29 16:45:27 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator> class __deque_base;
|
2017-01-04 23:56:00 +00:00
|
|
|
template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
|
|
|
|
class _DiffType, _DiffType _BlockSize>
|
2017-01-04 23:56:00 +00:00
|
|
|
class _LIBCPP_TEMPLATE_VIS __deque_iterator;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy_backward(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move_backward(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
2015-11-06 22:02:29 +00:00
|
|
|
template <class _ValueType, class _DiffType>
|
|
|
|
struct __deque_block_size {
|
|
|
|
static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
|
|
|
|
};
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
|
2015-11-06 22:02:29 +00:00
|
|
|
class _DiffType, _DiffType _BS =
|
|
|
|
#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
|
|
|
|
// Keep template parameter to avoid changing all template declarations thoughout
|
|
|
|
// this file.
|
|
|
|
0
|
|
|
|
#else
|
|
|
|
__deque_block_size<_ValueType, _DiffType>::value
|
|
|
|
#endif
|
|
|
|
>
|
2017-01-04 23:56:00 +00:00
|
|
|
class _LIBCPP_TEMPLATE_VIS __deque_iterator
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
typedef _MapPointer __map_iterator;
|
|
|
|
public:
|
|
|
|
typedef _Pointer pointer;
|
|
|
|
typedef _DiffType difference_type;
|
|
|
|
private:
|
|
|
|
__map_iterator __m_iter_;
|
|
|
|
pointer __ptr_;
|
|
|
|
|
2015-11-06 22:02:29 +00:00
|
|
|
static const difference_type __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
public:
|
|
|
|
typedef _ValueType value_type;
|
|
|
|
typedef random_access_iterator_tag iterator_category;
|
|
|
|
typedef _Reference reference;
|
|
|
|
|
2013-08-06 16:14:36 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT
|
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
: __m_iter_(nullptr), __ptr_(nullptr)
|
|
|
|
#endif
|
|
|
|
{}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2011-11-29 18:15:50 +00:00
|
|
|
template <class _Pp, class _Rp, class _MP>
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2015-11-06 22:02:29 +00:00
|
|
|
__deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
|
2011-11-29 18:15:50 +00:00
|
|
|
typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
: __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
|
|
|
|
{
|
|
|
|
if (++__ptr_ - *__m_iter_ == __block_size)
|
|
|
|
{
|
|
|
|
++__m_iter_;
|
|
|
|
__ptr_ = *__m_iter_;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
|
|
|
|
{
|
|
|
|
__deque_iterator __tmp = *this;
|
|
|
|
++(*this);
|
|
|
|
return __tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
|
|
|
|
{
|
|
|
|
if (__ptr_ == *__m_iter_)
|
|
|
|
{
|
|
|
|
--__m_iter_;
|
|
|
|
__ptr_ = *__m_iter_ + __block_size;
|
|
|
|
}
|
|
|
|
--__ptr_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
|
|
|
|
{
|
|
|
|
__deque_iterator __tmp = *this;
|
|
|
|
--(*this);
|
|
|
|
return __tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
|
|
|
|
{
|
|
|
|
if (__n != 0)
|
|
|
|
{
|
|
|
|
__n += __ptr_ - *__m_iter_;
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
__m_iter_ += __n / __block_size;
|
|
|
|
__ptr_ = *__m_iter_ + __n % __block_size;
|
|
|
|
}
|
|
|
|
else // (__n < 0)
|
|
|
|
{
|
|
|
|
difference_type __z = __block_size - 1 - __n;
|
|
|
|
__m_iter_ -= __z / __block_size;
|
|
|
|
__ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2010-08-22 00:02:43 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
|
|
|
|
{
|
|
|
|
return *this += -__n;
|
|
|
|
}
|
2010-08-22 00:02:43 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
|
|
|
|
{
|
|
|
|
__deque_iterator __t(*this);
|
|
|
|
__t += __n;
|
|
|
|
return __t;
|
|
|
|
}
|
2010-08-22 00:02:43 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
|
|
|
|
{
|
|
|
|
__deque_iterator __t(*this);
|
|
|
|
__t -= __n;
|
|
|
|
return __t;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
|
|
|
|
{return __it + __n;}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{
|
|
|
|
if (__x != __y)
|
|
|
|
return (__x.__m_iter_ - __y.__m_iter_) * __block_size
|
|
|
|
+ (__x.__ptr_ - *__x.__m_iter_)
|
|
|
|
- (__y.__ptr_ - *__y.__m_iter_);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
|
|
|
|
{return *(*this + __n);}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY friend
|
|
|
|
bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{return __x.__ptr_ == __y.__ptr_;}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY friend
|
|
|
|
bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{return !(__x == __y);}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY friend
|
|
|
|
bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{return __x.__m_iter_ < __y.__m_iter_ ||
|
|
|
|
(__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY friend
|
|
|
|
bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{return __y < __x;}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY friend
|
|
|
|
bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{return !(__y < __x);}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY friend
|
|
|
|
bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
|
|
|
|
{return !(__x < __y);}
|
|
|
|
|
|
|
|
private:
|
2022-02-09 17:30:46 -05:00
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
: __m_iter_(__m), __ptr_(__p) {}
|
|
|
|
|
2011-11-29 18:15:50 +00:00
|
|
|
template <class _Tp, class _Ap> friend class __deque_base;
|
2017-01-04 23:56:00 +00:00
|
|
|
template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
|
2011-11-29 18:15:50 +00:00
|
|
|
template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
|
2017-01-04 23:56:00 +00:00
|
|
|
friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
copy(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
|
|
|
friend
|
|
|
|
_OutputIterator
|
|
|
|
copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
copy_backward(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
|
|
|
friend
|
|
|
|
_OutputIterator
|
|
|
|
copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
move(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
|
|
|
friend
|
|
|
|
_OutputIterator
|
|
|
|
move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
move_backward(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
|
|
|
friend
|
|
|
|
_OutputIterator
|
|
|
|
move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r);
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
|
|
|
friend
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
|
|
|
move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
|
|
|
|
};
|
|
|
|
|
2015-11-06 22:02:29 +00:00
|
|
|
template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
|
|
|
|
class _DiffType, _DiffType _BlockSize>
|
|
|
|
const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
|
|
|
|
_DiffType, _BlockSize>::__block_size =
|
|
|
|
__deque_block_size<_ValueType, _DiffType>::value;
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
// copy
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
|
2015-11-06 22:02:29 +00:00
|
|
|
const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
while (__f != __l)
|
|
|
|
{
|
|
|
|
pointer __rb = __r.__ptr_;
|
2015-11-06 22:02:29 +00:00
|
|
|
pointer __re = *__r.__m_iter_ + __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __bs = __re - __rb;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
_RAIter __m = __l;
|
|
|
|
if (__n > __bs)
|
|
|
|
{
|
|
|
|
__n = __bs;
|
|
|
|
__m = __f + __n;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::copy(__f, __m, __rb);
|
2010-05-11 19:42:16 +00:00
|
|
|
__f = __m;
|
|
|
|
__r += __n;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
2015-11-06 22:02:29 +00:00
|
|
|
const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
pointer __fb = __f.__ptr_;
|
2015-11-06 22:02:29 +00:00
|
|
|
pointer __fe = *__f.__m_iter_ + __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __bs = __fe - __fb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__fe = __fb + __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::copy(__fb, __fe, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__f += __bs;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
2015-11-06 22:02:29 +00:00
|
|
|
const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
pointer __fb = __f.__ptr_;
|
2015-11-06 22:02:29 +00:00
|
|
|
pointer __fe = *__f.__m_iter_ + __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __bs = __fe - __fb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__fe = __fb + __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::copy(__fb, __fe, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__f += __bs;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy_backward
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy_backward(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
|
|
|
|
while (__f != __l)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
|
2010-05-11 19:42:16 +00:00
|
|
|
pointer __rb = *__rp.__m_iter_;
|
|
|
|
pointer __re = __rp.__ptr_ + 1;
|
|
|
|
difference_type __bs = __re - __rb;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
_RAIter __m = __f;
|
|
|
|
if (__n > __bs)
|
|
|
|
{
|
|
|
|
__n = __bs;
|
|
|
|
__m = __l - __n;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::copy_backward(__m, __l, __re);
|
2010-05-11 19:42:16 +00:00
|
|
|
__l = __m;
|
|
|
|
__r -= __n;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
--__l;
|
|
|
|
pointer __lb = *__l.__m_iter_;
|
|
|
|
pointer __le = __l.__ptr_ + 1;
|
|
|
|
difference_type __bs = __le - __lb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__lb = __le - __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::copy_backward(__lb, __le, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__l -= __bs - 1;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
--__l;
|
|
|
|
pointer __lb = *__l.__m_iter_;
|
|
|
|
pointer __le = __l.__ptr_ + 1;
|
|
|
|
difference_type __bs = __le - __lb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__lb = __le - __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::copy_backward(__lb, __le, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__l -= __bs - 1;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// move
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
|
2015-11-06 22:02:29 +00:00
|
|
|
const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
while (__f != __l)
|
|
|
|
{
|
|
|
|
pointer __rb = __r.__ptr_;
|
2015-11-06 22:02:29 +00:00
|
|
|
pointer __re = *__r.__m_iter_ + __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __bs = __re - __rb;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
_RAIter __m = __l;
|
|
|
|
if (__n > __bs)
|
|
|
|
{
|
|
|
|
__n = __bs;
|
|
|
|
__m = __f + __n;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::move(__f, __m, __rb);
|
2010-05-11 19:42:16 +00:00
|
|
|
__f = __m;
|
|
|
|
__r += __n;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
2015-11-06 22:02:29 +00:00
|
|
|
const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
pointer __fb = __f.__ptr_;
|
2015-11-06 22:02:29 +00:00
|
|
|
pointer __fe = *__f.__m_iter_ + __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __bs = __fe - __fb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__fe = __fb + __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::move(__fb, __fe, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__f += __bs;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
2015-11-06 22:02:29 +00:00
|
|
|
const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
pointer __fb = __f.__ptr_;
|
2015-11-06 22:02:29 +00:00
|
|
|
pointer __fe = *__f.__m_iter_ + __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __bs = __fe - __fb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__fe = __fb + __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::move(__fb, __fe, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__f += __bs;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// move_backward
|
|
|
|
|
|
|
|
template <class _RAIter,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move_backward(_RAIter __f,
|
|
|
|
_RAIter __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
|
|
|
|
while (__f != __l)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
|
2010-05-11 19:42:16 +00:00
|
|
|
pointer __rb = *__rp.__m_iter_;
|
|
|
|
pointer __re = __rp.__ptr_ + 1;
|
|
|
|
difference_type __bs = __re - __rb;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
_RAIter __m = __f;
|
|
|
|
if (__n > __bs)
|
|
|
|
{
|
|
|
|
__n = __bs;
|
|
|
|
__m = __l - __n;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::move_backward(__m, __l, __re);
|
2010-05-11 19:42:16 +00:00
|
|
|
__l = __m;
|
|
|
|
__r -= __n;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _OutputIterator>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _OutputIterator
|
2010-05-11 19:42:16 +00:00
|
|
|
move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
_OutputIterator __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
--__l;
|
|
|
|
pointer __lb = *__l.__m_iter_;
|
|
|
|
pointer __le = __l.__ptr_ + 1;
|
|
|
|
difference_type __bs = __le - __lb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__lb = __le - __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::move_backward(__lb, __le, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__l -= __bs - 1;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
|
|
|
|
class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
|
2010-05-11 19:42:16 +00:00
|
|
|
move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
|
|
|
|
__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
|
|
|
|
__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
|
|
|
|
{
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
|
|
|
|
typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
--__l;
|
|
|
|
pointer __lb = *__l.__m_iter_;
|
|
|
|
pointer __le = __l.__ptr_ + 1;
|
|
|
|
difference_type __bs = __le - __lb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__lb = __le - __bs;
|
|
|
|
}
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::move_backward(__lb, __le, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__l -= __bs - 1;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
class __deque_base
|
|
|
|
{
|
|
|
|
__deque_base(const __deque_base& __c);
|
|
|
|
__deque_base& operator=(const __deque_base& __c);
|
2018-05-18 23:44:13 +00:00
|
|
|
public:
|
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&,
allocator_type)` if `allocator_type` is not a valid allocator.
Otherwise, these constructors are considered when resolving e.g.
`(int*, int*, NotAnAllocator())`, leading to a hard error during
instantiation. A hard error makes the Standard's requirement to not
consider deduction guides of the form `(Iterator, Iterator,
BadAllocator)` during overload resolution essentially non-functional.
The previous approach was to SFINAE away `allocator_traits`. This patch
SFINAEs away the specific constructors instead, for consistency with
`basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes
a very similar problem for strings (note, however, that unlike LWG3076,
no valid constructor call is affected by the bad instantiation).
Differential Revision: https://reviews.llvm.org/D114311
2021-12-01 11:55:46 -08:00
|
|
|
typedef _Allocator allocator_type;
|
|
|
|
typedef allocator_traits<allocator_type> __alloc_traits;
|
|
|
|
typedef typename __alloc_traits::size_type size_type;
|
2019-08-01 23:11:18 +00:00
|
|
|
|
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&,
allocator_type)` if `allocator_type` is not a valid allocator.
Otherwise, these constructors are considered when resolving e.g.
`(int*, int*, NotAnAllocator())`, leading to a hard error during
instantiation. A hard error makes the Standard's requirement to not
consider deduction guides of the form `(Iterator, Iterator,
BadAllocator)` during overload resolution essentially non-functional.
The previous approach was to SFINAE away `allocator_traits`. This patch
SFINAEs away the specific constructors instead, for consistency with
`basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes
a very similar problem for strings (note, however, that unlike LWG3076,
no valid constructor call is affected by the bad instantiation).
Differential Revision: https://reviews.llvm.org/D114311
2021-12-01 11:55:46 -08:00
|
|
|
typedef _Tp value_type;
|
|
|
|
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;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2015-11-06 22:02:29 +00:00
|
|
|
static const difference_type __block_size;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2015-04-07 05:21:38 +00:00
|
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
|
2010-05-11 19:42:16 +00:00
|
|
|
typedef allocator_traits<__pointer_allocator> __map_traits;
|
|
|
|
typedef typename __map_traits::pointer __map_pointer;
|
2015-04-07 05:21:38 +00:00
|
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;
|
2013-06-23 21:17:24 +00:00
|
|
|
typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
|
2010-05-11 19:42:16 +00:00
|
|
|
typedef __split_buffer<pointer, __pointer_allocator> __map;
|
|
|
|
|
|
|
|
typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
|
2015-11-06 22:02:29 +00:00
|
|
|
difference_type> iterator;
|
2010-05-11 19:42:16 +00:00
|
|
|
typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
|
2015-11-06 22:02:29 +00:00
|
|
|
difference_type> const_iterator;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2019-08-12 07:51:05 +00:00
|
|
|
struct __deque_block_range {
|
|
|
|
explicit __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {}
|
|
|
|
const pointer __begin_;
|
|
|
|
const pointer __end_;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct __deque_range {
|
|
|
|
iterator __pos_;
|
|
|
|
const iterator __end_;
|
|
|
|
|
|
|
|
__deque_range(iterator __pos, iterator __e) _NOEXCEPT
|
|
|
|
: __pos_(__pos), __end_(__e) {}
|
|
|
|
|
|
|
|
explicit operator bool() const _NOEXCEPT {
|
|
|
|
return __pos_ != __end_;
|
|
|
|
}
|
|
|
|
|
|
|
|
__deque_range begin() const {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
__deque_range end() const {
|
|
|
|
return __deque_range(__end_, __end_);
|
|
|
|
}
|
|
|
|
__deque_block_range operator*() const _NOEXCEPT {
|
|
|
|
if (__pos_.__m_iter_ == __end_.__m_iter_) {
|
|
|
|
return __deque_block_range(__pos_.__ptr_, __end_.__ptr_);
|
|
|
|
}
|
|
|
|
return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
__deque_range& operator++() _NOEXCEPT {
|
|
|
|
if (__pos_.__m_iter_ == __end_.__m_iter_) {
|
|
|
|
__pos_ = __end_;
|
|
|
|
} else {
|
|
|
|
++__pos_.__m_iter_;
|
|
|
|
__pos_.__ptr_ = *__pos_.__m_iter_;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) {
|
2019-08-12 07:51:05 +00:00
|
|
|
return __lhs.__pos_ == __rhs.__pos_;
|
|
|
|
}
|
2022-08-13 13:23:16 +02:00
|
|
|
_LIBCPP_HIDE_FROM_ABI friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) {
|
2019-08-12 07:51:05 +00:00
|
|
|
return !(__lhs == __rhs);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct _ConstructTransaction {
|
|
|
|
_ConstructTransaction(__deque_base* __db, __deque_block_range& __r)
|
|
|
|
: __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {}
|
|
|
|
|
|
|
|
|
|
|
|
~_ConstructTransaction() {
|
|
|
|
__base_->size() += (__pos_ - __begin_);
|
|
|
|
}
|
|
|
|
|
|
|
|
pointer __pos_;
|
|
|
|
const pointer __end_;
|
|
|
|
private:
|
|
|
|
const pointer __begin_;
|
|
|
|
__deque_base * const __base_;
|
|
|
|
};
|
|
|
|
|
2018-05-18 23:44:13 +00:00
|
|
|
protected:
|
2010-05-11 19:42:16 +00:00
|
|
|
__map __map_;
|
|
|
|
size_type __start_;
|
|
|
|
__compressed_pair<size_type, allocator_type> __size_;
|
|
|
|
|
2011-06-02 16:10:22 +00:00
|
|
|
iterator begin() _NOEXCEPT;
|
|
|
|
const_iterator begin() const _NOEXCEPT;
|
|
|
|
iterator end() _NOEXCEPT;
|
|
|
|
const_iterator end() const _NOEXCEPT;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY size_type& size() {return __size_.first();}
|
2011-06-02 16:10:22 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const size_type& size() const _NOEXCEPT {return __size_.first();}
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __size_.second();}
|
2011-06-02 16:10:22 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-03 15:16:49 +00:00
|
|
|
__deque_base()
|
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
explicit __deque_base(const allocator_type& __a);
|
2011-06-02 20:00:14 +00:00
|
|
|
public:
|
2010-05-11 19:42:16 +00:00
|
|
|
~__deque_base();
|
|
|
|
|
2017-04-16 03:17:01 +00:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-06-02 20:00:14 +00:00
|
|
|
__deque_base(__deque_base&& __c)
|
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
|
2010-05-11 19:42:16 +00:00
|
|
|
__deque_base(__deque_base&& __c, const allocator_type& __a);
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2011-06-02 20:00:14 +00:00
|
|
|
void swap(__deque_base& __c)
|
2015-07-13 20:04:56 +00:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
|
|
|
_NOEXCEPT;
|
|
|
|
#else
|
2018-12-12 23:58:25 +00:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
|
2015-07-13 20:04:56 +00:00
|
|
|
__is_nothrow_swappable<allocator_type>::value);
|
|
|
|
#endif
|
2011-06-02 20:00:14 +00:00
|
|
|
protected:
|
2011-06-02 16:10:22 +00:00
|
|
|
void clear() _NOEXCEPT;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
bool __invariants() const;
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
void __move_assign(__deque_base& __c)
|
2011-06-02 21:38:57 +00:00
|
|
|
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__map_ = _VSTD::move(__c.__map_);
|
2010-05-11 19:42:16 +00:00
|
|
|
__start_ = __c.__start_;
|
|
|
|
size() = __c.size();
|
|
|
|
__move_assign_alloc(__c);
|
|
|
|
__c.__start_ = __c.size() = 0;
|
|
|
|
}
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
void __move_assign_alloc(__deque_base& __c)
|
2011-06-02 20:00:14 +00:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-11 19:42:16 +00:00
|
|
|
{__move_assign_alloc(__c, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_move_assignment::value>());}
|
|
|
|
|
|
|
|
private:
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-09-02 20:42:31 +00:00
|
|
|
void __move_assign_alloc(__deque_base& __c, true_type)
|
2011-06-02 20:00:14 +00:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc() = _VSTD::move(__c.__alloc());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-01 20:21:04 +00:00
|
|
|
void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2015-11-06 22:02:29 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
const typename __deque_base<_Tp, _Allocator>::difference_type
|
|
|
|
__deque_base<_Tp, _Allocator>::__block_size =
|
|
|
|
__deque_block_size<value_type, difference_type>::value;
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
bool
|
|
|
|
__deque_base<_Tp, _Allocator>::__invariants() const
|
|
|
|
{
|
|
|
|
if (!__map_.__invariants())
|
|
|
|
return false;
|
|
|
|
if (__map_.size() >= size_type(-1) / __block_size)
|
|
|
|
return false;
|
|
|
|
for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
|
|
|
|
__i != __e; ++__i)
|
|
|
|
if (*__i == nullptr)
|
|
|
|
return false;
|
|
|
|
if (__map_.size() != 0)
|
|
|
|
{
|
|
|
|
if (size() >= __map_.size() * __block_size)
|
|
|
|
return false;
|
|
|
|
if (__start_ >= __map_.size() * __block_size - size())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (size() != 0)
|
|
|
|
return false;
|
|
|
|
if (__start_ != 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename __deque_base<_Tp, _Allocator>::iterator
|
2011-06-02 16:10:22 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__map_pointer __mp = __map_.begin() + __start_ / __block_size;
|
|
|
|
return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename __deque_base<_Tp, _Allocator>::const_iterator
|
2011-06-02 16:10:22 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
2013-06-23 21:17:24 +00:00
|
|
|
__map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
|
2010-05-11 19:42:16 +00:00
|
|
|
return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename __deque_base<_Tp, _Allocator>::iterator
|
2011-06-02 16:10:22 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __p = size() + __start_;
|
|
|
|
__map_pointer __mp = __map_.begin() + __p / __block_size;
|
|
|
|
return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename __deque_base<_Tp, _Allocator>::const_iterator
|
2011-06-02 16:10:22 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __p = size() + __start_;
|
2013-06-23 21:17:24 +00:00
|
|
|
__map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
|
2010-05-11 19:42:16 +00:00
|
|
|
return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::__deque_base()
|
2011-06-03 15:16:49 +00:00
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
2019-12-16 18:23:39 -05:00
|
|
|
: __start_(0), __size_(0, __default_init_tag()) {}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
|
|
|
|
: __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
__deque_base<_Tp, _Allocator>::~__deque_base()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
typename __map::iterator __i = __map_.begin();
|
|
|
|
typename __map::iterator __e = __map_.end();
|
|
|
|
for (; __i != __e; ++__i)
|
|
|
|
__alloc_traits::deallocate(__alloc(), *__i, __block_size);
|
|
|
|
}
|
|
|
|
|
2017-04-16 03:17:01 +00:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
|
2011-06-02 20:00:14 +00:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
2011-06-30 21:18:19 +00:00
|
|
|
: __map_(_VSTD::move(__c.__map_)),
|
|
|
|
__start_(_VSTD::move(__c.__start_)),
|
|
|
|
__size_(_VSTD::move(__c.__size_))
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__c.__start_ = 0;
|
|
|
|
__c.size() = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
|
2011-06-30 21:18:19 +00:00
|
|
|
: __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),
|
|
|
|
__start_(_VSTD::move(__c.__start_)),
|
|
|
|
__size_(_VSTD::move(__c.size()), __a)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
if (__a == __c.__alloc())
|
|
|
|
{
|
|
|
|
__c.__start_ = 0;
|
|
|
|
__c.size() = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__map_.clear();
|
|
|
|
__start_ = 0;
|
|
|
|
size() = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
|
2015-07-13 20:04:56 +00:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
|
|
|
_NOEXCEPT
|
|
|
|
#else
|
2018-12-12 23:58:25 +00:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
|
2015-07-13 20:04:56 +00:00
|
|
|
__is_nothrow_swappable<allocator_type>::value)
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__map_.swap(__c.__map_);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::swap(__start_, __c.__start_);
|
|
|
|
_VSTD::swap(size(), __c.size());
|
2020-11-18 18:54:38 -05:00
|
|
|
_VSTD::__swap_allocator(__alloc(), __c.__alloc());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
2011-06-02 16:10:22 +00:00
|
|
|
__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
allocator_type& __a = __alloc();
|
|
|
|
for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::destroy(__a, _VSTD::addressof(*__i));
|
2010-05-11 19:42:16 +00:00
|
|
|
size() = 0;
|
|
|
|
while (__map_.size() > 2)
|
|
|
|
{
|
|
|
|
__alloc_traits::deallocate(__a, __map_.front(), __block_size);
|
|
|
|
__map_.pop_front();
|
|
|
|
}
|
|
|
|
switch (__map_.size())
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
__start_ = __block_size / 2;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
__start_ = __block_size;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-18 17:24:08 +00:00
|
|
|
template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
|
2017-01-04 23:56:00 +00:00
|
|
|
class _LIBCPP_TEMPLATE_VIS deque
|
2010-05-11 19:42:16 +00:00
|
|
|
: private __deque_base<_Tp, _Allocator>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// types:
|
2010-08-22 00:02:43 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
typedef _Tp value_type;
|
|
|
|
typedef _Allocator allocator_type;
|
|
|
|
|
2015-11-26 01:24:04 +00:00
|
|
|
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
|
|
|
|
"Allocator::value_type must be same type as value_type");
|
|
|
|
|
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&,
allocator_type)` if `allocator_type` is not a valid allocator.
Otherwise, these constructors are considered when resolving e.g.
`(int*, int*, NotAnAllocator())`, leading to a hard error during
instantiation. A hard error makes the Standard's requirement to not
consider deduction guides of the form `(Iterator, Iterator,
BadAllocator)` during overload resolution essentially non-functional.
The previous approach was to SFINAE away `allocator_traits`. This patch
SFINAEs away the specific constructors instead, for consistency with
`basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes
a very similar problem for strings (note, however, that unlike LWG3076,
no valid constructor call is affected by the bad instantiation).
Differential Revision: https://reviews.llvm.org/D114311
2021-12-01 11:55:46 -08:00
|
|
|
typedef __deque_base<value_type, allocator_type> __base;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&,
allocator_type)` if `allocator_type` is not a valid allocator.
Otherwise, these constructors are considered when resolving e.g.
`(int*, int*, NotAnAllocator())`, leading to a hard error during
instantiation. A hard error makes the Standard's requirement to not
consider deduction guides of the form `(Iterator, Iterator,
BadAllocator)` during overload resolution essentially non-functional.
The previous approach was to SFINAE away `allocator_traits`. This patch
SFINAEs away the specific constructors instead, for consistency with
`basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes
a very similar problem for strings (note, however, that unlike LWG3076,
no valid constructor call is affected by the bad instantiation).
Differential Revision: https://reviews.llvm.org/D114311
2021-12-01 11:55:46 -08:00
|
|
|
typedef typename __base::__alloc_traits __alloc_traits;
|
|
|
|
typedef typename __base::reference reference;
|
|
|
|
typedef typename __base::const_reference const_reference;
|
|
|
|
typedef typename __base::iterator iterator;
|
|
|
|
typedef typename __base::const_iterator const_iterator;
|
|
|
|
typedef typename __base::size_type size_type;
|
|
|
|
typedef typename __base::difference_type difference_type;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&,
allocator_type)` if `allocator_type` is not a valid allocator.
Otherwise, these constructors are considered when resolving e.g.
`(int*, int*, NotAnAllocator())`, leading to a hard error during
instantiation. A hard error makes the Standard's requirement to not
consider deduction guides of the form `(Iterator, Iterator,
BadAllocator)` during overload resolution essentially non-functional.
The previous approach was to SFINAE away `allocator_traits`. This patch
SFINAEs away the specific constructors instead, for consistency with
`basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes
a very similar problem for strings (note, however, that unlike LWG3076,
no valid constructor call is affected by the bad instantiation).
Differential Revision: https://reviews.llvm.org/D114311
2021-12-01 11:55:46 -08:00
|
|
|
typedef typename __base::pointer pointer;
|
|
|
|
typedef typename __base::const_pointer const_pointer;
|
|
|
|
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
|
|
|
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2019-08-12 07:51:05 +00:00
|
|
|
using typename __base::__deque_range;
|
|
|
|
using typename __base::__deque_block_range;
|
|
|
|
using typename __base::_ConstructTransaction;
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
// construct/copy/destroy:
|
2011-06-03 15:16:49 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
deque()
|
|
|
|
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
|
|
|
{}
|
2014-03-05 19:06:20 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
|
2010-05-11 19:42:16 +00:00
|
|
|
explicit deque(size_type __n);
|
2013-09-07 16:16:19 +00:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
explicit deque(size_type __n, const _Allocator& __a);
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
deque(size_type __n, const value_type& __v);
|
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&,
allocator_type)` if `allocator_type` is not a valid allocator.
Otherwise, these constructors are considered when resolving e.g.
`(int*, int*, NotAnAllocator())`, leading to a hard error during
instantiation. A hard error makes the Standard's requirement to not
consider deduction guides of the form `(Iterator, Iterator,
BadAllocator)` during overload resolution essentially non-functional.
The previous approach was to SFINAE away `allocator_traits`. This patch
SFINAEs away the specific constructors instead, for consistency with
`basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes
a very similar problem for strings (note, however, that unlike LWG3076,
no valid constructor call is affected by the bad instantiation).
Differential Revision: https://reviews.llvm.org/D114311
2021-12-01 11:55:46 -08:00
|
|
|
|
|
|
|
template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
|
|
|
|
deque(size_type __n, const value_type& __v, const allocator_type& __a) : __base(__a)
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
__append(__n, __v);
|
|
|
|
}
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _InputIter>
|
|
|
|
deque(_InputIter __f, _InputIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _InputIter>
|
|
|
|
deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
deque(const deque& __c);
|
2022-03-18 17:49:02 +01:00
|
|
|
deque(const deque& __c, const __type_identity_t<allocator_type>& __a);
|
2017-04-16 03:17:01 +00:00
|
|
|
|
|
|
|
deque& operator=(const deque& __c);
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
deque(initializer_list<value_type> __il);
|
|
|
|
deque(initializer_list<value_type> __il, const allocator_type& __a);
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
|
|
|
|
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 20:00:14 +00:00
|
|
|
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2022-03-18 17:49:02 +01:00
|
|
|
deque(deque&& __c, const __type_identity_t<allocator_type>& __a);
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 20:00:14 +00:00
|
|
|
deque& operator=(deque&& __c)
|
2011-06-02 21:38:57 +00:00
|
|
|
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value);
|
2017-04-16 03:17:01 +00:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _InputIter>
|
|
|
|
void assign(_InputIter __f, _InputIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
|
|
|
|
!__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _RAIter>
|
|
|
|
void assign(_RAIter __f, _RAIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
void assign(size_type __n, const value_type& __v);
|
|
|
|
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
allocator_type get_allocator() const _NOEXCEPT;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
// iterators:
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
iterator begin() _NOEXCEPT {return __base::begin();}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_iterator begin() const _NOEXCEPT {return __base::begin();}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
iterator end() _NOEXCEPT {return __base::end();}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_iterator end() const _NOEXCEPT {return __base::end();}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
reverse_iterator rbegin() _NOEXCEPT
|
|
|
|
{return reverse_iterator(__base::end());}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_reverse_iterator rbegin() const _NOEXCEPT
|
|
|
|
{return const_reverse_iterator(__base::end());}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
reverse_iterator rend() _NOEXCEPT
|
|
|
|
{return reverse_iterator(__base::begin());}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_reverse_iterator rend() const _NOEXCEPT
|
|
|
|
{return const_reverse_iterator(__base::begin());}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_iterator cbegin() const _NOEXCEPT
|
|
|
|
{return __base::begin();}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_iterator cend() const _NOEXCEPT
|
|
|
|
{return __base::end();}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_reverse_iterator crbegin() const _NOEXCEPT
|
|
|
|
{return const_reverse_iterator(__base::end());}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
const_reverse_iterator crend() const _NOEXCEPT
|
|
|
|
{return const_reverse_iterator(__base::begin());}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
// capacity:
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
size_type size() const _NOEXCEPT {return __base::size();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type max_size() const _NOEXCEPT
|
[libc++] Consistently replace `std::` qualification with `_VSTD::` or nothing. NFCI.
I used a lot of `git grep` to find places where `std::` was being used
outside of comments and assert-messages. There were three outcomes:
- Qualified function calls, e.g. `std::move` becomes `_VSTD::move`.
This is the most common case.
- Typenames that don't need qualification, e.g. `std::allocator` becomes `allocator`.
Leaving these as `_VSTD::allocator` would also be fine, but I decided
that removing the qualification is more consistent with existing practice.
- Names that specifically need un-versioned `std::` qualification,
or that I wasn't sure about. For example, I didn't touch any code in
<atomic>, <math.h>, <new>, or any ext/ or experimental/ headers;
and I didn't touch any instances of `std::type_info`.
In some deduction guides, we were accidentally using `class Alloc = typename std::allocator<T>`,
despite `std::allocator<T>`'s type-ness not being template-dependent.
Because `std::allocator` is a qualified name, this did parse as we intended;
but what we meant was simply `class Alloc = allocator<T>`.
Differential Revision: https://reviews.llvm.org/D92250
2020-11-27 11:02:06 -05:00
|
|
|
{return _VSTD::min<size_type>(
|
2016-11-23 01:18:56 +00:00
|
|
|
__alloc_traits::max_size(__base::__alloc()),
|
|
|
|
numeric_limits<difference_type>::max());}
|
2010-05-11 19:42:16 +00:00
|
|
|
void resize(size_type __n);
|
|
|
|
void resize(size_type __n, const value_type& __v);
|
2011-06-02 21:38:57 +00:00
|
|
|
void shrink_to_fit() _NOEXCEPT;
|
2017-11-15 05:51:26 +00:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
bool empty() const _NOEXCEPT {return __base::size() == 0;}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
// element access:
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-14 21:56:57 +00:00
|
|
|
reference operator[](size_type __i) _NOEXCEPT;
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-14 21:56:57 +00:00
|
|
|
const_reference operator[](size_type __i) const _NOEXCEPT;
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
reference at(size_type __i);
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
const_reference at(size_type __i) const;
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-19 03:30:07 +00:00
|
|
|
reference front() _NOEXCEPT;
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-19 03:30:07 +00:00
|
|
|
const_reference front() const _NOEXCEPT;
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-19 03:30:07 +00:00
|
|
|
reference back() _NOEXCEPT;
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-19 03:30:07 +00:00
|
|
|
const_reference back() const _NOEXCEPT;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
// 23.2.2.3 modifiers:
|
|
|
|
void push_front(const value_type& __v);
|
|
|
|
void push_back(const value_type& __v);
|
2017-04-16 03:17:01 +00:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2017-01-24 23:09:12 +00:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 03:20:17 +00:00
|
|
|
template <class... _Args> reference emplace_front(_Args&&... __args);
|
2017-01-24 23:09:12 +00:00
|
|
|
template <class... _Args> reference emplace_back (_Args&&... __args);
|
|
|
|
#else
|
|
|
|
template <class... _Args> void emplace_front(_Args&&... __args);
|
|
|
|
template <class... _Args> void emplace_back (_Args&&... __args);
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
|
2017-04-16 03:17:01 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
void push_front(value_type&& __v);
|
|
|
|
void push_back(value_type&& __v);
|
|
|
|
iterator insert(const_iterator __p, value_type&& __v);
|
2017-04-16 03:17:01 +00:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
iterator insert(const_iterator __p, initializer_list<value_type> __il)
|
|
|
|
{return insert(__p, __il.begin(), __il.end());}
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
iterator insert(const_iterator __p, const value_type& __v);
|
|
|
|
iterator insert(const_iterator __p, size_type __n, const value_type& __v);
|
|
|
|
template <class _InputIter>
|
2015-01-22 18:33:29 +00:00
|
|
|
iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
|
2022-07-04 22:45:49 +02:00
|
|
|
typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0);
|
2015-01-22 18:33:29 +00:00
|
|
|
template <class _ForwardIterator>
|
|
|
|
iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
|
2022-07-04 22:45:49 +02:00
|
|
|
typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _BiIter>
|
2015-01-22 18:33:29 +00:00
|
|
|
iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
|
2017-04-16 03:17:01 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
void pop_front();
|
|
|
|
void pop_back();
|
|
|
|
iterator erase(const_iterator __p);
|
|
|
|
iterator erase(const_iterator __f, const_iterator __l);
|
|
|
|
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 20:00:14 +00:00
|
|
|
void swap(deque& __c)
|
2015-07-13 20:04:56 +00:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
|
|
|
_NOEXCEPT;
|
|
|
|
#else
|
2011-06-02 20:00:14 +00:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
|
|
|
|
__is_nothrow_swappable<allocator_type>::value);
|
2015-07-13 20:04:56 +00:00
|
|
|
#endif
|
2015-11-07 01:22:13 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-06-02 16:10:22 +00:00
|
|
|
void clear() _NOEXCEPT;
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool __invariants() const {return __base::__invariants();}
|
2019-08-01 23:11:18 +00:00
|
|
|
|
2013-06-23 21:17:24 +00:00
|
|
|
typedef typename __base::__map_const_pointer __map_const_pointer;
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
static size_type __recommend_blocks(size_type __n)
|
|
|
|
{
|
|
|
|
return __n / __base::__block_size + (__n % __base::__block_size != 0);
|
|
|
|
}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
size_type __capacity() const
|
|
|
|
{
|
|
|
|
return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
|
|
|
|
}
|
2019-08-01 23:11:18 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __block_count() const
|
|
|
|
{
|
|
|
|
return __base::__map_.size();
|
|
|
|
}
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
size_type __front_spare() const
|
|
|
|
{
|
|
|
|
return __base::__start_;
|
|
|
|
}
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-08-01 23:11:18 +00:00
|
|
|
size_type __front_spare_blocks() const {
|
|
|
|
return __front_spare() / __base::__block_size;
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
size_type __back_spare() const
|
|
|
|
{
|
|
|
|
return __capacity() - (__base::__start_ + __base::size());
|
|
|
|
}
|
2019-08-01 23:11:18 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_type __back_spare_blocks() const {
|
|
|
|
return __back_spare() / __base::__block_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool __maybe_remove_front_spare(bool __keep_one = true) {
|
|
|
|
if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) {
|
|
|
|
__alloc_traits::deallocate(__base::__alloc(), __base::__map_.front(),
|
|
|
|
__base::__block_size);
|
|
|
|
__base::__map_.pop_front();
|
|
|
|
__base::__start_ -= __base::__block_size;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool __maybe_remove_back_spare(bool __keep_one = true) {
|
|
|
|
if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) {
|
|
|
|
__alloc_traits::deallocate(__base::__alloc(), __base::__map_.back(),
|
|
|
|
__base::__block_size);
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _InpIter>
|
|
|
|
void __append(_InpIter __f, _InpIter __l,
|
2022-07-04 22:45:49 +02:00
|
|
|
typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _ForIter>
|
|
|
|
void __append(_ForIter __f, _ForIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
|
2010-05-11 19:42:16 +00:00
|
|
|
void __append(size_type __n);
|
|
|
|
void __append(size_type __n, const value_type& __v);
|
|
|
|
void __erase_to_end(const_iterator __f);
|
|
|
|
void __add_front_capacity();
|
|
|
|
void __add_front_capacity(size_type __n);
|
|
|
|
void __add_back_capacity();
|
|
|
|
void __add_back_capacity(size_type __n);
|
|
|
|
iterator __move_and_check(iterator __f, iterator __l, iterator __r,
|
|
|
|
const_pointer& __vt);
|
|
|
|
iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
|
|
|
|
const_pointer& __vt);
|
|
|
|
void __move_construct_and_check(iterator __f, iterator __l,
|
|
|
|
iterator __r, const_pointer& __vt);
|
|
|
|
void __move_construct_backward_and_check(iterator __f, iterator __l,
|
|
|
|
iterator __r, const_pointer& __vt);
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
void __copy_assign_alloc(const deque& __c)
|
|
|
|
{__copy_assign_alloc(__c, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_copy_assignment::value>());}
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
void __copy_assign_alloc(const deque& __c, true_type)
|
|
|
|
{
|
|
|
|
if (__base::__alloc() != __c.__alloc())
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
shrink_to_fit();
|
|
|
|
}
|
|
|
|
__base::__alloc() = __c.__alloc();
|
|
|
|
__base::__map_.__alloc() = __c.__map_.__alloc();
|
|
|
|
}
|
|
|
|
|
2010-09-21 21:28:23 +00:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-12-01 20:21:04 +00:00
|
|
|
void __copy_assign_alloc(const deque&, false_type)
|
2010-05-11 19:42:16 +00:00
|
|
|
{}
|
|
|
|
|
2011-06-02 21:38:57 +00:00
|
|
|
void __move_assign(deque& __c, true_type)
|
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
|
2010-05-11 19:42:16 +00:00
|
|
|
void __move_assign(deque& __c, false_type);
|
|
|
|
};
|
|
|
|
|
2021-08-17 11:59:07 -04:00
|
|
|
#if _LIBCPP_STD_VER >= 17
|
2018-05-18 23:44:13 +00:00
|
|
|
template<class _InputIterator,
|
2021-03-03 23:02:20 -05:00
|
|
|
class _Alloc = allocator<__iter_value_type<_InputIterator>>,
|
2021-11-09 09:21:02 -08:00
|
|
|
class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-17 12:26:09 -04:00
|
|
|
class = enable_if_t<__is_allocator<_Alloc>::value>
|
2018-05-18 23:44:13 +00:00
|
|
|
>
|
|
|
|
deque(_InputIterator, _InputIterator)
|
2021-03-03 23:02:20 -05:00
|
|
|
-> deque<__iter_value_type<_InputIterator>, _Alloc>;
|
2018-05-18 23:44:13 +00:00
|
|
|
|
|
|
|
template<class _InputIterator,
|
|
|
|
class _Alloc,
|
2021-11-09 09:21:02 -08:00
|
|
|
class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-17 12:26:09 -04:00
|
|
|
class = enable_if_t<__is_allocator<_Alloc>::value>
|
2018-05-18 23:44:13 +00:00
|
|
|
>
|
|
|
|
deque(_InputIterator, _InputIterator, _Alloc)
|
2021-03-03 23:02:20 -05:00
|
|
|
-> deque<__iter_value_type<_InputIterator>, _Alloc>;
|
2018-05-18 23:44:13 +00:00
|
|
|
#endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>::deque(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
__append(__n);
|
|
|
|
}
|
|
|
|
|
2013-09-07 16:16:19 +00:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
|
|
|
|
: __base(__a)
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
__append(__n);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
|
|
|
|
{
|
|
|
|
if (__n > 0)
|
|
|
|
__append(__n, __v);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIter>
|
|
|
|
deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__append(__f, __l);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIter>
|
|
|
|
deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
: __base(__a)
|
|
|
|
{
|
|
|
|
__append(__f, __l);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>::deque(const deque& __c)
|
|
|
|
: __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
|
|
|
|
{
|
|
|
|
__append(__c.begin(), __c.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2022-03-18 17:49:02 +01:00
|
|
|
deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a)
|
2010-05-11 19:42:16 +00:00
|
|
|
: __base(__a)
|
|
|
|
{
|
|
|
|
__append(__c.begin(), __c.end());
|
|
|
|
}
|
|
|
|
|
2017-04-16 03:17:01 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>&
|
|
|
|
deque<_Tp, _Allocator>::operator=(const deque& __c)
|
|
|
|
{
|
2021-09-28 19:15:18 +02:00
|
|
|
if (this != _VSTD::addressof(__c))
|
2017-04-16 03:17:01 +00:00
|
|
|
{
|
|
|
|
__copy_assign_alloc(__c);
|
|
|
|
assign(__c.begin(), __c.end());
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-08-12 21:56:02 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
|
|
|
|
{
|
|
|
|
__append(__il.begin(), __il.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
|
|
|
|
: __base(__a)
|
|
|
|
{
|
|
|
|
__append(__il.begin(), __il.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
deque<_Tp, _Allocator>::deque(deque&& __c)
|
2011-06-02 20:00:14 +00:00
|
|
|
_NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
|
2011-06-30 21:18:19 +00:00
|
|
|
: __base(_VSTD::move(__c))
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2022-03-18 17:49:02 +01:00
|
|
|
deque<_Tp, _Allocator>::deque(deque&& __c, const __type_identity_t<allocator_type>& __a)
|
2011-06-30 21:18:19 +00:00
|
|
|
: __base(_VSTD::move(__c), __a)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
if (__a != __c.__alloc())
|
|
|
|
{
|
2011-11-29 18:15:50 +00:00
|
|
|
typedef move_iterator<iterator> _Ip;
|
|
|
|
assign(_Ip(__c.begin()), _Ip(__c.end()));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
deque<_Tp, _Allocator>&
|
|
|
|
deque<_Tp, _Allocator>::operator=(deque&& __c)
|
2011-06-02 21:38:57 +00:00
|
|
|
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
|
|
|
|
is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__move_assign(__c, integral_constant<bool,
|
|
|
|
__alloc_traits::propagate_on_container_move_assignment::value>());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
|
|
|
|
{
|
|
|
|
if (__base::__alloc() != __c.__alloc())
|
|
|
|
{
|
2011-11-29 18:15:50 +00:00
|
|
|
typedef move_iterator<iterator> _Ip;
|
|
|
|
assign(_Ip(__c.begin()), _Ip(__c.end()));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
__move_assign(__c, true_type());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
|
2011-06-02 21:38:57 +00:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
clear();
|
|
|
|
shrink_to_fit();
|
|
|
|
__base::__move_assign(__c);
|
|
|
|
}
|
|
|
|
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIter>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value &&
|
|
|
|
!__is_cpp17_random_access_iterator<_InputIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
iterator __i = __base::begin();
|
|
|
|
iterator __e = __base::end();
|
2014-10-27 19:28:20 +00:00
|
|
|
for (; __f != __l && __i != __e; ++__f, (void) ++__i)
|
2010-05-11 19:42:16 +00:00
|
|
|
*__i = *__f;
|
|
|
|
if (__f != __l)
|
|
|
|
__append(__f, __l);
|
|
|
|
else
|
|
|
|
__erase_to_end(__i);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _RAIter>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
if (static_cast<size_type>(__l - __f) > __base::size())
|
|
|
|
{
|
|
|
|
_RAIter __m = __f + __base::size();
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::copy(__f, __m, __base::begin());
|
2010-05-11 19:42:16 +00:00
|
|
|
__append(__m, __l);
|
|
|
|
}
|
|
|
|
else
|
2011-06-30 21:18:19 +00:00
|
|
|
__erase_to_end(_VSTD::copy(__f, __l, __base::begin()));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
|
|
|
|
{
|
|
|
|
if (__n > __base::size())
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::fill_n(__base::begin(), __base::size(), __v);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __base::size();
|
|
|
|
__append(__n, __v);
|
|
|
|
}
|
|
|
|
else
|
2011-06-30 21:18:19 +00:00
|
|
|
__erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
_Allocator
|
2011-06-02 16:10:22 +00:00
|
|
|
deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
return __base::__alloc();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::resize(size_type __n)
|
|
|
|
{
|
|
|
|
if (__n > __base::size())
|
|
|
|
__append(__n - __base::size());
|
|
|
|
else if (__n < __base::size())
|
|
|
|
__erase_to_end(__base::begin() + __n);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
|
|
|
|
{
|
|
|
|
if (__n > __base::size())
|
|
|
|
__append(__n - __base::size(), __v);
|
|
|
|
else if (__n < __base::size())
|
|
|
|
__erase_to_end(__base::begin() + __n);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
2011-06-02 21:38:57 +00:00
|
|
|
deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (empty())
|
|
|
|
{
|
|
|
|
while (__base::__map_.size() > 0)
|
|
|
|
{
|
|
|
|
__alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
}
|
|
|
|
__base::__start_ = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-08-01 23:11:18 +00:00
|
|
|
__maybe_remove_front_spare(/*__keep_one=*/false);
|
|
|
|
__maybe_remove_back_spare(/*__keep_one=*/false);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
__base::__map_.shrink_to_fit();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::reference
|
2019-03-14 21:56:57 +00:00
|
|
|
deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __p = __base::__start_ + __i;
|
|
|
|
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::const_reference
|
2019-03-14 21:56:57 +00:00
|
|
|
deque<_Tp, _Allocator>::operator[](size_type __i) const _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __p = __base::__start_ + __i;
|
|
|
|
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::reference
|
|
|
|
deque<_Tp, _Allocator>::at(size_type __i)
|
|
|
|
{
|
|
|
|
if (__i >= __base::size())
|
2021-08-19 12:15:31 -04:00
|
|
|
_VSTD::__throw_out_of_range("deque");
|
2010-05-11 19:42:16 +00:00
|
|
|
size_type __p = __base::__start_ + __i;
|
|
|
|
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::const_reference
|
|
|
|
deque<_Tp, _Allocator>::at(size_type __i) const
|
|
|
|
{
|
|
|
|
if (__i >= __base::size())
|
2021-08-19 12:15:31 -04:00
|
|
|
_VSTD::__throw_out_of_range("deque");
|
2010-05-11 19:42:16 +00:00
|
|
|
size_type __p = __base::__start_ + __i;
|
|
|
|
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::reference
|
2019-03-19 03:30:07 +00:00
|
|
|
deque<_Tp, _Allocator>::front() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
|
|
|
|
+ __base::__start_ % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::const_reference
|
2019-03-19 03:30:07 +00:00
|
|
|
deque<_Tp, _Allocator>::front() const _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
|
|
|
|
+ __base::__start_ % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::reference
|
2019-03-19 03:30:07 +00:00
|
|
|
deque<_Tp, _Allocator>::back() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __p = __base::size() + __base::__start_ - 1;
|
|
|
|
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::const_reference
|
2019-03-19 03:30:07 +00:00
|
|
|
deque<_Tp, _Allocator>::back() const _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __p = __base::size() + __base::__start_ - 1;
|
|
|
|
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::push_back(const value_type& __v)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__back_spare() == 0)
|
|
|
|
__add_back_capacity();
|
|
|
|
// __back_spare() >= 1
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
|
2017-04-16 03:17:01 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::push_front(const value_type& __v)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__front_spare() == 0)
|
|
|
|
__add_front_capacity();
|
|
|
|
// __front_spare() >= 1
|
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
|
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
|
2017-04-16 03:17:01 +00:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::push_back(value_type&& __v)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__back_spare() == 0)
|
|
|
|
__add_back_capacity();
|
|
|
|
// __back_spare() >= 1
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class... _Args>
|
2017-01-24 23:09:12 +00:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 03:20:17 +00:00
|
|
|
typename deque<_Tp, _Allocator>::reference
|
2017-01-24 23:09:12 +00:00
|
|
|
#else
|
|
|
|
void
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__back_spare() == 0)
|
|
|
|
__add_back_capacity();
|
|
|
|
// __back_spare() >= 1
|
2016-07-21 03:20:17 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__base::end()),
|
|
|
|
_VSTD::forward<_Args>(__args)...);
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
2017-01-24 23:09:12 +00:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 03:20:17 +00:00
|
|
|
return *--__base::end();
|
2017-01-24 23:09:12 +00:00
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::push_front(value_type&& __v)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__front_spare() == 0)
|
|
|
|
__add_front_capacity();
|
|
|
|
// __front_spare() >= 1
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
|
2010-09-04 23:28:19 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class... _Args>
|
2017-01-24 23:09:12 +00:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 03:20:17 +00:00
|
|
|
typename deque<_Tp, _Allocator>::reference
|
2017-01-24 23:09:12 +00:00
|
|
|
#else
|
|
|
|
void
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__front_spare() == 0)
|
|
|
|
__add_front_capacity();
|
|
|
|
// __front_spare() >= 1
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
2017-01-24 23:09:12 +00:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2016-07-21 03:20:17 +00:00
|
|
|
return *__base::begin();
|
2017-01-24 23:09:12 +00:00
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
2017-04-16 03:17:01 +00:00
|
|
|
deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __pos = __p - __base::begin();
|
|
|
|
size_type __to_end = __base::size() - __pos;
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__pos < __to_end)
|
|
|
|
{ // insert by shifting things backward
|
|
|
|
if (__front_spare() == 0)
|
|
|
|
__add_front_capacity();
|
|
|
|
// __front_spare() >= 1
|
|
|
|
if (__pos == 0)
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
iterator __b = __base::begin();
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __bm1 = _VSTD::prev(__b);
|
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
if (__pos > 1)
|
2017-04-16 03:17:01 +00:00
|
|
|
__b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
|
|
|
|
*__b = _VSTD::move(__v);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // insert by shifting things forward
|
|
|
|
if (__back_spare() == 0)
|
|
|
|
__add_back_capacity();
|
|
|
|
// __back_capacity >= 1
|
|
|
|
size_type __de = __base::size() - __pos;
|
|
|
|
if (__de == 0)
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
iterator __e = __base::end();
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __em1 = _VSTD::prev(__e);
|
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
if (__de > 1)
|
2017-04-16 03:17:01 +00:00
|
|
|
__e = _VSTD::move_backward(__e - __de, __em1, __e);
|
|
|
|
*--__e = _VSTD::move(__v);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2017-04-16 03:17:01 +00:00
|
|
|
template <class... _Args>
|
2010-05-11 19:42:16 +00:00
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
2017-04-16 03:17:01 +00:00
|
|
|
deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __pos = __p - __base::begin();
|
|
|
|
size_type __to_end = __base::size() - __pos;
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__pos < __to_end)
|
|
|
|
{ // insert by shifting things backward
|
|
|
|
if (__front_spare() == 0)
|
|
|
|
__add_front_capacity();
|
|
|
|
// __front_spare() >= 1
|
|
|
|
if (__pos == 0)
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
|
2010-05-11 19:42:16 +00:00
|
|
|
iterator __b = __base::begin();
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __bm1 = _VSTD::prev(__b);
|
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
if (__pos > 1)
|
2011-06-30 21:18:19 +00:00
|
|
|
__b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
|
2017-04-16 03:17:01 +00:00
|
|
|
*__b = _VSTD::move(__tmp.get());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // insert by shifting things forward
|
|
|
|
if (__back_spare() == 0)
|
|
|
|
__add_back_capacity();
|
|
|
|
// __back_capacity >= 1
|
|
|
|
size_type __de = __base::size() - __pos;
|
|
|
|
if (__de == 0)
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
|
2010-05-11 19:42:16 +00:00
|
|
|
iterator __e = __base::end();
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __em1 = _VSTD::prev(__e);
|
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
if (__de > 1)
|
2011-06-30 21:18:19 +00:00
|
|
|
__e = _VSTD::move_backward(__e - __de, __em1, __e);
|
2017-04-16 03:17:01 +00:00
|
|
|
*--__e = _VSTD::move(__tmp.get());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2017-04-16 03:17:01 +00:00
|
|
|
|
2010-09-04 23:28:19 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
2017-04-16 03:17:01 +00:00
|
|
|
deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
size_type __pos = __p - __base::begin();
|
|
|
|
size_type __to_end = __base::size() - __pos;
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__pos < __to_end)
|
|
|
|
{ // insert by shifting things backward
|
|
|
|
if (__front_spare() == 0)
|
|
|
|
__add_front_capacity();
|
|
|
|
// __front_spare() >= 1
|
|
|
|
if (__pos == 0)
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
|
2010-05-11 19:42:16 +00:00
|
|
|
iterator __b = __base::begin();
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __bm1 = _VSTD::prev(__b);
|
2017-04-16 03:17:01 +00:00
|
|
|
if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
|
|
|
|
__vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
if (__pos > 1)
|
2017-04-16 03:17:01 +00:00
|
|
|
__b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
|
|
|
|
*__b = *__vt;
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // insert by shifting things forward
|
|
|
|
if (__back_spare() == 0)
|
|
|
|
__add_back_capacity();
|
|
|
|
// __back_capacity >= 1
|
|
|
|
size_type __de = __base::size() - __pos;
|
|
|
|
if (__de == 0)
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-16 03:17:01 +00:00
|
|
|
const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
|
2010-05-11 19:42:16 +00:00
|
|
|
iterator __e = __base::end();
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __em1 = _VSTD::prev(__e);
|
2017-04-16 03:17:01 +00:00
|
|
|
if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
|
|
|
|
__vt = pointer_traits<const_pointer>::pointer_to(*__e);
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
|
2010-05-11 19:42:16 +00:00
|
|
|
++__base::size();
|
|
|
|
if (__de > 1)
|
2017-04-16 03:17:01 +00:00
|
|
|
__e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
|
|
|
|
*--__e = *__vt;
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
|
|
|
|
{
|
|
|
|
size_type __pos = __p - __base::begin();
|
|
|
|
size_type __to_end = __base::size() - __pos;
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__pos < __to_end)
|
|
|
|
{ // insert by shifting things backward
|
|
|
|
if (__n > __front_spare())
|
|
|
|
__add_front_capacity(__n - __front_spare());
|
|
|
|
// __n <= __front_spare()
|
|
|
|
iterator __old_begin = __base::begin();
|
|
|
|
iterator __i = __old_begin;
|
|
|
|
if (__n > __pos)
|
|
|
|
{
|
|
|
|
for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n = __pos;
|
|
|
|
}
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
|
|
|
|
iterator __obn = __old_begin + __n;
|
|
|
|
__move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
|
|
|
|
if (__n < __pos)
|
|
|
|
__old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::fill_n(__old_begin, __n, *__vt);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // insert by shifting things forward
|
|
|
|
size_type __back_capacity = __back_spare();
|
|
|
|
if (__n > __back_capacity)
|
|
|
|
__add_back_capacity(__n - __back_capacity);
|
|
|
|
// __n <= __back_capacity
|
|
|
|
iterator __old_end = __base::end();
|
|
|
|
iterator __i = __old_end;
|
|
|
|
size_type __de = __base::size() - __pos;
|
|
|
|
if (__n > __de)
|
|
|
|
{
|
2021-09-07 21:35:37 -04:00
|
|
|
for (size_type __m = __n - __de; __m; --__m, (void) ++__i, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n = __de;
|
|
|
|
}
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
|
|
|
|
iterator __oen = __old_end - __n;
|
|
|
|
__move_construct_and_check(__oen, __old_end, __i, __vt);
|
|
|
|
if (__n < __de)
|
|
|
|
__old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::fill_n(__old_end - __n, __n, *__vt);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InputIter>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
|
2022-07-04 22:45:49 +02:00
|
|
|
typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
|
|
|
|
__buf.__construct_at_end(__f, __l);
|
|
|
|
typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
|
|
|
|
return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
|
|
|
|
}
|
|
|
|
|
2015-01-22 18:33:29 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForwardIterator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
|
2022-07-04 22:45:49 +02:00
|
|
|
typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
|
2015-01-22 18:33:29 +00:00
|
|
|
{
|
|
|
|
size_type __n = _VSTD::distance(__f, __l);
|
|
|
|
__split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
|
|
|
|
__buf.__construct_at_end(__f, __l);
|
|
|
|
typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
|
|
|
|
return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
|
|
|
|
}
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _BiIter>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
size_type __n = _VSTD::distance(__f, __l);
|
2010-05-11 19:42:16 +00:00
|
|
|
size_type __pos = __p - __base::begin();
|
|
|
|
size_type __to_end = __base::size() - __pos;
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__pos < __to_end)
|
|
|
|
{ // insert by shifting things backward
|
|
|
|
if (__n > __front_spare())
|
|
|
|
__add_front_capacity(__n - __front_spare());
|
|
|
|
// __n <= __front_spare()
|
|
|
|
iterator __old_begin = __base::begin();
|
|
|
|
iterator __i = __old_begin;
|
|
|
|
_BiIter __m = __f;
|
|
|
|
if (__n > __pos)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
|
2010-05-11 19:42:16 +00:00
|
|
|
for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n = __pos;
|
|
|
|
}
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
iterator __obn = __old_begin + __n;
|
|
|
|
for (iterator __j = __obn; __j != __old_begin;)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
if (__n < __pos)
|
2011-06-30 21:18:19 +00:00
|
|
|
__old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
|
|
|
|
_VSTD::copy(__m, __l, __old_begin);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // insert by shifting things forward
|
|
|
|
size_type __back_capacity = __back_spare();
|
|
|
|
if (__n > __back_capacity)
|
|
|
|
__add_back_capacity(__n - __back_capacity);
|
|
|
|
// __n <= __back_capacity
|
|
|
|
iterator __old_end = __base::end();
|
|
|
|
iterator __i = __old_end;
|
|
|
|
_BiIter __m = __l;
|
|
|
|
size_type __de = __base::size() - __pos;
|
|
|
|
if (__n > __de)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
|
2014-10-27 19:28:20 +00:00
|
|
|
for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n = __de;
|
|
|
|
}
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
iterator __oen = __old_end - __n;
|
2021-09-07 21:35:37 -04:00
|
|
|
for (iterator __j = __oen; __j != __old_end; ++__i, (void) ++__j, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
|
2010-05-11 19:42:16 +00:00
|
|
|
if (__n < __de)
|
2011-06-30 21:18:19 +00:00
|
|
|
__old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
|
|
|
|
_VSTD::copy_backward(__f, __m, __old_end);
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _InpIter>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
|
2022-07-04 22:45:49 +02:00
|
|
|
typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
for (; __f != __l; ++__f)
|
2017-10-17 13:03:17 +00:00
|
|
|
#ifdef _LIBCPP_CXX03_LANG
|
2010-05-11 19:42:16 +00:00
|
|
|
push_back(*__f);
|
2017-10-17 13:03:17 +00:00
|
|
|
#else
|
|
|
|
emplace_back(*__f);
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
template <class _ForIter>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
|
2019-11-18 01:46:58 -05:00
|
|
|
typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*)
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
size_type __n = _VSTD::distance(__f, __l);
|
2010-05-11 19:42:16 +00:00
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
size_type __back_capacity = __back_spare();
|
|
|
|
if (__n > __back_capacity)
|
|
|
|
__add_back_capacity(__n - __back_capacity);
|
|
|
|
// __n <= __back_capacity
|
2019-08-12 07:51:05 +00:00
|
|
|
for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
|
|
|
|
_ConstructTransaction __tx(this, __br);
|
|
|
|
for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) {
|
2020-11-18 18:54:38 -05:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f);
|
2019-08-12 07:51:05 +00:00
|
|
|
}
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__append(size_type __n)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
size_type __back_capacity = __back_spare();
|
|
|
|
if (__n > __back_capacity)
|
|
|
|
__add_back_capacity(__n - __back_capacity);
|
|
|
|
// __n <= __back_capacity
|
2019-08-12 07:51:05 +00:00
|
|
|
for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
|
|
|
|
_ConstructTransaction __tx(this, __br);
|
|
|
|
for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
|
2020-11-18 18:54:38 -05:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_));
|
2019-08-12 07:51:05 +00:00
|
|
|
}
|
|
|
|
}
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
size_type __back_capacity = __back_spare();
|
|
|
|
if (__n > __back_capacity)
|
|
|
|
__add_back_capacity(__n - __back_capacity);
|
|
|
|
// __n <= __back_capacity
|
2019-08-12 07:51:05 +00:00
|
|
|
for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) {
|
|
|
|
_ConstructTransaction __tx(this, __br);
|
|
|
|
for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
|
2020-11-18 18:54:38 -05:00
|
|
|
__alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v);
|
2019-08-12 07:51:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create front capacity for one block of elements.
|
|
|
|
// Strong guarantee. Either do it or don't touch anything.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__add_front_capacity()
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__back_spare() >= __base::__block_size)
|
|
|
|
{
|
|
|
|
__base::__start_ += __base::__block_size;
|
|
|
|
pointer __pt = __base::__map_.back();
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
__base::__map_.push_front(__pt);
|
|
|
|
}
|
|
|
|
// Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
|
|
|
|
else if (__base::__map_.size() < __base::__map_.capacity())
|
|
|
|
{ // we can put the new buffer into the map, but don't shift things around
|
|
|
|
// until all buffers are allocated. If we throw, we don't need to fix
|
|
|
|
// anything up (any added buffers are undetectible)
|
|
|
|
if (__base::__map_.__front_spare() > 0)
|
|
|
|
__base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
// Done allocating, reorder capacity
|
|
|
|
pointer __pt = __base::__map_.back();
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
__base::__map_.push_front(__pt);
|
|
|
|
}
|
|
|
|
__base::__start_ = __base::__map_.size() == 1 ?
|
|
|
|
__base::__block_size / 2 :
|
|
|
|
__base::__start_ + __base::__block_size;
|
|
|
|
}
|
|
|
|
// Else need to allocate 1 buffer, *and* we need to reallocate __map_.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__split_buffer<pointer, typename __base::__pointer_allocator&>
|
|
|
|
__buf(max<size_type>(2 * __base::__map_.capacity(), 1),
|
|
|
|
0, __base::__map_.__alloc());
|
2015-03-09 17:08:51 +00:00
|
|
|
|
2015-07-13 20:04:56 +00:00
|
|
|
typedef __allocator_destructor<_Allocator> _Dp;
|
|
|
|
unique_ptr<pointer, _Dp> __hold(
|
|
|
|
__alloc_traits::allocate(__a, __base::__block_size),
|
|
|
|
_Dp(__a, __base::__block_size));
|
|
|
|
__buf.push_back(__hold.get());
|
|
|
|
__hold.release();
|
2018-12-12 23:58:25 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
for (typename __base::__map_pointer __i = __base::__map_.begin();
|
|
|
|
__i != __base::__map_.end(); ++__i)
|
|
|
|
__buf.push_back(*__i);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::swap(__base::__map_.__first_, __buf.__first_);
|
|
|
|
_VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_, __buf.__end_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
|
2010-05-11 19:42:16 +00:00
|
|
|
__base::__start_ = __base::__map_.size() == 1 ?
|
|
|
|
__base::__block_size / 2 :
|
|
|
|
__base::__start_ + __base::__block_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create front capacity for __n elements.
|
|
|
|
// Strong guarantee. Either do it or don't touch anything.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
|
|
|
|
// Number of unused blocks at back:
|
|
|
|
size_type __back_capacity = __back_spare() / __base::__block_size;
|
2011-06-30 21:18:19 +00:00
|
|
|
__back_capacity = _VSTD::min(__back_capacity, __nb); // don't take more than you need
|
2010-05-11 19:42:16 +00:00
|
|
|
__nb -= __back_capacity; // number of blocks need to allocate
|
|
|
|
// If __nb == 0, then we have sufficient capacity.
|
|
|
|
if (__nb == 0)
|
|
|
|
{
|
|
|
|
__base::__start_ += __base::__block_size * __back_capacity;
|
|
|
|
for (; __back_capacity > 0; --__back_capacity)
|
|
|
|
{
|
|
|
|
pointer __pt = __base::__map_.back();
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
__base::__map_.push_front(__pt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
|
|
|
|
else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
|
|
|
|
{ // we can put the new buffers into the map, but don't shift things around
|
|
|
|
// until all buffers are allocated. If we throw, we don't need to fix
|
|
|
|
// anything up (any added buffers are undetectible)
|
|
|
|
for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
|
|
|
|
{
|
|
|
|
if (__base::__map_.__front_spare() == 0)
|
|
|
|
break;
|
|
|
|
__base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
}
|
|
|
|
for (; __nb > 0; --__nb, ++__back_capacity)
|
|
|
|
__base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
// Done allocating, reorder capacity
|
|
|
|
__base::__start_ += __back_capacity * __base::__block_size;
|
|
|
|
for (; __back_capacity > 0; --__back_capacity)
|
|
|
|
{
|
|
|
|
pointer __pt = __base::__map_.back();
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
__base::__map_.push_front(__pt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Else need to allocate __nb buffers, *and* we need to reallocate __map_.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
|
|
|
|
__split_buffer<pointer, typename __base::__pointer_allocator&>
|
|
|
|
__buf(max<size_type>(2* __base::__map_.capacity(),
|
|
|
|
__nb + __base::__map_.size()),
|
|
|
|
0, __base::__map_.__alloc());
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
try
|
|
|
|
{
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-11 19:42:16 +00:00
|
|
|
for (; __nb > 0; --__nb)
|
|
|
|
__buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
for (typename __base::__map_pointer __i = __buf.begin();
|
|
|
|
__i != __buf.end(); ++__i)
|
|
|
|
__alloc_traits::deallocate(__a, *__i, __base::__block_size);
|
|
|
|
throw;
|
|
|
|
}
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-11 19:42:16 +00:00
|
|
|
for (; __back_capacity > 0; --__back_capacity)
|
|
|
|
{
|
|
|
|
__buf.push_back(__base::__map_.back());
|
|
|
|
__base::__map_.pop_back();
|
|
|
|
}
|
|
|
|
for (typename __base::__map_pointer __i = __base::__map_.begin();
|
|
|
|
__i != __base::__map_.end(); ++__i)
|
|
|
|
__buf.push_back(*__i);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::swap(__base::__map_.__first_, __buf.__first_);
|
|
|
|
_VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_, __buf.__end_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
|
2010-05-11 19:42:16 +00:00
|
|
|
__base::__start_ += __ds;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create back capacity for one block of elements.
|
|
|
|
// Strong guarantee. Either do it or don't touch anything.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__add_back_capacity()
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
if (__front_spare() >= __base::__block_size)
|
|
|
|
{
|
|
|
|
__base::__start_ -= __base::__block_size;
|
|
|
|
pointer __pt = __base::__map_.front();
|
|
|
|
__base::__map_.pop_front();
|
|
|
|
__base::__map_.push_back(__pt);
|
|
|
|
}
|
|
|
|
// Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
|
|
|
|
else if (__base::__map_.size() < __base::__map_.capacity())
|
|
|
|
{ // we can put the new buffer into the map, but don't shift things around
|
|
|
|
// until it is allocated. If we throw, we don't need to fix
|
|
|
|
// anything up (any added buffers are undetectible)
|
|
|
|
if (__base::__map_.__back_spare() != 0)
|
|
|
|
__base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
// Done allocating, reorder capacity
|
|
|
|
pointer __pt = __base::__map_.front();
|
|
|
|
__base::__map_.pop_front();
|
|
|
|
__base::__map_.push_back(__pt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Else need to allocate 1 buffer, *and* we need to reallocate __map_.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__split_buffer<pointer, typename __base::__pointer_allocator&>
|
|
|
|
__buf(max<size_type>(2* __base::__map_.capacity(), 1),
|
|
|
|
__base::__map_.size(),
|
|
|
|
__base::__map_.__alloc());
|
2015-03-09 17:08:51 +00:00
|
|
|
|
2015-07-13 20:04:56 +00:00
|
|
|
typedef __allocator_destructor<_Allocator> _Dp;
|
|
|
|
unique_ptr<pointer, _Dp> __hold(
|
|
|
|
__alloc_traits::allocate(__a, __base::__block_size),
|
|
|
|
_Dp(__a, __base::__block_size));
|
|
|
|
__buf.push_back(__hold.get());
|
|
|
|
__hold.release();
|
2015-03-09 17:08:51 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
for (typename __base::__map_pointer __i = __base::__map_.end();
|
|
|
|
__i != __base::__map_.begin();)
|
|
|
|
__buf.push_front(*--__i);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::swap(__base::__map_.__first_, __buf.__first_);
|
|
|
|
_VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_, __buf.__end_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create back capacity for __n elements.
|
|
|
|
// Strong guarantee. Either do it or don't touch anything.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
|
|
|
|
// Number of unused blocks at front:
|
|
|
|
size_type __front_capacity = __front_spare() / __base::__block_size;
|
2011-06-30 21:18:19 +00:00
|
|
|
__front_capacity = _VSTD::min(__front_capacity, __nb); // don't take more than you need
|
2010-05-11 19:42:16 +00:00
|
|
|
__nb -= __front_capacity; // number of blocks need to allocate
|
|
|
|
// If __nb == 0, then we have sufficient capacity.
|
|
|
|
if (__nb == 0)
|
|
|
|
{
|
|
|
|
__base::__start_ -= __base::__block_size * __front_capacity;
|
|
|
|
for (; __front_capacity > 0; --__front_capacity)
|
|
|
|
{
|
|
|
|
pointer __pt = __base::__map_.front();
|
|
|
|
__base::__map_.pop_front();
|
|
|
|
__base::__map_.push_back(__pt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
|
|
|
|
else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
|
|
|
|
{ // we can put the new buffers into the map, but don't shift things around
|
|
|
|
// until all buffers are allocated. If we throw, we don't need to fix
|
|
|
|
// anything up (any added buffers are undetectible)
|
|
|
|
for (; __nb > 0; --__nb)
|
|
|
|
{
|
|
|
|
if (__base::__map_.__back_spare() == 0)
|
|
|
|
break;
|
|
|
|
__base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
}
|
|
|
|
for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
|
|
|
|
__base::__block_size - (__base::__map_.size() == 1))
|
|
|
|
__base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
// Done allocating, reorder capacity
|
|
|
|
__base::__start_ -= __base::__block_size * __front_capacity;
|
|
|
|
for (; __front_capacity > 0; --__front_capacity)
|
|
|
|
{
|
|
|
|
pointer __pt = __base::__map_.front();
|
|
|
|
__base::__map_.pop_front();
|
|
|
|
__base::__map_.push_back(__pt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Else need to allocate __nb buffers, *and* we need to reallocate __map_.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_type __ds = __front_capacity * __base::__block_size;
|
|
|
|
__split_buffer<pointer, typename __base::__pointer_allocator&>
|
|
|
|
__buf(max<size_type>(2* __base::__map_.capacity(),
|
|
|
|
__nb + __base::__map_.size()),
|
|
|
|
__base::__map_.size() - __front_capacity,
|
|
|
|
__base::__map_.__alloc());
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
try
|
|
|
|
{
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-11 19:42:16 +00:00
|
|
|
for (; __nb > 0; --__nb)
|
|
|
|
__buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
for (typename __base::__map_pointer __i = __buf.begin();
|
|
|
|
__i != __buf.end(); ++__i)
|
|
|
|
__alloc_traits::deallocate(__a, *__i, __base::__block_size);
|
|
|
|
throw;
|
|
|
|
}
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
2010-05-11 19:42:16 +00:00
|
|
|
for (; __front_capacity > 0; --__front_capacity)
|
|
|
|
{
|
|
|
|
__buf.push_back(__base::__map_.front());
|
|
|
|
__base::__map_.pop_front();
|
|
|
|
}
|
|
|
|
for (typename __base::__map_pointer __i = __base::__map_.end();
|
|
|
|
__i != __base::__map_.begin();)
|
|
|
|
__buf.push_front(*--__i);
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::swap(__base::__map_.__first_, __buf.__first_);
|
|
|
|
_VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_, __buf.__end_);
|
|
|
|
_VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
|
2010-05-11 19:42:16 +00:00
|
|
|
__base::__start_ -= __ds;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::pop_front()
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
2020-11-18 18:54:38 -05:00
|
|
|
__alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
|
2013-06-23 21:17:24 +00:00
|
|
|
__base::__start_ / __base::__block_size) +
|
|
|
|
__base::__start_ % __base::__block_size));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::size();
|
2019-08-01 23:11:18 +00:00
|
|
|
++__base::__start_;
|
|
|
|
__maybe_remove_front_spare();
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::pop_back()
|
|
|
|
{
|
2021-05-09 19:29:56 +02:00
|
|
|
_LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque");
|
2010-05-11 19:42:16 +00:00
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
size_type __p = __base::size() + __base::__start_ - 1;
|
2020-11-18 18:54:38 -05:00
|
|
|
__alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() +
|
2013-06-23 21:17:24 +00:00
|
|
|
__p / __base::__block_size) +
|
|
|
|
__p % __base::__block_size));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::size();
|
2019-08-01 23:11:18 +00:00
|
|
|
__maybe_remove_back_spare();
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// move assign [__f, __l) to [__r, __r + (__l-__f)).
|
|
|
|
// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
|
|
|
|
const_pointer& __vt)
|
|
|
|
{
|
|
|
|
// as if
|
|
|
|
// for (; __f != __l; ++__f, ++__r)
|
2011-06-30 21:18:19 +00:00
|
|
|
// *__r = _VSTD::move(*__f);
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
pointer __fb = __f.__ptr_;
|
|
|
|
pointer __fe = *__f.__m_iter_ + __base::__block_size;
|
|
|
|
difference_type __bs = __fe - __fb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__fe = __fb + __bs;
|
|
|
|
}
|
|
|
|
if (__fb <= __vt && __vt < __fe)
|
2013-06-23 21:17:24 +00:00
|
|
|
__vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::move(__fb, __fe, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__f += __bs;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
|
|
|
|
// If __vt points into [__f, __l), then add (__r - __l) to __vt.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
|
|
|
|
const_pointer& __vt)
|
|
|
|
{
|
|
|
|
// as if
|
|
|
|
// while (__f != __l)
|
2011-06-30 21:18:19 +00:00
|
|
|
// *--__r = _VSTD::move(*--__l);
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
--__l;
|
|
|
|
pointer __lb = *__l.__m_iter_;
|
|
|
|
pointer __le = __l.__ptr_ + 1;
|
|
|
|
difference_type __bs = __le - __lb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__lb = __le - __bs;
|
|
|
|
}
|
|
|
|
if (__lb <= __vt && __vt < __le)
|
2013-06-23 21:17:24 +00:00
|
|
|
__vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
|
2011-06-30 21:18:19 +00:00
|
|
|
__r = _VSTD::move_backward(__lb, __le, __r);
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__l -= __bs - 1;
|
|
|
|
}
|
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// move construct [__f, __l) to [__r, __r + (__l-__f)).
|
|
|
|
// If __vt points into [__f, __l), then add (__r - __f) to __vt.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
|
|
|
|
iterator __r, const_pointer& __vt)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
// as if
|
|
|
|
// for (; __f != __l; ++__r, ++__f, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
// __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
|
2010-05-11 19:42:16 +00:00
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
pointer __fb = __f.__ptr_;
|
|
|
|
pointer __fe = *__f.__m_iter_ + __base::__block_size;
|
|
|
|
difference_type __bs = __fe - __fb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__fe = __fb + __bs;
|
|
|
|
}
|
|
|
|
if (__fb <= __vt && __vt < __fe)
|
2013-06-23 21:17:24 +00:00
|
|
|
__vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
|
2010-05-11 19:42:16 +00:00
|
|
|
for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
|
2010-05-11 19:42:16 +00:00
|
|
|
__n -= __bs;
|
|
|
|
__f += __bs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
|
|
|
|
// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
|
|
|
|
iterator __r, const_pointer& __vt)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
// as if
|
|
|
|
// for (iterator __j = __l; __j != __f;)
|
|
|
|
// {
|
2011-06-30 21:18:19 +00:00
|
|
|
// __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
|
2010-05-11 19:42:16 +00:00
|
|
|
// --__base::__start_;
|
|
|
|
// ++__base::size();
|
|
|
|
// }
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
while (__n > 0)
|
|
|
|
{
|
|
|
|
--__l;
|
|
|
|
pointer __lb = *__l.__m_iter_;
|
|
|
|
pointer __le = __l.__ptr_ + 1;
|
|
|
|
difference_type __bs = __le - __lb;
|
|
|
|
if (__bs > __n)
|
|
|
|
{
|
|
|
|
__bs = __n;
|
|
|
|
__lb = __le - __bs;
|
|
|
|
}
|
|
|
|
if (__lb <= __vt && __vt < __le)
|
2013-06-23 21:17:24 +00:00
|
|
|
__vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
|
2010-05-11 19:42:16 +00:00
|
|
|
while (__le != __lb)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::__start_;
|
|
|
|
++__base::size();
|
|
|
|
}
|
|
|
|
__n -= __bs;
|
|
|
|
__l -= __bs - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::erase(const_iterator __f)
|
|
|
|
{
|
|
|
|
iterator __b = __base::begin();
|
|
|
|
difference_type __pos = __f - __b;
|
|
|
|
iterator __p = __b + __pos;
|
|
|
|
allocator_type& __a = __base::__alloc();
|
2016-12-24 00:24:44 +00:00
|
|
|
if (static_cast<size_t>(__pos) <= (__base::size() - 1) / 2)
|
2010-05-11 19:42:16 +00:00
|
|
|
{ // erase from front
|
2011-06-30 21:18:19 +00:00
|
|
|
_VSTD::move_backward(__b, __p, _VSTD::next(__p));
|
|
|
|
__alloc_traits::destroy(__a, _VSTD::addressof(*__b));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::size();
|
|
|
|
++__base::__start_;
|
2019-08-01 23:11:18 +00:00
|
|
|
__maybe_remove_front_spare();
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // erase from back
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);
|
|
|
|
__alloc_traits::destroy(__a, _VSTD::addressof(*__i));
|
2010-05-11 19:42:16 +00:00
|
|
|
--__base::size();
|
2019-08-01 23:11:18 +00:00
|
|
|
__maybe_remove_back_spare();
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
typename deque<_Tp, _Allocator>::iterator
|
|
|
|
deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
|
|
|
|
{
|
|
|
|
difference_type __n = __l - __f;
|
|
|
|
iterator __b = __base::begin();
|
|
|
|
difference_type __pos = __f - __b;
|
|
|
|
iterator __p = __b + __pos;
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
2016-12-24 00:24:44 +00:00
|
|
|
if (static_cast<size_t>(__pos) <= (__base::size() - __n) / 2)
|
2010-05-11 19:42:16 +00:00
|
|
|
{ // erase from front
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
|
2010-05-11 19:42:16 +00:00
|
|
|
for (; __b != __i; ++__b)
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::destroy(__a, _VSTD::addressof(*__b));
|
2010-05-11 19:42:16 +00:00
|
|
|
__base::size() -= __n;
|
|
|
|
__base::__start_ += __n;
|
2019-08-01 23:11:18 +00:00
|
|
|
while (__maybe_remove_front_spare()) {
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // erase from back
|
2011-06-30 21:18:19 +00:00
|
|
|
iterator __i = _VSTD::move(__p + __n, __base::end(), __p);
|
2010-05-11 19:42:16 +00:00
|
|
|
for (iterator __e = __base::end(); __i != __e; ++__i)
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::destroy(__a, _VSTD::addressof(*__i));
|
2010-05-11 19:42:16 +00:00
|
|
|
__base::size() -= __n;
|
2019-08-01 23:11:18 +00:00
|
|
|
while (__maybe_remove_back_spare()) {
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return __base::begin() + __pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
|
|
|
|
{
|
|
|
|
iterator __e = __base::end();
|
|
|
|
difference_type __n = __e - __f;
|
|
|
|
if (__n > 0)
|
|
|
|
{
|
|
|
|
allocator_type& __a = __base::__alloc();
|
|
|
|
iterator __b = __base::begin();
|
|
|
|
difference_type __pos = __f - __b;
|
|
|
|
for (iterator __p = __b + __pos; __p != __e; ++__p)
|
2011-06-30 21:18:19 +00:00
|
|
|
__alloc_traits::destroy(__a, _VSTD::addressof(*__p));
|
2010-05-11 19:42:16 +00:00
|
|
|
__base::size() -= __n;
|
2019-08-01 23:11:18 +00:00
|
|
|
while (__maybe_remove_back_spare()) {
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
void
|
|
|
|
deque<_Tp, _Allocator>::swap(deque& __c)
|
2015-07-13 20:04:56 +00:00
|
|
|
#if _LIBCPP_STD_VER >= 14
|
|
|
|
_NOEXCEPT
|
|
|
|
#else
|
2018-12-12 23:58:25 +00:00
|
|
|
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
|
2015-07-13 20:04:56 +00:00
|
|
|
__is_nothrow_swappable<allocator_type>::value)
|
|
|
|
#endif
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__base::swap(__c);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2015-11-07 01:22:13 +00:00
|
|
|
inline
|
2010-05-11 19:42:16 +00:00
|
|
|
void
|
2011-06-02 16:10:22 +00:00
|
|
|
deque<_Tp, _Allocator>::clear() _NOEXCEPT
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__base::clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool
|
|
|
|
operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
|
2011-06-30 21:18:19 +00:00
|
|
|
return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool
|
|
|
|
operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return !(__x == __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool
|
|
|
|
operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
|
|
|
|
{
|
2011-06-30 21:18:19 +00:00
|
|
|
return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
|
2010-05-11 19:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool
|
|
|
|
operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return __y < __x;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool
|
|
|
|
operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return !(__x < __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
bool
|
|
|
|
operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
|
|
|
|
{
|
|
|
|
return !(__y < __x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Allocator>
|
2013-10-04 22:09:00 +00:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2010-05-11 19:42:16 +00:00
|
|
|
void
|
|
|
|
swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
|
2011-06-02 20:00:14 +00:00
|
|
|
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
|
2010-05-11 19:42:16 +00:00
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
2018-12-14 18:49:35 +00:00
|
|
|
#if _LIBCPP_STD_VER > 17
|
|
|
|
template <class _Tp, class _Allocator, class _Up>
|
2020-05-02 13:58:03 +02:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
|
|
|
|
erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
|
|
|
|
auto __old_size = __c.size();
|
|
|
|
__c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
|
|
|
|
return __old_size - __c.size();
|
|
|
|
}
|
2018-12-14 18:49:35 +00:00
|
|
|
|
|
|
|
template <class _Tp, class _Allocator, class _Predicate>
|
2020-05-02 13:58:03 +02:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
|
|
|
|
erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
|
|
|
|
auto __old_size = __c.size();
|
|
|
|
__c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
|
|
|
|
return __old_size - __c.size();
|
|
|
|
}
|
2021-09-26 15:47:42 +02:00
|
|
|
|
|
|
|
template <>
|
|
|
|
inline constexpr bool __format::__enable_insertable<std::deque<char>> = true;
|
|
|
|
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
|
|
|
template <>
|
|
|
|
inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
|
2018-12-14 18:49:35 +00:00
|
|
|
#endif
|
|
|
|
|
2021-09-26 15:47:42 +02:00
|
|
|
#endif // _LIBCPP_STD_VER > 17
|
2018-12-14 18:49:35 +00:00
|
|
|
|
2010-05-11 19:42:16 +00:00
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
2017-05-31 22:07:49 +00:00
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
|
2021-04-20 12:03:32 -04:00
|
|
|
#endif // _LIBCPP_DEQUE
|