xref: /freebsd-12.1/contrib/libc++/include/deque (revision b5893f02)
17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===---------------------------- deque -----------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_DEQUE
127a984708SDavid Chisnall#define _LIBCPP_DEQUE
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall    deque synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207a984708SDavid Chisnalltemplate <class T, class Allocator = allocator<T> >
217a984708SDavid Chisnallclass deque
227a984708SDavid Chisnall{
237a984708SDavid Chisnallpublic:
247a984708SDavid Chisnall    // types:
257a984708SDavid Chisnall    typedef T value_type;
267a984708SDavid Chisnall    typedef Allocator allocator_type;
277a984708SDavid Chisnall
287a984708SDavid Chisnall    typedef typename allocator_type::reference       reference;
297a984708SDavid Chisnall    typedef typename allocator_type::const_reference const_reference;
307a984708SDavid Chisnall    typedef implementation-defined                   iterator;
317a984708SDavid Chisnall    typedef implementation-defined                   const_iterator;
327a984708SDavid Chisnall    typedef typename allocator_type::size_type       size_type;
337a984708SDavid Chisnall    typedef typename allocator_type::difference_type difference_type;
347a984708SDavid Chisnall
357a984708SDavid Chisnall    typedef typename allocator_type::pointer         pointer;
367a984708SDavid Chisnall    typedef typename allocator_type::const_pointer   const_pointer;
377a984708SDavid Chisnall    typedef std::reverse_iterator<iterator>          reverse_iterator;
387a984708SDavid Chisnall    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
397a984708SDavid Chisnall
407a984708SDavid Chisnall    // construct/copy/destroy:
417a984708SDavid Chisnall    deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
427a984708SDavid Chisnall    explicit deque(const allocator_type& a);
437a984708SDavid Chisnall    explicit deque(size_type n);
444f7ab58eSDimitry Andric    explicit deque(size_type n, const allocator_type& a); // C++14
457a984708SDavid Chisnall    deque(size_type n, const value_type& v);
467a984708SDavid Chisnall    deque(size_type n, const value_type& v, const allocator_type& a);
477a984708SDavid Chisnall    template <class InputIterator>
487a984708SDavid Chisnall        deque(InputIterator f, InputIterator l);
497a984708SDavid Chisnall    template <class InputIterator>
507a984708SDavid Chisnall        deque(InputIterator f, InputIterator l, const allocator_type& a);
517a984708SDavid Chisnall    deque(const deque& c);
527a984708SDavid Chisnall    deque(deque&& c)
537a984708SDavid Chisnall        noexcept(is_nothrow_move_constructible<allocator_type>::value);
547a984708SDavid Chisnall    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
557a984708SDavid Chisnall    deque(const deque& c, const allocator_type& a);
567a984708SDavid Chisnall    deque(deque&& c, const allocator_type& a);
577a984708SDavid Chisnall    ~deque();
587a984708SDavid Chisnall
597a984708SDavid Chisnall    deque& operator=(const deque& c);
607a984708SDavid Chisnall    deque& operator=(deque&& c)
617a984708SDavid Chisnall        noexcept(
627a984708SDavid Chisnall             allocator_type::propagate_on_container_move_assignment::value &&
637a984708SDavid Chisnall             is_nothrow_move_assignable<allocator_type>::value);
647a984708SDavid Chisnall    deque& operator=(initializer_list<value_type> il);
657a984708SDavid Chisnall
667a984708SDavid Chisnall    template <class InputIterator>
677a984708SDavid Chisnall        void assign(InputIterator f, InputIterator l);
687a984708SDavid Chisnall    void assign(size_type n, const value_type& v);
697a984708SDavid Chisnall    void assign(initializer_list<value_type> il);
707a984708SDavid Chisnall
717a984708SDavid Chisnall    allocator_type get_allocator() const noexcept;
727a984708SDavid Chisnall
737a984708SDavid Chisnall    // iterators:
747a984708SDavid Chisnall
757a984708SDavid Chisnall    iterator       begin() noexcept;
767a984708SDavid Chisnall    const_iterator begin() const noexcept;
777a984708SDavid Chisnall    iterator       end() noexcept;
787a984708SDavid Chisnall    const_iterator end() const noexcept;
797a984708SDavid Chisnall
807a984708SDavid Chisnall    reverse_iterator       rbegin() noexcept;
817a984708SDavid Chisnall    const_reverse_iterator rbegin() const noexcept;
827a984708SDavid Chisnall    reverse_iterator       rend() noexcept;
837a984708SDavid Chisnall    const_reverse_iterator rend() const noexcept;
847a984708SDavid Chisnall
857a984708SDavid Chisnall    const_iterator         cbegin() const noexcept;
867a984708SDavid Chisnall    const_iterator         cend() const noexcept;
877a984708SDavid Chisnall    const_reverse_iterator crbegin() const noexcept;
887a984708SDavid Chisnall    const_reverse_iterator crend() const noexcept;
897a984708SDavid Chisnall
907a984708SDavid Chisnall    // capacity:
917a984708SDavid Chisnall    size_type size() const noexcept;
927a984708SDavid Chisnall    size_type max_size() const noexcept;
937a984708SDavid Chisnall    void resize(size_type n);
947a984708SDavid Chisnall    void resize(size_type n, const value_type& v);
957a984708SDavid Chisnall    void shrink_to_fit();
967a984708SDavid Chisnall    bool empty() const noexcept;
977a984708SDavid Chisnall
987a984708SDavid Chisnall    // element access:
997a984708SDavid Chisnall    reference operator[](size_type i);
1007a984708SDavid Chisnall    const_reference operator[](size_type i) const;
1017a984708SDavid Chisnall    reference at(size_type i);
1027a984708SDavid Chisnall    const_reference at(size_type i) const;
1037a984708SDavid Chisnall    reference front();
1047a984708SDavid Chisnall    const_reference front() const;
1057a984708SDavid Chisnall    reference back();
1067a984708SDavid Chisnall    const_reference back() const;
1077a984708SDavid Chisnall
1087a984708SDavid Chisnall    // modifiers:
1097a984708SDavid Chisnall    void push_front(const value_type& v);
1107a984708SDavid Chisnall    void push_front(value_type&& v);
1117a984708SDavid Chisnall    void push_back(const value_type& v);
1127a984708SDavid Chisnall    void push_back(value_type&& v);
11398221d2eSDimitry Andric    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
11498221d2eSDimitry Andric    template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17
1157a984708SDavid Chisnall    template <class... Args> iterator emplace(const_iterator p, Args&&... args);
1167a984708SDavid Chisnall    iterator insert(const_iterator p, const value_type& v);
1177a984708SDavid Chisnall    iterator insert(const_iterator p, value_type&& v);
1187a984708SDavid Chisnall    iterator insert(const_iterator p, size_type n, const value_type& v);
1197a984708SDavid Chisnall    template <class InputIterator>
1207a984708SDavid Chisnall        iterator insert(const_iterator p, InputIterator f, InputIterator l);
1217a984708SDavid Chisnall    iterator insert(const_iterator p, initializer_list<value_type> il);
1227a984708SDavid Chisnall    void pop_front();
1237a984708SDavid Chisnall    void pop_back();
1247a984708SDavid Chisnall    iterator erase(const_iterator p);
1257a984708SDavid Chisnall    iterator erase(const_iterator f, const_iterator l);
1267a984708SDavid Chisnall    void swap(deque& c)
127854fa44bSDimitry Andric        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
1287a984708SDavid Chisnall    void clear() noexcept;
1297a984708SDavid Chisnall};
1307a984708SDavid Chisnall
1314ba319b5SDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1324ba319b5SDimitry Andric   deque(InputIterator, InputIterator, Allocator = Allocator())
1334ba319b5SDimitry Andric   -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
1344ba319b5SDimitry Andric
1357a984708SDavid Chisnalltemplate <class T, class Allocator>
1367a984708SDavid Chisnall    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1377a984708SDavid Chisnalltemplate <class T, class Allocator>
1387a984708SDavid Chisnall    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1397a984708SDavid Chisnalltemplate <class T, class Allocator>
1407a984708SDavid Chisnall    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1417a984708SDavid Chisnalltemplate <class T, class Allocator>
1427a984708SDavid Chisnall    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1437a984708SDavid Chisnalltemplate <class T, class Allocator>
1447a984708SDavid Chisnall    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1457a984708SDavid Chisnalltemplate <class T, class Allocator>
1467a984708SDavid Chisnall    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
1477a984708SDavid Chisnall
1487a984708SDavid Chisnall// specialized algorithms:
1497a984708SDavid Chisnalltemplate <class T, class Allocator>
1507a984708SDavid Chisnall    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
1517a984708SDavid Chisnall         noexcept(noexcept(x.swap(y)));
1527a984708SDavid Chisnall
153*b5893f02SDimitry Andrictemplate <class T, class Allocator, class U>
154*b5893f02SDimitry Andric    void erase(deque<T, Allocator>& c, const U& value);       // C++20
155*b5893f02SDimitry Andrictemplate <class T, class Allocator, class Predicate>
156*b5893f02SDimitry Andric    void erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20
157*b5893f02SDimitry Andric
1587a984708SDavid Chisnall}  // std
1597a984708SDavid Chisnall
1607a984708SDavid Chisnall*/
1617a984708SDavid Chisnall
1627a984708SDavid Chisnall#include <__config>
1637a984708SDavid Chisnall#include <__split_buffer>
1647a984708SDavid Chisnall#include <type_traits>
1657a984708SDavid Chisnall#include <initializer_list>
1667a984708SDavid Chisnall#include <iterator>
1677a984708SDavid Chisnall#include <algorithm>
1687a984708SDavid Chisnall#include <stdexcept>
169*b5893f02SDimitry Andric#include <version>
1707a984708SDavid Chisnall
171f9448bf3SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
172f9448bf3SDimitry Andric#pragma GCC system_header
173f9448bf3SDimitry Andric#endif
174f9448bf3SDimitry Andric
175f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS
176f9448bf3SDimitry Andric#include <__undef_macros>
177f9448bf3SDimitry Andric
17894e3ee44SDavid Chisnall
1797a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
1807a984708SDavid Chisnall
1817a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> class __deque_base;
182aed8d94eSDimitry Andrictemplate <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
1837a984708SDavid Chisnall
1847a984708SDavid Chisnalltemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
1857a984708SDavid Chisnall          class _DiffType, _DiffType _BlockSize>
186aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator;
1877a984708SDavid Chisnall
1887a984708SDavid Chisnalltemplate <class _RAIter,
1897a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
1907a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
1917a984708SDavid Chisnallcopy(_RAIter __f,
1927a984708SDavid Chisnall     _RAIter __l,
1937a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
1947a984708SDavid Chisnall     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
1957a984708SDavid Chisnall
1967a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
1977a984708SDavid Chisnall          class _OutputIterator>
1987a984708SDavid Chisnall_OutputIterator
1997a984708SDavid Chisnallcopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2007a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2017a984708SDavid Chisnall     _OutputIterator __r);
2027a984708SDavid Chisnall
2037a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2047a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2057a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2067a984708SDavid Chisnallcopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2077a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2087a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
2097a984708SDavid Chisnall
2107a984708SDavid Chisnalltemplate <class _RAIter,
2117a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2127a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2137a984708SDavid Chisnallcopy_backward(_RAIter __f,
2147a984708SDavid Chisnall              _RAIter __l,
2157a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
2167a984708SDavid Chisnall              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
2177a984708SDavid Chisnall
2187a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2197a984708SDavid Chisnall          class _OutputIterator>
2207a984708SDavid Chisnall_OutputIterator
2217a984708SDavid Chisnallcopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2227a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2237a984708SDavid Chisnall              _OutputIterator __r);
2247a984708SDavid Chisnall
2257a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2267a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2277a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2287a984708SDavid Chisnallcopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2297a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2307a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
2317a984708SDavid Chisnall
2327a984708SDavid Chisnalltemplate <class _RAIter,
2337a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2347a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2357a984708SDavid Chisnallmove(_RAIter __f,
2367a984708SDavid Chisnall     _RAIter __l,
2377a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
2387a984708SDavid Chisnall     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
2397a984708SDavid Chisnall
2407a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2417a984708SDavid Chisnall          class _OutputIterator>
2427a984708SDavid Chisnall_OutputIterator
2437a984708SDavid Chisnallmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2447a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2457a984708SDavid Chisnall     _OutputIterator __r);
2467a984708SDavid Chisnall
2477a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2487a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2497a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2507a984708SDavid Chisnallmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2517a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2527a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
2537a984708SDavid Chisnall
2547a984708SDavid Chisnalltemplate <class _RAIter,
2557a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2567a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2577a984708SDavid Chisnallmove_backward(_RAIter __f,
2587a984708SDavid Chisnall              _RAIter __l,
2597a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
2607a984708SDavid Chisnall              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
2617a984708SDavid Chisnall
2627a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2637a984708SDavid Chisnall          class _OutputIterator>
2647a984708SDavid Chisnall_OutputIterator
2657a984708SDavid Chisnallmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2667a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2677a984708SDavid Chisnall              _OutputIterator __r);
2687a984708SDavid Chisnall
2697a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
2707a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
2717a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
2727a984708SDavid Chisnallmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
2737a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
2747a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
2757a984708SDavid Chisnall
2769729cf09SDimitry Andrictemplate <class _ValueType, class _DiffType>
2779729cf09SDimitry Andricstruct __deque_block_size {
2789729cf09SDimitry Andric  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
2799729cf09SDimitry Andric};
2809729cf09SDimitry Andric
2817a984708SDavid Chisnalltemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
2829729cf09SDimitry Andric          class _DiffType, _DiffType _BS =
2839729cf09SDimitry Andric#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
2849729cf09SDimitry Andric// Keep template parameter to avoid changing all template declarations thoughout
2859729cf09SDimitry Andric// this file.
2869729cf09SDimitry Andric                               0
2879729cf09SDimitry Andric#else
2889729cf09SDimitry Andric                               __deque_block_size<_ValueType, _DiffType>::value
2899729cf09SDimitry Andric#endif
2909729cf09SDimitry Andric          >
291aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __deque_iterator
2927a984708SDavid Chisnall{
2937a984708SDavid Chisnall    typedef _MapPointer __map_iterator;
2947a984708SDavid Chisnallpublic:
2957a984708SDavid Chisnall    typedef _Pointer  pointer;
2967a984708SDavid Chisnall    typedef _DiffType difference_type;
2977a984708SDavid Chisnallprivate:
2987a984708SDavid Chisnall    __map_iterator __m_iter_;
2997a984708SDavid Chisnall    pointer        __ptr_;
3007a984708SDavid Chisnall
3019729cf09SDimitry Andric    static const difference_type __block_size;
3027a984708SDavid Chisnallpublic:
3037a984708SDavid Chisnall    typedef _ValueType                  value_type;
3047a984708SDavid Chisnall    typedef random_access_iterator_tag  iterator_category;
3057a984708SDavid Chisnall    typedef _Reference                  reference;
3067a984708SDavid Chisnall
3074f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT
3084f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
3094f7ab58eSDimitry Andric     : __m_iter_(nullptr), __ptr_(nullptr)
3104f7ab58eSDimitry Andric#endif
3114f7ab58eSDimitry Andric     {}
3127a984708SDavid Chisnall
31394e3ee44SDavid Chisnall    template <class _Pp, class _Rp, class _MP>
3147a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3159729cf09SDimitry Andric    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
31694e3ee44SDavid Chisnall                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
3177a984708SDavid Chisnall        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
3187a984708SDavid Chisnall
3197a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
3207a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
3217a984708SDavid Chisnall
3227a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
3237a984708SDavid Chisnall    {
3247a984708SDavid Chisnall        if (++__ptr_ - *__m_iter_ == __block_size)
3257a984708SDavid Chisnall        {
3267a984708SDavid Chisnall            ++__m_iter_;
3277a984708SDavid Chisnall            __ptr_ = *__m_iter_;
3287a984708SDavid Chisnall        }
3297a984708SDavid Chisnall        return *this;
3307a984708SDavid Chisnall    }
3317a984708SDavid Chisnall
3327a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
3337a984708SDavid Chisnall    {
3347a984708SDavid Chisnall        __deque_iterator __tmp = *this;
3357a984708SDavid Chisnall        ++(*this);
3367a984708SDavid Chisnall        return __tmp;
3377a984708SDavid Chisnall    }
3387a984708SDavid Chisnall
3397a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
3407a984708SDavid Chisnall    {
3417a984708SDavid Chisnall        if (__ptr_ == *__m_iter_)
3427a984708SDavid Chisnall        {
3437a984708SDavid Chisnall            --__m_iter_;
3447a984708SDavid Chisnall            __ptr_ = *__m_iter_ + __block_size;
3457a984708SDavid Chisnall        }
3467a984708SDavid Chisnall        --__ptr_;
3477a984708SDavid Chisnall        return *this;
3487a984708SDavid Chisnall    }
3497a984708SDavid Chisnall
3507a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
3517a984708SDavid Chisnall    {
3527a984708SDavid Chisnall        __deque_iterator __tmp = *this;
3537a984708SDavid Chisnall        --(*this);
3547a984708SDavid Chisnall        return __tmp;
3557a984708SDavid Chisnall    }
3567a984708SDavid Chisnall
3577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
3587a984708SDavid Chisnall    {
3597a984708SDavid Chisnall        if (__n != 0)
3607a984708SDavid Chisnall        {
3617a984708SDavid Chisnall            __n += __ptr_ - *__m_iter_;
3627a984708SDavid Chisnall            if (__n > 0)
3637a984708SDavid Chisnall            {
3647a984708SDavid Chisnall                __m_iter_ += __n / __block_size;
3657a984708SDavid Chisnall                __ptr_ = *__m_iter_ + __n % __block_size;
3667a984708SDavid Chisnall            }
3677a984708SDavid Chisnall            else // (__n < 0)
3687a984708SDavid Chisnall            {
3697a984708SDavid Chisnall                difference_type __z = __block_size - 1 - __n;
3707a984708SDavid Chisnall                __m_iter_ -= __z / __block_size;
3717a984708SDavid Chisnall                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
3727a984708SDavid Chisnall            }
3737a984708SDavid Chisnall        }
3747a984708SDavid Chisnall        return *this;
3757a984708SDavid Chisnall    }
3767a984708SDavid Chisnall
3777a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
3787a984708SDavid Chisnall    {
3797a984708SDavid Chisnall        return *this += -__n;
3807a984708SDavid Chisnall    }
3817a984708SDavid Chisnall
3827a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
3837a984708SDavid Chisnall    {
3847a984708SDavid Chisnall        __deque_iterator __t(*this);
3857a984708SDavid Chisnall        __t += __n;
3867a984708SDavid Chisnall        return __t;
3877a984708SDavid Chisnall    }
3887a984708SDavid Chisnall
3897a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
3907a984708SDavid Chisnall    {
3917a984708SDavid Chisnall        __deque_iterator __t(*this);
3927a984708SDavid Chisnall        __t -= __n;
3937a984708SDavid Chisnall        return __t;
3947a984708SDavid Chisnall    }
3957a984708SDavid Chisnall
3967a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3977a984708SDavid Chisnall    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
3987a984708SDavid Chisnall        {return __it + __n;}
3997a984708SDavid Chisnall
4007a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4017a984708SDavid Chisnall    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
4027a984708SDavid Chisnall    {
4037a984708SDavid Chisnall        if (__x != __y)
4047a984708SDavid Chisnall            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
4057a984708SDavid Chisnall                 + (__x.__ptr_ - *__x.__m_iter_)
4067a984708SDavid Chisnall                 - (__y.__ptr_ - *__y.__m_iter_);
4077a984708SDavid Chisnall        return 0;
4087a984708SDavid Chisnall    }
4097a984708SDavid Chisnall
4107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
4117a984708SDavid Chisnall        {return *(*this + __n);}
4127a984708SDavid Chisnall
4137a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY friend
4147a984708SDavid Chisnall        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
4157a984708SDavid Chisnall        {return __x.__ptr_ == __y.__ptr_;}
4167a984708SDavid Chisnall
4177a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY friend
4187a984708SDavid Chisnall        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
4197a984708SDavid Chisnall        {return !(__x == __y);}
4207a984708SDavid Chisnall
4217a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY friend
4227a984708SDavid Chisnall        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
4237a984708SDavid Chisnall        {return __x.__m_iter_ < __y.__m_iter_ ||
4247a984708SDavid Chisnall               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
4257a984708SDavid Chisnall
4267a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY friend
4277a984708SDavid Chisnall        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
4287a984708SDavid Chisnall        {return __y < __x;}
4297a984708SDavid Chisnall
4307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY friend
4317a984708SDavid Chisnall        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
4327a984708SDavid Chisnall        {return !(__y < __x);}
4337a984708SDavid Chisnall
4347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY friend
4357a984708SDavid Chisnall        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
4367a984708SDavid Chisnall        {return !(__x < __y);}
4377a984708SDavid Chisnall
4387a984708SDavid Chisnallprivate:
4397a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
4407a984708SDavid Chisnall        : __m_iter_(__m), __ptr_(__p) {}
4417a984708SDavid Chisnall
44294e3ee44SDavid Chisnall    template <class _Tp, class _Ap> friend class __deque_base;
443aed8d94eSDimitry Andric    template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
44494e3ee44SDavid Chisnall    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
445aed8d94eSDimitry Andric        friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
4467a984708SDavid Chisnall
4477a984708SDavid Chisnall    template <class _RAIter,
4487a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
4497a984708SDavid Chisnall    friend
4507a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
4517a984708SDavid Chisnall    copy(_RAIter __f,
4527a984708SDavid Chisnall         _RAIter __l,
4537a984708SDavid Chisnall         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
4547a984708SDavid Chisnall         typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
4557a984708SDavid Chisnall
4567a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
4577a984708SDavid Chisnall              class _OutputIterator>
4587a984708SDavid Chisnall    friend
4597a984708SDavid Chisnall    _OutputIterator
4607a984708SDavid Chisnall    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
4617a984708SDavid Chisnall         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
4627a984708SDavid Chisnall         _OutputIterator __r);
4637a984708SDavid Chisnall
4647a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
4657a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
4667a984708SDavid Chisnall    friend
4677a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
4687a984708SDavid Chisnall    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
4697a984708SDavid Chisnall         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
4707a984708SDavid Chisnall         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
4717a984708SDavid Chisnall
4727a984708SDavid Chisnall    template <class _RAIter,
4737a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
4747a984708SDavid Chisnall    friend
4757a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
4767a984708SDavid Chisnall    copy_backward(_RAIter __f,
4777a984708SDavid Chisnall                  _RAIter __l,
4787a984708SDavid Chisnall                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
4797a984708SDavid Chisnall                  typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
4807a984708SDavid Chisnall
4817a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
4827a984708SDavid Chisnall              class _OutputIterator>
4837a984708SDavid Chisnall    friend
4847a984708SDavid Chisnall    _OutputIterator
4857a984708SDavid Chisnall    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
4867a984708SDavid Chisnall                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
4877a984708SDavid Chisnall                  _OutputIterator __r);
4887a984708SDavid Chisnall
4897a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
4907a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
4917a984708SDavid Chisnall    friend
4927a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
4937a984708SDavid Chisnall    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
4947a984708SDavid Chisnall                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
4957a984708SDavid Chisnall                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
4967a984708SDavid Chisnall
4977a984708SDavid Chisnall    template <class _RAIter,
4987a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
4997a984708SDavid Chisnall    friend
5007a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
5017a984708SDavid Chisnall    move(_RAIter __f,
5027a984708SDavid Chisnall         _RAIter __l,
5037a984708SDavid Chisnall         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
5047a984708SDavid Chisnall         typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
5057a984708SDavid Chisnall
5067a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
5077a984708SDavid Chisnall              class _OutputIterator>
5087a984708SDavid Chisnall    friend
5097a984708SDavid Chisnall    _OutputIterator
5107a984708SDavid Chisnall    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
5117a984708SDavid Chisnall         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
5127a984708SDavid Chisnall         _OutputIterator __r);
5137a984708SDavid Chisnall
5147a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
5157a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
5167a984708SDavid Chisnall    friend
5177a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
5187a984708SDavid Chisnall    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
5197a984708SDavid Chisnall         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
5207a984708SDavid Chisnall         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
5217a984708SDavid Chisnall
5227a984708SDavid Chisnall    template <class _RAIter,
5237a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
5247a984708SDavid Chisnall    friend
5257a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
5267a984708SDavid Chisnall    move_backward(_RAIter __f,
5277a984708SDavid Chisnall                  _RAIter __l,
5287a984708SDavid Chisnall                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
5297a984708SDavid Chisnall                  typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
5307a984708SDavid Chisnall
5317a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
5327a984708SDavid Chisnall              class _OutputIterator>
5337a984708SDavid Chisnall    friend
5347a984708SDavid Chisnall    _OutputIterator
5357a984708SDavid Chisnall    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
5367a984708SDavid Chisnall                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
5377a984708SDavid Chisnall                  _OutputIterator __r);
5387a984708SDavid Chisnall
5397a984708SDavid Chisnall    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
5407a984708SDavid Chisnall              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
5417a984708SDavid Chisnall    friend
5427a984708SDavid Chisnall    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
5437a984708SDavid Chisnall    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
5447a984708SDavid Chisnall                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
5457a984708SDavid Chisnall                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
5467a984708SDavid Chisnall};
5477a984708SDavid Chisnall
5489729cf09SDimitry Andrictemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
5499729cf09SDimitry Andric          class _DiffType, _DiffType _BlockSize>
5509729cf09SDimitry Andricconst _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
5519729cf09SDimitry Andric                                 _DiffType, _BlockSize>::__block_size =
5529729cf09SDimitry Andric    __deque_block_size<_ValueType, _DiffType>::value;
5539729cf09SDimitry Andric
5547a984708SDavid Chisnall// copy
5557a984708SDavid Chisnall
5567a984708SDavid Chisnalltemplate <class _RAIter,
5577a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
5587a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
5597a984708SDavid Chisnallcopy(_RAIter __f,
5607a984708SDavid Chisnall     _RAIter __l,
5617a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
5627a984708SDavid Chisnall     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
5637a984708SDavid Chisnall{
5647a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
5657a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
5669729cf09SDimitry Andric    const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
5677a984708SDavid Chisnall    while (__f != __l)
5687a984708SDavid Chisnall    {
5697a984708SDavid Chisnall        pointer __rb = __r.__ptr_;
5709729cf09SDimitry Andric        pointer __re = *__r.__m_iter_ + __block_size;
5717a984708SDavid Chisnall        difference_type __bs = __re - __rb;
5727a984708SDavid Chisnall        difference_type __n = __l - __f;
5737a984708SDavid Chisnall        _RAIter __m = __l;
5747a984708SDavid Chisnall        if (__n > __bs)
5757a984708SDavid Chisnall        {
5767a984708SDavid Chisnall            __n = __bs;
5777a984708SDavid Chisnall            __m = __f + __n;
5787a984708SDavid Chisnall        }
5797a984708SDavid Chisnall        _VSTD::copy(__f, __m, __rb);
5807a984708SDavid Chisnall        __f = __m;
5817a984708SDavid Chisnall        __r += __n;
5827a984708SDavid Chisnall    }
5837a984708SDavid Chisnall    return __r;
5847a984708SDavid Chisnall}
5857a984708SDavid Chisnall
5867a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
5877a984708SDavid Chisnall          class _OutputIterator>
5887a984708SDavid Chisnall_OutputIterator
5897a984708SDavid Chisnallcopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
5907a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
5917a984708SDavid Chisnall     _OutputIterator __r)
5927a984708SDavid Chisnall{
5937a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
5947a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
5959729cf09SDimitry Andric    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
5967a984708SDavid Chisnall    difference_type __n = __l - __f;
5977a984708SDavid Chisnall    while (__n > 0)
5987a984708SDavid Chisnall    {
5997a984708SDavid Chisnall        pointer __fb = __f.__ptr_;
6009729cf09SDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
6017a984708SDavid Chisnall        difference_type __bs = __fe - __fb;
6027a984708SDavid Chisnall        if (__bs > __n)
6037a984708SDavid Chisnall        {
6047a984708SDavid Chisnall            __bs = __n;
6057a984708SDavid Chisnall            __fe = __fb + __bs;
6067a984708SDavid Chisnall        }
6077a984708SDavid Chisnall        __r = _VSTD::copy(__fb, __fe, __r);
6087a984708SDavid Chisnall        __n -= __bs;
6097a984708SDavid Chisnall        __f += __bs;
6107a984708SDavid Chisnall    }
6117a984708SDavid Chisnall    return __r;
6127a984708SDavid Chisnall}
6137a984708SDavid Chisnall
6147a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
6157a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
6167a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
6177a984708SDavid Chisnallcopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
6187a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
6197a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
6207a984708SDavid Chisnall{
6217a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
6227a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
6239729cf09SDimitry Andric    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
6247a984708SDavid Chisnall    difference_type __n = __l - __f;
6257a984708SDavid Chisnall    while (__n > 0)
6267a984708SDavid Chisnall    {
6277a984708SDavid Chisnall        pointer __fb = __f.__ptr_;
6289729cf09SDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
6297a984708SDavid Chisnall        difference_type __bs = __fe - __fb;
6307a984708SDavid Chisnall        if (__bs > __n)
6317a984708SDavid Chisnall        {
6327a984708SDavid Chisnall            __bs = __n;
6337a984708SDavid Chisnall            __fe = __fb + __bs;
6347a984708SDavid Chisnall        }
6357a984708SDavid Chisnall        __r = _VSTD::copy(__fb, __fe, __r);
6367a984708SDavid Chisnall        __n -= __bs;
6377a984708SDavid Chisnall        __f += __bs;
6387a984708SDavid Chisnall    }
6397a984708SDavid Chisnall    return __r;
6407a984708SDavid Chisnall}
6417a984708SDavid Chisnall
6427a984708SDavid Chisnall// copy_backward
6437a984708SDavid Chisnall
6447a984708SDavid Chisnalltemplate <class _RAIter,
6457a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
6467a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
6477a984708SDavid Chisnallcopy_backward(_RAIter __f,
6487a984708SDavid Chisnall              _RAIter __l,
6497a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
6507a984708SDavid Chisnall              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
6517a984708SDavid Chisnall{
6527a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
6537a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
6547a984708SDavid Chisnall    while (__f != __l)
6557a984708SDavid Chisnall    {
6567a984708SDavid Chisnall        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
6577a984708SDavid Chisnall        pointer __rb = *__rp.__m_iter_;
6587a984708SDavid Chisnall        pointer __re = __rp.__ptr_ + 1;
6597a984708SDavid Chisnall        difference_type __bs = __re - __rb;
6607a984708SDavid Chisnall        difference_type __n = __l - __f;
6617a984708SDavid Chisnall        _RAIter __m = __f;
6627a984708SDavid Chisnall        if (__n > __bs)
6637a984708SDavid Chisnall        {
6647a984708SDavid Chisnall            __n = __bs;
6657a984708SDavid Chisnall            __m = __l - __n;
6667a984708SDavid Chisnall        }
6677a984708SDavid Chisnall        _VSTD::copy_backward(__m, __l, __re);
6687a984708SDavid Chisnall        __l = __m;
6697a984708SDavid Chisnall        __r -= __n;
6707a984708SDavid Chisnall    }
6717a984708SDavid Chisnall    return __r;
6727a984708SDavid Chisnall}
6737a984708SDavid Chisnall
6747a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
6757a984708SDavid Chisnall          class _OutputIterator>
6767a984708SDavid Chisnall_OutputIterator
6777a984708SDavid Chisnallcopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
6787a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
6797a984708SDavid Chisnall              _OutputIterator __r)
6807a984708SDavid Chisnall{
6817a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
6827a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
6837a984708SDavid Chisnall    difference_type __n = __l - __f;
6847a984708SDavid Chisnall    while (__n > 0)
6857a984708SDavid Chisnall    {
6867a984708SDavid Chisnall        --__l;
6877a984708SDavid Chisnall        pointer __lb = *__l.__m_iter_;
6887a984708SDavid Chisnall        pointer __le = __l.__ptr_ + 1;
6897a984708SDavid Chisnall        difference_type __bs = __le - __lb;
6907a984708SDavid Chisnall        if (__bs > __n)
6917a984708SDavid Chisnall        {
6927a984708SDavid Chisnall            __bs = __n;
6937a984708SDavid Chisnall            __lb = __le - __bs;
6947a984708SDavid Chisnall        }
6957a984708SDavid Chisnall        __r = _VSTD::copy_backward(__lb, __le, __r);
6967a984708SDavid Chisnall        __n -= __bs;
6977a984708SDavid Chisnall        __l -= __bs - 1;
6987a984708SDavid Chisnall    }
6997a984708SDavid Chisnall    return __r;
7007a984708SDavid Chisnall}
7017a984708SDavid Chisnall
7027a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
7037a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
7047a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
7057a984708SDavid Chisnallcopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
7067a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
7077a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
7087a984708SDavid Chisnall{
7097a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
7107a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
7117a984708SDavid Chisnall    difference_type __n = __l - __f;
7127a984708SDavid Chisnall    while (__n > 0)
7137a984708SDavid Chisnall    {
7147a984708SDavid Chisnall        --__l;
7157a984708SDavid Chisnall        pointer __lb = *__l.__m_iter_;
7167a984708SDavid Chisnall        pointer __le = __l.__ptr_ + 1;
7177a984708SDavid Chisnall        difference_type __bs = __le - __lb;
7187a984708SDavid Chisnall        if (__bs > __n)
7197a984708SDavid Chisnall        {
7207a984708SDavid Chisnall            __bs = __n;
7217a984708SDavid Chisnall            __lb = __le - __bs;
7227a984708SDavid Chisnall        }
7237a984708SDavid Chisnall        __r = _VSTD::copy_backward(__lb, __le, __r);
7247a984708SDavid Chisnall        __n -= __bs;
7257a984708SDavid Chisnall        __l -= __bs - 1;
7267a984708SDavid Chisnall    }
7277a984708SDavid Chisnall    return __r;
7287a984708SDavid Chisnall}
7297a984708SDavid Chisnall
7307a984708SDavid Chisnall// move
7317a984708SDavid Chisnall
7327a984708SDavid Chisnalltemplate <class _RAIter,
7337a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
7347a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
7357a984708SDavid Chisnallmove(_RAIter __f,
7367a984708SDavid Chisnall     _RAIter __l,
7377a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
7387a984708SDavid Chisnall     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
7397a984708SDavid Chisnall{
7407a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
7417a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
7429729cf09SDimitry Andric    const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
7437a984708SDavid Chisnall    while (__f != __l)
7447a984708SDavid Chisnall    {
7457a984708SDavid Chisnall        pointer __rb = __r.__ptr_;
7469729cf09SDimitry Andric        pointer __re = *__r.__m_iter_ + __block_size;
7477a984708SDavid Chisnall        difference_type __bs = __re - __rb;
7487a984708SDavid Chisnall        difference_type __n = __l - __f;
7497a984708SDavid Chisnall        _RAIter __m = __l;
7507a984708SDavid Chisnall        if (__n > __bs)
7517a984708SDavid Chisnall        {
7527a984708SDavid Chisnall            __n = __bs;
7537a984708SDavid Chisnall            __m = __f + __n;
7547a984708SDavid Chisnall        }
7557a984708SDavid Chisnall        _VSTD::move(__f, __m, __rb);
7567a984708SDavid Chisnall        __f = __m;
7577a984708SDavid Chisnall        __r += __n;
7587a984708SDavid Chisnall    }
7597a984708SDavid Chisnall    return __r;
7607a984708SDavid Chisnall}
7617a984708SDavid Chisnall
7627a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
7637a984708SDavid Chisnall          class _OutputIterator>
7647a984708SDavid Chisnall_OutputIterator
7657a984708SDavid Chisnallmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
7667a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
7677a984708SDavid Chisnall     _OutputIterator __r)
7687a984708SDavid Chisnall{
7697a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
7707a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
7719729cf09SDimitry Andric    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
7727a984708SDavid Chisnall    difference_type __n = __l - __f;
7737a984708SDavid Chisnall    while (__n > 0)
7747a984708SDavid Chisnall    {
7757a984708SDavid Chisnall        pointer __fb = __f.__ptr_;
7769729cf09SDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
7777a984708SDavid Chisnall        difference_type __bs = __fe - __fb;
7787a984708SDavid Chisnall        if (__bs > __n)
7797a984708SDavid Chisnall        {
7807a984708SDavid Chisnall            __bs = __n;
7817a984708SDavid Chisnall            __fe = __fb + __bs;
7827a984708SDavid Chisnall        }
7837a984708SDavid Chisnall        __r = _VSTD::move(__fb, __fe, __r);
7847a984708SDavid Chisnall        __n -= __bs;
7857a984708SDavid Chisnall        __f += __bs;
7867a984708SDavid Chisnall    }
7877a984708SDavid Chisnall    return __r;
7887a984708SDavid Chisnall}
7897a984708SDavid Chisnall
7907a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
7917a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
7927a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
7937a984708SDavid Chisnallmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
7947a984708SDavid Chisnall     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
7957a984708SDavid Chisnall     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
7967a984708SDavid Chisnall{
7977a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
7987a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
7999729cf09SDimitry Andric    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
8007a984708SDavid Chisnall    difference_type __n = __l - __f;
8017a984708SDavid Chisnall    while (__n > 0)
8027a984708SDavid Chisnall    {
8037a984708SDavid Chisnall        pointer __fb = __f.__ptr_;
8049729cf09SDimitry Andric        pointer __fe = *__f.__m_iter_ + __block_size;
8057a984708SDavid Chisnall        difference_type __bs = __fe - __fb;
8067a984708SDavid Chisnall        if (__bs > __n)
8077a984708SDavid Chisnall        {
8087a984708SDavid Chisnall            __bs = __n;
8097a984708SDavid Chisnall            __fe = __fb + __bs;
8107a984708SDavid Chisnall        }
8117a984708SDavid Chisnall        __r = _VSTD::move(__fb, __fe, __r);
8127a984708SDavid Chisnall        __n -= __bs;
8137a984708SDavid Chisnall        __f += __bs;
8147a984708SDavid Chisnall    }
8157a984708SDavid Chisnall    return __r;
8167a984708SDavid Chisnall}
8177a984708SDavid Chisnall
8187a984708SDavid Chisnall// move_backward
8197a984708SDavid Chisnall
8207a984708SDavid Chisnalltemplate <class _RAIter,
8217a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
8227a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
8237a984708SDavid Chisnallmove_backward(_RAIter __f,
8247a984708SDavid Chisnall              _RAIter __l,
8257a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
8267a984708SDavid Chisnall              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
8277a984708SDavid Chisnall{
8287a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
8297a984708SDavid Chisnall    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
8307a984708SDavid Chisnall    while (__f != __l)
8317a984708SDavid Chisnall    {
8327a984708SDavid Chisnall        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
8337a984708SDavid Chisnall        pointer __rb = *__rp.__m_iter_;
8347a984708SDavid Chisnall        pointer __re = __rp.__ptr_ + 1;
8357a984708SDavid Chisnall        difference_type __bs = __re - __rb;
8367a984708SDavid Chisnall        difference_type __n = __l - __f;
8377a984708SDavid Chisnall        _RAIter __m = __f;
8387a984708SDavid Chisnall        if (__n > __bs)
8397a984708SDavid Chisnall        {
8407a984708SDavid Chisnall            __n = __bs;
8417a984708SDavid Chisnall            __m = __l - __n;
8427a984708SDavid Chisnall        }
8437a984708SDavid Chisnall        _VSTD::move_backward(__m, __l, __re);
8447a984708SDavid Chisnall        __l = __m;
8457a984708SDavid Chisnall        __r -= __n;
8467a984708SDavid Chisnall    }
8477a984708SDavid Chisnall    return __r;
8487a984708SDavid Chisnall}
8497a984708SDavid Chisnall
8507a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
8517a984708SDavid Chisnall          class _OutputIterator>
8527a984708SDavid Chisnall_OutputIterator
8537a984708SDavid Chisnallmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
8547a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
8557a984708SDavid Chisnall              _OutputIterator __r)
8567a984708SDavid Chisnall{
8577a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
8587a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
8597a984708SDavid Chisnall    difference_type __n = __l - __f;
8607a984708SDavid Chisnall    while (__n > 0)
8617a984708SDavid Chisnall    {
8627a984708SDavid Chisnall        --__l;
8637a984708SDavid Chisnall        pointer __lb = *__l.__m_iter_;
8647a984708SDavid Chisnall        pointer __le = __l.__ptr_ + 1;
8657a984708SDavid Chisnall        difference_type __bs = __le - __lb;
8667a984708SDavid Chisnall        if (__bs > __n)
8677a984708SDavid Chisnall        {
8687a984708SDavid Chisnall            __bs = __n;
8697a984708SDavid Chisnall            __lb = __le - __bs;
8707a984708SDavid Chisnall        }
8717a984708SDavid Chisnall        __r = _VSTD::move_backward(__lb, __le, __r);
8727a984708SDavid Chisnall        __n -= __bs;
8737a984708SDavid Chisnall        __l -= __bs - 1;
8747a984708SDavid Chisnall    }
8757a984708SDavid Chisnall    return __r;
8767a984708SDavid Chisnall}
8777a984708SDavid Chisnall
8787a984708SDavid Chisnalltemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
8797a984708SDavid Chisnall          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
8807a984708SDavid Chisnall__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
8817a984708SDavid Chisnallmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
8827a984708SDavid Chisnall              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
8837a984708SDavid Chisnall              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
8847a984708SDavid Chisnall{
8857a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
8867a984708SDavid Chisnall    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
8877a984708SDavid Chisnall    difference_type __n = __l - __f;
8887a984708SDavid Chisnall    while (__n > 0)
8897a984708SDavid Chisnall    {
8907a984708SDavid Chisnall        --__l;
8917a984708SDavid Chisnall        pointer __lb = *__l.__m_iter_;
8927a984708SDavid Chisnall        pointer __le = __l.__ptr_ + 1;
8937a984708SDavid Chisnall        difference_type __bs = __le - __lb;
8947a984708SDavid Chisnall        if (__bs > __n)
8957a984708SDavid Chisnall        {
8967a984708SDavid Chisnall            __bs = __n;
8977a984708SDavid Chisnall            __lb = __le - __bs;
8987a984708SDavid Chisnall        }
8997a984708SDavid Chisnall        __r = _VSTD::move_backward(__lb, __le, __r);
9007a984708SDavid Chisnall        __n -= __bs;
9017a984708SDavid Chisnall        __l -= __bs - 1;
9027a984708SDavid Chisnall    }
9037a984708SDavid Chisnall    return __r;
9047a984708SDavid Chisnall}
9057a984708SDavid Chisnall
9067a984708SDavid Chisnalltemplate <bool>
9077a984708SDavid Chisnallclass __deque_base_common
9087a984708SDavid Chisnall{
9097a984708SDavid Chisnallprotected:
910aed8d94eSDimitry Andric    _LIBCPP_NORETURN void __throw_length_error() const;
911aed8d94eSDimitry Andric    _LIBCPP_NORETURN void __throw_out_of_range() const;
9127a984708SDavid Chisnall};
9137a984708SDavid Chisnall
9147a984708SDavid Chisnalltemplate <bool __b>
9157a984708SDavid Chisnallvoid
9167a984708SDavid Chisnall__deque_base_common<__b>::__throw_length_error() const
9177a984708SDavid Chisnall{
918aed8d94eSDimitry Andric    _VSTD::__throw_length_error("deque");
9197a984708SDavid Chisnall}
9207a984708SDavid Chisnall
9217a984708SDavid Chisnalltemplate <bool __b>
9227a984708SDavid Chisnallvoid
9237a984708SDavid Chisnall__deque_base_common<__b>::__throw_out_of_range() const
9247a984708SDavid Chisnall{
925aed8d94eSDimitry Andric    _VSTD::__throw_out_of_range("deque");
9267a984708SDavid Chisnall}
9277a984708SDavid Chisnall
9287a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
9297a984708SDavid Chisnallclass __deque_base
9307a984708SDavid Chisnall    : protected __deque_base_common<true>
9317a984708SDavid Chisnall{
9327a984708SDavid Chisnall    __deque_base(const __deque_base& __c);
9337a984708SDavid Chisnall    __deque_base& operator=(const __deque_base& __c);
9344ba319b5SDimitry Andricpublic:
9357a984708SDavid Chisnall    typedef _Allocator                               allocator_type;
9367a984708SDavid Chisnall    typedef allocator_traits<allocator_type>         __alloc_traits;
9374ba319b5SDimitry Andric    typedef typename __alloc_traits::size_type       size_type;
9384ba319b5SDimitry Andricprotected:
9394ba319b5SDimitry Andric    typedef _Tp                                      value_type;
9407a984708SDavid Chisnall    typedef value_type&                              reference;
9417a984708SDavid Chisnall    typedef const value_type&                        const_reference;
9427a984708SDavid Chisnall    typedef typename __alloc_traits::difference_type difference_type;
9437a984708SDavid Chisnall    typedef typename __alloc_traits::pointer         pointer;
9447a984708SDavid Chisnall    typedef typename __alloc_traits::const_pointer   const_pointer;
9457a984708SDavid Chisnall
9469729cf09SDimitry Andric    static const difference_type __block_size;
9477a984708SDavid Chisnall
948854fa44bSDimitry Andric    typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
9497a984708SDavid Chisnall    typedef allocator_traits<__pointer_allocator>        __map_traits;
9507a984708SDavid Chisnall    typedef typename __map_traits::pointer               __map_pointer;
951854fa44bSDimitry Andric    typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;
9524bab9fd9SDavid Chisnall    typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
9537a984708SDavid Chisnall    typedef __split_buffer<pointer, __pointer_allocator> __map;
9547a984708SDavid Chisnall
9557a984708SDavid Chisnall    typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
9569729cf09SDimitry Andric                             difference_type>    iterator;
9577a984708SDavid Chisnall    typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
9589729cf09SDimitry Andric                             difference_type>    const_iterator;
9597a984708SDavid Chisnall
9604ba319b5SDimitry Andricprotected:
9617a984708SDavid Chisnall    __map __map_;
9627a984708SDavid Chisnall    size_type __start_;
9637a984708SDavid Chisnall    __compressed_pair<size_type, allocator_type> __size_;
9647a984708SDavid Chisnall
9657a984708SDavid Chisnall    iterator       begin() _NOEXCEPT;
9667a984708SDavid Chisnall    const_iterator begin() const _NOEXCEPT;
9677a984708SDavid Chisnall    iterator       end() _NOEXCEPT;
9687a984708SDavid Chisnall    const_iterator end() const _NOEXCEPT;
9697a984708SDavid Chisnall
9707a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY size_type&            size()          {return __size_.first();}
9717a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9727a984708SDavid Chisnall    const size_type& size() const _NOEXCEPT {return __size_.first();}
9737a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY allocator_type&       __alloc()       {return __size_.second();}
9747a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9757a984708SDavid Chisnall    const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
9767a984708SDavid Chisnall
9779729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
9787a984708SDavid Chisnall    __deque_base()
9797a984708SDavid Chisnall        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
9809729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
9817a984708SDavid Chisnall    explicit __deque_base(const allocator_type& __a);
9827a984708SDavid Chisnallpublic:
9837a984708SDavid Chisnall    ~__deque_base();
9847a984708SDavid Chisnall
985540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9867a984708SDavid Chisnall    __deque_base(__deque_base&& __c)
9877a984708SDavid Chisnall        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
9887a984708SDavid Chisnall    __deque_base(__deque_base&& __c, const allocator_type& __a);
989540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
9907a984708SDavid Chisnall
9917a984708SDavid Chisnall    void swap(__deque_base& __c)
992854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
993854fa44bSDimitry Andric        _NOEXCEPT;
994854fa44bSDimitry Andric#else
9957a984708SDavid Chisnall        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
9967a984708SDavid Chisnall                    __is_nothrow_swappable<allocator_type>::value);
997854fa44bSDimitry Andric#endif
9987a984708SDavid Chisnallprotected:
9997a984708SDavid Chisnall    void clear() _NOEXCEPT;
10007a984708SDavid Chisnall
10017a984708SDavid Chisnall    bool __invariants() const;
10027a984708SDavid Chisnall
10037a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
10047a984708SDavid Chisnall    void __move_assign(__deque_base& __c)
10057a984708SDavid Chisnall        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
10067a984708SDavid Chisnall                   is_nothrow_move_assignable<allocator_type>::value)
10077a984708SDavid Chisnall    {
10087a984708SDavid Chisnall        __map_ = _VSTD::move(__c.__map_);
10097a984708SDavid Chisnall        __start_ = __c.__start_;
10107a984708SDavid Chisnall        size() = __c.size();
10117a984708SDavid Chisnall        __move_assign_alloc(__c);
10127a984708SDavid Chisnall        __c.__start_ = __c.size() = 0;
10137a984708SDavid Chisnall    }
10147a984708SDavid Chisnall
10157a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
10167a984708SDavid Chisnall    void __move_assign_alloc(__deque_base& __c)
10177a984708SDavid Chisnall        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
10187a984708SDavid Chisnall                   is_nothrow_move_assignable<allocator_type>::value)
10197a984708SDavid Chisnall        {__move_assign_alloc(__c, integral_constant<bool,
10207a984708SDavid Chisnall                      __alloc_traits::propagate_on_container_move_assignment::value>());}
10217a984708SDavid Chisnall
10227a984708SDavid Chisnallprivate:
10237a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
10247a984708SDavid Chisnall    void __move_assign_alloc(__deque_base& __c, true_type)
10257a984708SDavid Chisnall        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
10267a984708SDavid Chisnall        {
10277a984708SDavid Chisnall            __alloc() = _VSTD::move(__c.__alloc());
10287a984708SDavid Chisnall        }
10297a984708SDavid Chisnall
10307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
103194e3ee44SDavid Chisnall    void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
10327a984708SDavid Chisnall        {}
10337a984708SDavid Chisnall};
10347a984708SDavid Chisnall
10357a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
10369729cf09SDimitry Andricconst typename __deque_base<_Tp, _Allocator>::difference_type
10379729cf09SDimitry Andric    __deque_base<_Tp, _Allocator>::__block_size =
10389729cf09SDimitry Andric        __deque_block_size<value_type, difference_type>::value;
10399729cf09SDimitry Andric
10409729cf09SDimitry Andrictemplate <class _Tp, class _Allocator>
10417a984708SDavid Chisnallbool
10427a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::__invariants() const
10437a984708SDavid Chisnall{
10447a984708SDavid Chisnall    if (!__map_.__invariants())
10457a984708SDavid Chisnall        return false;
10467a984708SDavid Chisnall    if (__map_.size() >= size_type(-1) / __block_size)
10477a984708SDavid Chisnall        return false;
10487a984708SDavid Chisnall    for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
10497a984708SDavid Chisnall         __i != __e; ++__i)
10507a984708SDavid Chisnall        if (*__i == nullptr)
10517a984708SDavid Chisnall            return false;
10527a984708SDavid Chisnall    if (__map_.size() != 0)
10537a984708SDavid Chisnall    {
10547a984708SDavid Chisnall        if (size() >= __map_.size() * __block_size)
10557a984708SDavid Chisnall            return false;
10567a984708SDavid Chisnall        if (__start_ >= __map_.size() * __block_size - size())
10577a984708SDavid Chisnall            return false;
10587a984708SDavid Chisnall    }
10597a984708SDavid Chisnall    else
10607a984708SDavid Chisnall    {
10617a984708SDavid Chisnall        if (size() != 0)
10627a984708SDavid Chisnall            return false;
10637a984708SDavid Chisnall        if (__start_ != 0)
10647a984708SDavid Chisnall            return false;
10657a984708SDavid Chisnall    }
10667a984708SDavid Chisnall    return true;
10677a984708SDavid Chisnall}
10687a984708SDavid Chisnall
10697a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
10707a984708SDavid Chisnalltypename __deque_base<_Tp, _Allocator>::iterator
10717a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
10727a984708SDavid Chisnall{
10737a984708SDavid Chisnall    __map_pointer __mp = __map_.begin() + __start_ / __block_size;
10747a984708SDavid Chisnall    return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
10757a984708SDavid Chisnall}
10767a984708SDavid Chisnall
10777a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
10787a984708SDavid Chisnalltypename __deque_base<_Tp, _Allocator>::const_iterator
10797a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
10807a984708SDavid Chisnall{
10814bab9fd9SDavid Chisnall    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
10827a984708SDavid Chisnall    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
10837a984708SDavid Chisnall}
10847a984708SDavid Chisnall
10857a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
10867a984708SDavid Chisnalltypename __deque_base<_Tp, _Allocator>::iterator
10877a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
10887a984708SDavid Chisnall{
10897a984708SDavid Chisnall    size_type __p = size() + __start_;
10907a984708SDavid Chisnall    __map_pointer __mp = __map_.begin() + __p / __block_size;
10917a984708SDavid Chisnall    return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
10927a984708SDavid Chisnall}
10937a984708SDavid Chisnall
10947a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
10957a984708SDavid Chisnalltypename __deque_base<_Tp, _Allocator>::const_iterator
10967a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
10977a984708SDavid Chisnall{
10987a984708SDavid Chisnall    size_type __p = size() + __start_;
10994bab9fd9SDavid Chisnall    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
11007a984708SDavid Chisnall    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
11017a984708SDavid Chisnall}
11027a984708SDavid Chisnall
11037a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11049729cf09SDimitry Andricinline
11057a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::__deque_base()
11067a984708SDavid Chisnall    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
11077a984708SDavid Chisnall    : __start_(0), __size_(0) {}
11087a984708SDavid Chisnall
11097a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11109729cf09SDimitry Andricinline
11117a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
11127a984708SDavid Chisnall    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
11137a984708SDavid Chisnall
11147a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11157a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::~__deque_base()
11167a984708SDavid Chisnall{
11177a984708SDavid Chisnall    clear();
11187a984708SDavid Chisnall    typename __map::iterator __i = __map_.begin();
11197a984708SDavid Chisnall    typename __map::iterator __e = __map_.end();
11207a984708SDavid Chisnall    for (; __i != __e; ++__i)
11217a984708SDavid Chisnall        __alloc_traits::deallocate(__alloc(), *__i, __block_size);
11227a984708SDavid Chisnall}
11237a984708SDavid Chisnall
1124540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
11257a984708SDavid Chisnall
11267a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11277a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
11287a984708SDavid Chisnall    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
11297a984708SDavid Chisnall    : __map_(_VSTD::move(__c.__map_)),
11307a984708SDavid Chisnall      __start_(_VSTD::move(__c.__start_)),
11317a984708SDavid Chisnall      __size_(_VSTD::move(__c.__size_))
11327a984708SDavid Chisnall{
11337a984708SDavid Chisnall    __c.__start_ = 0;
11347a984708SDavid Chisnall    __c.size() = 0;
11357a984708SDavid Chisnall}
11367a984708SDavid Chisnall
11377a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11387a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
11397a984708SDavid Chisnall    : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),
11407a984708SDavid Chisnall      __start_(_VSTD::move(__c.__start_)),
11417a984708SDavid Chisnall      __size_(_VSTD::move(__c.size()), __a)
11427a984708SDavid Chisnall{
11437a984708SDavid Chisnall    if (__a == __c.__alloc())
11447a984708SDavid Chisnall    {
11457a984708SDavid Chisnall        __c.__start_ = 0;
11467a984708SDavid Chisnall        __c.size() = 0;
11477a984708SDavid Chisnall    }
11487a984708SDavid Chisnall    else
11497a984708SDavid Chisnall    {
11507a984708SDavid Chisnall        __map_.clear();
11517a984708SDavid Chisnall        __start_ = 0;
11527a984708SDavid Chisnall        size() = 0;
11537a984708SDavid Chisnall    }
11547a984708SDavid Chisnall}
11557a984708SDavid Chisnall
1156540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
11577a984708SDavid Chisnall
11587a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11597a984708SDavid Chisnallvoid
11607a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
1161854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
1162854fa44bSDimitry Andric        _NOEXCEPT
1163854fa44bSDimitry Andric#else
11647a984708SDavid Chisnall        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
11657a984708SDavid Chisnall                    __is_nothrow_swappable<allocator_type>::value)
1166854fa44bSDimitry Andric#endif
11677a984708SDavid Chisnall{
11687a984708SDavid Chisnall    __map_.swap(__c.__map_);
11697a984708SDavid Chisnall    _VSTD::swap(__start_, __c.__start_);
11707a984708SDavid Chisnall    _VSTD::swap(size(), __c.size());
1171854fa44bSDimitry Andric    __swap_allocator(__alloc(), __c.__alloc());
11727a984708SDavid Chisnall}
11737a984708SDavid Chisnall
11747a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
11757a984708SDavid Chisnallvoid
11767a984708SDavid Chisnall__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
11777a984708SDavid Chisnall{
11787a984708SDavid Chisnall    allocator_type& __a = __alloc();
11797a984708SDavid Chisnall    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
11807a984708SDavid Chisnall        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
11817a984708SDavid Chisnall    size() = 0;
11827a984708SDavid Chisnall    while (__map_.size() > 2)
11837a984708SDavid Chisnall    {
11847a984708SDavid Chisnall        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
11857a984708SDavid Chisnall        __map_.pop_front();
11867a984708SDavid Chisnall    }
11877a984708SDavid Chisnall    switch (__map_.size())
11887a984708SDavid Chisnall    {
11897a984708SDavid Chisnall    case 1:
11907a984708SDavid Chisnall        __start_ = __block_size / 2;
11917a984708SDavid Chisnall        break;
11927a984708SDavid Chisnall    case 2:
11937a984708SDavid Chisnall        __start_ = __block_size;
11947a984708SDavid Chisnall        break;
11957a984708SDavid Chisnall    }
11967a984708SDavid Chisnall}
11977a984708SDavid Chisnall
1198854fa44bSDimitry Andrictemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/>
1199aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS deque
12007a984708SDavid Chisnall    : private __deque_base<_Tp, _Allocator>
12017a984708SDavid Chisnall{
12027a984708SDavid Chisnallpublic:
12037a984708SDavid Chisnall    // types:
12047a984708SDavid Chisnall
12057a984708SDavid Chisnall    typedef _Tp value_type;
12067a984708SDavid Chisnall    typedef _Allocator allocator_type;
12077a984708SDavid Chisnall
12089729cf09SDimitry Andric    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
12099729cf09SDimitry Andric                  "Allocator::value_type must be same type as value_type");
12109729cf09SDimitry Andric
12117a984708SDavid Chisnall    typedef __deque_base<value_type, allocator_type> __base;
12127a984708SDavid Chisnall
12137a984708SDavid Chisnall    typedef typename __base::__alloc_traits        __alloc_traits;
12147a984708SDavid Chisnall    typedef typename __base::reference             reference;
12157a984708SDavid Chisnall    typedef typename __base::const_reference       const_reference;
12167a984708SDavid Chisnall    typedef typename __base::iterator              iterator;
12177a984708SDavid Chisnall    typedef typename __base::const_iterator        const_iterator;
12187a984708SDavid Chisnall    typedef typename __base::size_type             size_type;
12197a984708SDavid Chisnall    typedef typename __base::difference_type       difference_type;
12207a984708SDavid Chisnall
12217a984708SDavid Chisnall    typedef typename __base::pointer               pointer;
12227a984708SDavid Chisnall    typedef typename __base::const_pointer         const_pointer;
12237a984708SDavid Chisnall    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
12247a984708SDavid Chisnall    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
12257a984708SDavid Chisnall
12267a984708SDavid Chisnall    // construct/copy/destroy:
12277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12287a984708SDavid Chisnall    deque()
12297a984708SDavid Chisnall        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
12307a984708SDavid Chisnall        {}
1231d72607e9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
12327a984708SDavid Chisnall    explicit deque(size_type __n);
12334f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
12344f7ab58eSDimitry Andric    explicit deque(size_type __n, const _Allocator& __a);
12354f7ab58eSDimitry Andric#endif
12367a984708SDavid Chisnall    deque(size_type __n, const value_type& __v);
12377a984708SDavid Chisnall    deque(size_type __n, const value_type& __v, const allocator_type& __a);
12387a984708SDavid Chisnall    template <class _InputIter>
12397a984708SDavid Chisnall        deque(_InputIter __f, _InputIter __l,
12407a984708SDavid Chisnall              typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
12417a984708SDavid Chisnall    template <class _InputIter>
12427a984708SDavid Chisnall        deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
12437a984708SDavid Chisnall              typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
12447a984708SDavid Chisnall    deque(const deque& __c);
12457a984708SDavid Chisnall    deque(const deque& __c, const allocator_type& __a);
12467a984708SDavid Chisnall
12477a984708SDavid Chisnall    deque& operator=(const deque& __c);
1248540d2a8bSDimitry Andric
1249540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1250540d2a8bSDimitry Andric    deque(initializer_list<value_type> __il);
1251540d2a8bSDimitry Andric    deque(initializer_list<value_type> __il, const allocator_type& __a);
1252540d2a8bSDimitry Andric
12537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12547a984708SDavid Chisnall    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
12557a984708SDavid Chisnall
12569729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12577a984708SDavid Chisnall    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
12589729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12597a984708SDavid Chisnall    deque(deque&& __c, const allocator_type& __a);
12609729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12617a984708SDavid Chisnall    deque& operator=(deque&& __c)
12627a984708SDavid Chisnall        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
12637a984708SDavid Chisnall                   is_nothrow_move_assignable<allocator_type>::value);
1264540d2a8bSDimitry Andric
1265540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1266540d2a8bSDimitry Andric    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
1267540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
12687a984708SDavid Chisnall
12697a984708SDavid Chisnall    template <class _InputIter>
12707a984708SDavid Chisnall        void assign(_InputIter __f, _InputIter __l,
12717a984708SDavid Chisnall                    typename enable_if<__is_input_iterator<_InputIter>::value &&
12727a984708SDavid Chisnall                                      !__is_random_access_iterator<_InputIter>::value>::type* = 0);
12737a984708SDavid Chisnall    template <class _RAIter>
12747a984708SDavid Chisnall        void assign(_RAIter __f, _RAIter __l,
12757a984708SDavid Chisnall                    typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
12767a984708SDavid Chisnall    void assign(size_type __n, const value_type& __v);
12777a984708SDavid Chisnall
12789729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12797a984708SDavid Chisnall    allocator_type get_allocator() const _NOEXCEPT;
12807a984708SDavid Chisnall
12817a984708SDavid Chisnall    // iterators:
12827a984708SDavid Chisnall
12837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12847a984708SDavid Chisnall    iterator       begin() _NOEXCEPT       {return __base::begin();}
12857a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12867a984708SDavid Chisnall    const_iterator begin() const _NOEXCEPT {return __base::begin();}
12877a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12887a984708SDavid Chisnall    iterator       end() _NOEXCEPT         {return __base::end();}
12897a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12907a984708SDavid Chisnall    const_iterator end()   const _NOEXCEPT {return __base::end();}
12917a984708SDavid Chisnall
12927a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12937a984708SDavid Chisnall    reverse_iterator       rbegin() _NOEXCEPT
12947a984708SDavid Chisnall        {return       reverse_iterator(__base::end());}
12957a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12967a984708SDavid Chisnall    const_reverse_iterator rbegin() const _NOEXCEPT
12977a984708SDavid Chisnall        {return const_reverse_iterator(__base::end());}
12987a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12997a984708SDavid Chisnall    reverse_iterator       rend() _NOEXCEPT
13007a984708SDavid Chisnall        {return       reverse_iterator(__base::begin());}
13017a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13027a984708SDavid Chisnall    const_reverse_iterator rend()   const _NOEXCEPT
13037a984708SDavid Chisnall        {return const_reverse_iterator(__base::begin());}
13047a984708SDavid Chisnall
13057a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13067a984708SDavid Chisnall    const_iterator         cbegin()  const _NOEXCEPT
13077a984708SDavid Chisnall        {return __base::begin();}
13087a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13097a984708SDavid Chisnall    const_iterator         cend()    const _NOEXCEPT
13107a984708SDavid Chisnall        {return __base::end();}
13117a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13127a984708SDavid Chisnall    const_reverse_iterator crbegin() const _NOEXCEPT
13137a984708SDavid Chisnall        {return const_reverse_iterator(__base::end());}
13147a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13157a984708SDavid Chisnall    const_reverse_iterator crend()   const _NOEXCEPT
13167a984708SDavid Chisnall        {return const_reverse_iterator(__base::begin());}
13177a984708SDavid Chisnall
13187a984708SDavid Chisnall    // capacity:
13197a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13207a984708SDavid Chisnall    size_type size() const _NOEXCEPT {return __base::size();}
13217a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13227a984708SDavid Chisnall    size_type max_size() const _NOEXCEPT
1323aed8d94eSDimitry Andric        {return std::min<size_type>(
1324aed8d94eSDimitry Andric            __alloc_traits::max_size(__base::__alloc()),
1325aed8d94eSDimitry Andric            numeric_limits<difference_type>::max());}
13267a984708SDavid Chisnall    void resize(size_type __n);
13277a984708SDavid Chisnall    void resize(size_type __n, const value_type& __v);
13287a984708SDavid Chisnall    void shrink_to_fit() _NOEXCEPT;
1329b2c7081bSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
13307a984708SDavid Chisnall    bool empty() const _NOEXCEPT {return __base::size() == 0;}
13317a984708SDavid Chisnall
13327a984708SDavid Chisnall    // element access:
13339729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13347a984708SDavid Chisnall    reference operator[](size_type __i);
13359729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13367a984708SDavid Chisnall    const_reference operator[](size_type __i) const;
13379729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13387a984708SDavid Chisnall    reference at(size_type __i);
13399729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13407a984708SDavid Chisnall    const_reference at(size_type __i) const;
13419729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13427a984708SDavid Chisnall    reference front();
13439729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13447a984708SDavid Chisnall    const_reference front() const;
13459729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13467a984708SDavid Chisnall    reference back();
13479729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13487a984708SDavid Chisnall    const_reference back() const;
13497a984708SDavid Chisnall
13507a984708SDavid Chisnall    // 23.2.2.3 modifiers:
13517a984708SDavid Chisnall    void push_front(const value_type& __v);
13527a984708SDavid Chisnall    void push_back(const value_type& __v);
1353540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
135498221d2eSDimitry Andric#if _LIBCPP_STD_VER > 14
1355aed8d94eSDimitry Andric    template <class... _Args> reference emplace_front(_Args&&... __args);
1356aed8d94eSDimitry Andric    template <class... _Args> reference emplace_back (_Args&&... __args);
135798221d2eSDimitry Andric#else
135898221d2eSDimitry Andric    template <class... _Args> void      emplace_front(_Args&&... __args);
135998221d2eSDimitry Andric    template <class... _Args> void      emplace_back (_Args&&... __args);
136098221d2eSDimitry Andric#endif
13617a984708SDavid Chisnall    template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
1362540d2a8bSDimitry Andric
13637a984708SDavid Chisnall    void push_front(value_type&& __v);
13647a984708SDavid Chisnall    void push_back(value_type&& __v);
13657a984708SDavid Chisnall    iterator insert(const_iterator __p, value_type&& __v);
1366540d2a8bSDimitry Andric
1367540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1368540d2a8bSDimitry Andric    iterator insert(const_iterator __p, initializer_list<value_type> __il)
1369540d2a8bSDimitry Andric        {return insert(__p, __il.begin(), __il.end());}
1370540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
13717a984708SDavid Chisnall    iterator insert(const_iterator __p, const value_type& __v);
13727a984708SDavid Chisnall    iterator insert(const_iterator __p, size_type __n, const value_type& __v);
13737a984708SDavid Chisnall    template <class _InputIter>
13747a984708SDavid Chisnall        iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
13757a984708SDavid Chisnall                         typename enable_if<__is_input_iterator<_InputIter>::value
1376854fa44bSDimitry Andric                                         &&!__is_forward_iterator<_InputIter>::value>::type* = 0);
1377854fa44bSDimitry Andric    template <class _ForwardIterator>
1378854fa44bSDimitry Andric        iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
1379854fa44bSDimitry Andric                               typename enable_if<__is_forward_iterator<_ForwardIterator>::value
1380854fa44bSDimitry Andric                                         &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);
13817a984708SDavid Chisnall    template <class _BiIter>
13827a984708SDavid Chisnall        iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
13837a984708SDavid Chisnall                         typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0);
1384540d2a8bSDimitry Andric
13857a984708SDavid Chisnall    void pop_front();
13867a984708SDavid Chisnall    void pop_back();
13877a984708SDavid Chisnall    iterator erase(const_iterator __p);
13887a984708SDavid Chisnall    iterator erase(const_iterator __f, const_iterator __l);
13897a984708SDavid Chisnall
13909729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13917a984708SDavid Chisnall    void swap(deque& __c)
1392854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
1393854fa44bSDimitry Andric        _NOEXCEPT;
1394854fa44bSDimitry Andric#else
13957a984708SDavid Chisnall        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
13967a984708SDavid Chisnall                   __is_nothrow_swappable<allocator_type>::value);
1397854fa44bSDimitry Andric#endif
13989729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13997a984708SDavid Chisnall    void clear() _NOEXCEPT;
14007a984708SDavid Chisnall
14017a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14027a984708SDavid Chisnall    bool __invariants() const {return __base::__invariants();}
14037a984708SDavid Chisnallprivate:
14044bab9fd9SDavid Chisnall    typedef typename __base::__map_const_pointer __map_const_pointer;
14054bab9fd9SDavid Chisnall
14067a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14077a984708SDavid Chisnall    static size_type __recommend_blocks(size_type __n)
14087a984708SDavid Chisnall    {
14097a984708SDavid Chisnall        return __n / __base::__block_size + (__n % __base::__block_size != 0);
14107a984708SDavid Chisnall    }
14117a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14127a984708SDavid Chisnall    size_type __capacity() const
14137a984708SDavid Chisnall    {
14147a984708SDavid Chisnall        return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
14157a984708SDavid Chisnall    }
14167a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14177a984708SDavid Chisnall    size_type __front_spare() const
14187a984708SDavid Chisnall    {
14197a984708SDavid Chisnall        return __base::__start_;
14207a984708SDavid Chisnall    }
14217a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14227a984708SDavid Chisnall    size_type __back_spare() const
14237a984708SDavid Chisnall    {
14247a984708SDavid Chisnall        return __capacity() - (__base::__start_ + __base::size());
14257a984708SDavid Chisnall    }
14267a984708SDavid Chisnall
14277a984708SDavid Chisnall    template <class _InpIter>
14287a984708SDavid Chisnall        void __append(_InpIter __f, _InpIter __l,
14297a984708SDavid Chisnall                 typename enable_if<__is_input_iterator<_InpIter>::value &&
14307a984708SDavid Chisnall                                   !__is_forward_iterator<_InpIter>::value>::type* = 0);
14317a984708SDavid Chisnall    template <class _ForIter>
14327a984708SDavid Chisnall        void __append(_ForIter __f, _ForIter __l,
14337a984708SDavid Chisnall                      typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0);
14347a984708SDavid Chisnall    void __append(size_type __n);
14357a984708SDavid Chisnall    void __append(size_type __n, const value_type& __v);
14367a984708SDavid Chisnall    void __erase_to_end(const_iterator __f);
14377a984708SDavid Chisnall    void __add_front_capacity();
14387a984708SDavid Chisnall    void __add_front_capacity(size_type __n);
14397a984708SDavid Chisnall    void __add_back_capacity();
14407a984708SDavid Chisnall    void __add_back_capacity(size_type __n);
14417a984708SDavid Chisnall    iterator __move_and_check(iterator __f, iterator __l, iterator __r,
14427a984708SDavid Chisnall                              const_pointer& __vt);
14437a984708SDavid Chisnall    iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
14447a984708SDavid Chisnall                                       const_pointer& __vt);
14457a984708SDavid Chisnall    void __move_construct_and_check(iterator __f, iterator __l,
14467a984708SDavid Chisnall                                    iterator __r, const_pointer& __vt);
14477a984708SDavid Chisnall    void __move_construct_backward_and_check(iterator __f, iterator __l,
14487a984708SDavid Chisnall                                             iterator __r, const_pointer& __vt);
14497a984708SDavid Chisnall
14507a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14517a984708SDavid Chisnall    void __copy_assign_alloc(const deque& __c)
14527a984708SDavid Chisnall        {__copy_assign_alloc(__c, integral_constant<bool,
14537a984708SDavid Chisnall                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
14547a984708SDavid Chisnall
14557a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
14567a984708SDavid Chisnall    void __copy_assign_alloc(const deque& __c, true_type)
14577a984708SDavid Chisnall        {
14587a984708SDavid Chisnall            if (__base::__alloc() != __c.__alloc())
14597a984708SDavid Chisnall            {
14607a984708SDavid Chisnall                clear();
14617a984708SDavid Chisnall                shrink_to_fit();
14627a984708SDavid Chisnall            }
14637a984708SDavid Chisnall            __base::__alloc() = __c.__alloc();
14647a984708SDavid Chisnall            __base::__map_.__alloc() = __c.__map_.__alloc();
14657a984708SDavid Chisnall        }
14667a984708SDavid Chisnall
14677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
146894e3ee44SDavid Chisnall    void __copy_assign_alloc(const deque&, false_type)
14697a984708SDavid Chisnall        {}
14707a984708SDavid Chisnall
14717a984708SDavid Chisnall    void __move_assign(deque& __c, true_type)
14727a984708SDavid Chisnall        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
14737a984708SDavid Chisnall    void __move_assign(deque& __c, false_type);
14747a984708SDavid Chisnall};
14757a984708SDavid Chisnall
14764ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
14774ba319b5SDimitry Andrictemplate<class _InputIterator,
14784ba319b5SDimitry Andric         class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
14794ba319b5SDimitry Andric         class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
14804ba319b5SDimitry Andric         >
14814ba319b5SDimitry Andricdeque(_InputIterator, _InputIterator)
14824ba319b5SDimitry Andric  -> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
14834ba319b5SDimitry Andric
14844ba319b5SDimitry Andrictemplate<class _InputIterator,
14854ba319b5SDimitry Andric         class _Alloc,
14864ba319b5SDimitry Andric         class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
14874ba319b5SDimitry Andric         >
14884ba319b5SDimitry Andricdeque(_InputIterator, _InputIterator, _Alloc)
14894ba319b5SDimitry Andric  -> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
14904ba319b5SDimitry Andric#endif
14914ba319b5SDimitry Andric
14924ba319b5SDimitry Andric
14937a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
14947a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(size_type __n)
14957a984708SDavid Chisnall{
14967a984708SDavid Chisnall    if (__n > 0)
14977a984708SDavid Chisnall        __append(__n);
14987a984708SDavid Chisnall}
14997a984708SDavid Chisnall
15004f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
15014f7ab58eSDimitry Andrictemplate <class _Tp, class _Allocator>
15024f7ab58eSDimitry Andricdeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
15034f7ab58eSDimitry Andric    : __base(__a)
15044f7ab58eSDimitry Andric{
15054f7ab58eSDimitry Andric    if (__n > 0)
15064f7ab58eSDimitry Andric        __append(__n);
15074f7ab58eSDimitry Andric}
15084f7ab58eSDimitry Andric#endif
15094f7ab58eSDimitry Andric
15107a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15117a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
15127a984708SDavid Chisnall{
15137a984708SDavid Chisnall    if (__n > 0)
15147a984708SDavid Chisnall        __append(__n, __v);
15157a984708SDavid Chisnall}
15167a984708SDavid Chisnall
15177a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15187a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
15197a984708SDavid Chisnall    : __base(__a)
15207a984708SDavid Chisnall{
15217a984708SDavid Chisnall    if (__n > 0)
15227a984708SDavid Chisnall        __append(__n, __v);
15237a984708SDavid Chisnall}
15247a984708SDavid Chisnall
15257a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15267a984708SDavid Chisnalltemplate <class _InputIter>
15277a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
15287a984708SDavid Chisnall              typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
15297a984708SDavid Chisnall{
15307a984708SDavid Chisnall    __append(__f, __l);
15317a984708SDavid Chisnall}
15327a984708SDavid Chisnall
15337a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15347a984708SDavid Chisnalltemplate <class _InputIter>
15357a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
15367a984708SDavid Chisnall              typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
15377a984708SDavid Chisnall    : __base(__a)
15387a984708SDavid Chisnall{
15397a984708SDavid Chisnall    __append(__f, __l);
15407a984708SDavid Chisnall}
15417a984708SDavid Chisnall
15427a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15437a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(const deque& __c)
15447a984708SDavid Chisnall    : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
15457a984708SDavid Chisnall{
15467a984708SDavid Chisnall    __append(__c.begin(), __c.end());
15477a984708SDavid Chisnall}
15487a984708SDavid Chisnall
15497a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15507a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
15517a984708SDavid Chisnall    : __base(__a)
15527a984708SDavid Chisnall{
15537a984708SDavid Chisnall    __append(__c.begin(), __c.end());
15547a984708SDavid Chisnall}
15557a984708SDavid Chisnall
1556540d2a8bSDimitry Andrictemplate <class _Tp, class _Allocator>
1557540d2a8bSDimitry Andricdeque<_Tp, _Allocator>&
1558540d2a8bSDimitry Andricdeque<_Tp, _Allocator>::operator=(const deque& __c)
1559540d2a8bSDimitry Andric{
1560540d2a8bSDimitry Andric    if (this != &__c)
1561540d2a8bSDimitry Andric    {
1562540d2a8bSDimitry Andric        __copy_assign_alloc(__c);
1563540d2a8bSDimitry Andric        assign(__c.begin(), __c.end());
1564540d2a8bSDimitry Andric    }
1565540d2a8bSDimitry Andric    return *this;
1566540d2a8bSDimitry Andric}
1567540d2a8bSDimitry Andric
1568540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
15697a984708SDavid Chisnall
15707a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15717a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
15727a984708SDavid Chisnall{
15737a984708SDavid Chisnall    __append(__il.begin(), __il.end());
15747a984708SDavid Chisnall}
15757a984708SDavid Chisnall
15767a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15777a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
15787a984708SDavid Chisnall    : __base(__a)
15797a984708SDavid Chisnall{
15807a984708SDavid Chisnall    __append(__il.begin(), __il.end());
15817a984708SDavid Chisnall}
15827a984708SDavid Chisnall
15837a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15849729cf09SDimitry Andricinline
15857a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(deque&& __c)
15867a984708SDavid Chisnall    _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
15877a984708SDavid Chisnall    : __base(_VSTD::move(__c))
15887a984708SDavid Chisnall{
15897a984708SDavid Chisnall}
15907a984708SDavid Chisnall
15917a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
15929729cf09SDimitry Andricinline
15937a984708SDavid Chisnalldeque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
15947a984708SDavid Chisnall    : __base(_VSTD::move(__c), __a)
15957a984708SDavid Chisnall{
15967a984708SDavid Chisnall    if (__a != __c.__alloc())
15977a984708SDavid Chisnall    {
159894e3ee44SDavid Chisnall        typedef move_iterator<iterator> _Ip;
159994e3ee44SDavid Chisnall        assign(_Ip(__c.begin()), _Ip(__c.end()));
16007a984708SDavid Chisnall    }
16017a984708SDavid Chisnall}
16027a984708SDavid Chisnall
16037a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16049729cf09SDimitry Andricinline
16057a984708SDavid Chisnalldeque<_Tp, _Allocator>&
16067a984708SDavid Chisnalldeque<_Tp, _Allocator>::operator=(deque&& __c)
16077a984708SDavid Chisnall        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
16087a984708SDavid Chisnall                   is_nothrow_move_assignable<allocator_type>::value)
16097a984708SDavid Chisnall{
16107a984708SDavid Chisnall    __move_assign(__c, integral_constant<bool,
16117a984708SDavid Chisnall          __alloc_traits::propagate_on_container_move_assignment::value>());
16127a984708SDavid Chisnall    return *this;
16137a984708SDavid Chisnall}
16147a984708SDavid Chisnall
16157a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16167a984708SDavid Chisnallvoid
16177a984708SDavid Chisnalldeque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
16187a984708SDavid Chisnall{
16197a984708SDavid Chisnall    if (__base::__alloc() != __c.__alloc())
16207a984708SDavid Chisnall    {
162194e3ee44SDavid Chisnall        typedef move_iterator<iterator> _Ip;
162294e3ee44SDavid Chisnall        assign(_Ip(__c.begin()), _Ip(__c.end()));
16237a984708SDavid Chisnall    }
16247a984708SDavid Chisnall    else
16257a984708SDavid Chisnall        __move_assign(__c, true_type());
16267a984708SDavid Chisnall}
16277a984708SDavid Chisnall
16287a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16297a984708SDavid Chisnallvoid
16307a984708SDavid Chisnalldeque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
16317a984708SDavid Chisnall    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
16327a984708SDavid Chisnall{
16337a984708SDavid Chisnall    clear();
16347a984708SDavid Chisnall    shrink_to_fit();
16357a984708SDavid Chisnall    __base::__move_assign(__c);
16367a984708SDavid Chisnall}
16377a984708SDavid Chisnall
1638540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
16397a984708SDavid Chisnall
16407a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16417a984708SDavid Chisnalltemplate <class _InputIter>
16427a984708SDavid Chisnallvoid
16437a984708SDavid Chisnalldeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
16447a984708SDavid Chisnall                               typename enable_if<__is_input_iterator<_InputIter>::value &&
16457a984708SDavid Chisnall                                                 !__is_random_access_iterator<_InputIter>::value>::type*)
16467a984708SDavid Chisnall{
16477a984708SDavid Chisnall    iterator __i = __base::begin();
16487a984708SDavid Chisnall    iterator __e = __base::end();
1649d72607e9SDimitry Andric    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
16507a984708SDavid Chisnall        *__i = *__f;
16517a984708SDavid Chisnall    if (__f != __l)
16527a984708SDavid Chisnall        __append(__f, __l);
16537a984708SDavid Chisnall    else
16547a984708SDavid Chisnall        __erase_to_end(__i);
16557a984708SDavid Chisnall}
16567a984708SDavid Chisnall
16577a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16587a984708SDavid Chisnalltemplate <class _RAIter>
16597a984708SDavid Chisnallvoid
16607a984708SDavid Chisnalldeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
16617a984708SDavid Chisnall                               typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
16627a984708SDavid Chisnall{
16637a984708SDavid Chisnall    if (static_cast<size_type>(__l - __f) > __base::size())
16647a984708SDavid Chisnall    {
16657a984708SDavid Chisnall        _RAIter __m = __f + __base::size();
16667a984708SDavid Chisnall        _VSTD::copy(__f, __m, __base::begin());
16677a984708SDavid Chisnall        __append(__m, __l);
16687a984708SDavid Chisnall    }
16697a984708SDavid Chisnall    else
16707a984708SDavid Chisnall        __erase_to_end(_VSTD::copy(__f, __l, __base::begin()));
16717a984708SDavid Chisnall}
16727a984708SDavid Chisnall
16737a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16747a984708SDavid Chisnallvoid
16757a984708SDavid Chisnalldeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
16767a984708SDavid Chisnall{
16777a984708SDavid Chisnall    if (__n > __base::size())
16787a984708SDavid Chisnall    {
16797a984708SDavid Chisnall        _VSTD::fill_n(__base::begin(), __base::size(), __v);
16807a984708SDavid Chisnall        __n -= __base::size();
16817a984708SDavid Chisnall        __append(__n, __v);
16827a984708SDavid Chisnall    }
16837a984708SDavid Chisnall    else
16847a984708SDavid Chisnall        __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));
16857a984708SDavid Chisnall}
16867a984708SDavid Chisnall
16877a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16889729cf09SDimitry Andricinline
16897a984708SDavid Chisnall_Allocator
16907a984708SDavid Chisnalldeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
16917a984708SDavid Chisnall{
16927a984708SDavid Chisnall    return __base::__alloc();
16937a984708SDavid Chisnall}
16947a984708SDavid Chisnall
16957a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
16967a984708SDavid Chisnallvoid
16977a984708SDavid Chisnalldeque<_Tp, _Allocator>::resize(size_type __n)
16987a984708SDavid Chisnall{
16997a984708SDavid Chisnall    if (__n > __base::size())
17007a984708SDavid Chisnall        __append(__n - __base::size());
17017a984708SDavid Chisnall    else if (__n < __base::size())
17027a984708SDavid Chisnall        __erase_to_end(__base::begin() + __n);
17037a984708SDavid Chisnall}
17047a984708SDavid Chisnall
17057a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17067a984708SDavid Chisnallvoid
17077a984708SDavid Chisnalldeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
17087a984708SDavid Chisnall{
17097a984708SDavid Chisnall    if (__n > __base::size())
17107a984708SDavid Chisnall        __append(__n - __base::size(), __v);
17117a984708SDavid Chisnall    else if (__n < __base::size())
17127a984708SDavid Chisnall        __erase_to_end(__base::begin() + __n);
17137a984708SDavid Chisnall}
17147a984708SDavid Chisnall
17157a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17167a984708SDavid Chisnallvoid
17177a984708SDavid Chisnalldeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
17187a984708SDavid Chisnall{
17197a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
17207a984708SDavid Chisnall    if (empty())
17217a984708SDavid Chisnall    {
17227a984708SDavid Chisnall        while (__base::__map_.size() > 0)
17237a984708SDavid Chisnall        {
17247a984708SDavid Chisnall            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
17257a984708SDavid Chisnall            __base::__map_.pop_back();
17267a984708SDavid Chisnall        }
17277a984708SDavid Chisnall        __base::__start_ = 0;
17287a984708SDavid Chisnall    }
17297a984708SDavid Chisnall    else
17307a984708SDavid Chisnall    {
17317a984708SDavid Chisnall        if (__front_spare() >= __base::__block_size)
17327a984708SDavid Chisnall        {
17337a984708SDavid Chisnall            __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
17347a984708SDavid Chisnall            __base::__map_.pop_front();
17357a984708SDavid Chisnall            __base::__start_ -= __base::__block_size;
17367a984708SDavid Chisnall        }
17377a984708SDavid Chisnall        if (__back_spare() >= __base::__block_size)
17387a984708SDavid Chisnall        {
17397a984708SDavid Chisnall            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
17407a984708SDavid Chisnall            __base::__map_.pop_back();
17417a984708SDavid Chisnall        }
17427a984708SDavid Chisnall    }
17437a984708SDavid Chisnall    __base::__map_.shrink_to_fit();
17447a984708SDavid Chisnall}
17457a984708SDavid Chisnall
17467a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17479729cf09SDimitry Andricinline
17487a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::reference
17497a984708SDavid Chisnalldeque<_Tp, _Allocator>::operator[](size_type __i)
17507a984708SDavid Chisnall{
17517a984708SDavid Chisnall    size_type __p = __base::__start_ + __i;
17527a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
17537a984708SDavid Chisnall}
17547a984708SDavid Chisnall
17557a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17569729cf09SDimitry Andricinline
17577a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::const_reference
17587a984708SDavid Chisnalldeque<_Tp, _Allocator>::operator[](size_type __i) const
17597a984708SDavid Chisnall{
17607a984708SDavid Chisnall    size_type __p = __base::__start_ + __i;
17617a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
17627a984708SDavid Chisnall}
17637a984708SDavid Chisnall
17647a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17659729cf09SDimitry Andricinline
17667a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::reference
17677a984708SDavid Chisnalldeque<_Tp, _Allocator>::at(size_type __i)
17687a984708SDavid Chisnall{
17697a984708SDavid Chisnall    if (__i >= __base::size())
17707a984708SDavid Chisnall        __base::__throw_out_of_range();
17717a984708SDavid Chisnall    size_type __p = __base::__start_ + __i;
17727a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
17737a984708SDavid Chisnall}
17747a984708SDavid Chisnall
17757a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17769729cf09SDimitry Andricinline
17777a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::const_reference
17787a984708SDavid Chisnalldeque<_Tp, _Allocator>::at(size_type __i) const
17797a984708SDavid Chisnall{
17807a984708SDavid Chisnall    if (__i >= __base::size())
17817a984708SDavid Chisnall        __base::__throw_out_of_range();
17827a984708SDavid Chisnall    size_type __p = __base::__start_ + __i;
17837a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
17847a984708SDavid Chisnall}
17857a984708SDavid Chisnall
17867a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17879729cf09SDimitry Andricinline
17887a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::reference
17897a984708SDavid Chisnalldeque<_Tp, _Allocator>::front()
17907a984708SDavid Chisnall{
17917a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
17927a984708SDavid Chisnall                                      + __base::__start_ % __base::__block_size);
17937a984708SDavid Chisnall}
17947a984708SDavid Chisnall
17957a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
17969729cf09SDimitry Andricinline
17977a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::const_reference
17987a984708SDavid Chisnalldeque<_Tp, _Allocator>::front() const
17997a984708SDavid Chisnall{
18007a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
18017a984708SDavid Chisnall                                      + __base::__start_ % __base::__block_size);
18027a984708SDavid Chisnall}
18037a984708SDavid Chisnall
18047a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18059729cf09SDimitry Andricinline
18067a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::reference
18077a984708SDavid Chisnalldeque<_Tp, _Allocator>::back()
18087a984708SDavid Chisnall{
18097a984708SDavid Chisnall    size_type __p = __base::size() + __base::__start_ - 1;
18107a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
18117a984708SDavid Chisnall}
18127a984708SDavid Chisnall
18137a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18149729cf09SDimitry Andricinline
18157a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::const_reference
18167a984708SDavid Chisnalldeque<_Tp, _Allocator>::back() const
18177a984708SDavid Chisnall{
18187a984708SDavid Chisnall    size_type __p = __base::size() + __base::__start_ - 1;
18197a984708SDavid Chisnall    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
18207a984708SDavid Chisnall}
18217a984708SDavid Chisnall
18227a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18237a984708SDavid Chisnallvoid
18247a984708SDavid Chisnalldeque<_Tp, _Allocator>::push_back(const value_type& __v)
18257a984708SDavid Chisnall{
18267a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
18277a984708SDavid Chisnall    if (__back_spare() == 0)
18287a984708SDavid Chisnall        __add_back_capacity();
18297a984708SDavid Chisnall    // __back_spare() >= 1
18307a984708SDavid Chisnall    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
18317a984708SDavid Chisnall    ++__base::size();
18327a984708SDavid Chisnall}
18337a984708SDavid Chisnall
1834540d2a8bSDimitry Andrictemplate <class _Tp, class _Allocator>
1835540d2a8bSDimitry Andricvoid
1836540d2a8bSDimitry Andricdeque<_Tp, _Allocator>::push_front(const value_type& __v)
1837540d2a8bSDimitry Andric{
1838540d2a8bSDimitry Andric    allocator_type& __a = __base::__alloc();
1839540d2a8bSDimitry Andric    if (__front_spare() == 0)
1840540d2a8bSDimitry Andric        __add_front_capacity();
1841540d2a8bSDimitry Andric    // __front_spare() >= 1
1842540d2a8bSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
1843540d2a8bSDimitry Andric    --__base::__start_;
1844540d2a8bSDimitry Andric    ++__base::size();
1845540d2a8bSDimitry Andric}
18467a984708SDavid Chisnall
1847540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
18487a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18497a984708SDavid Chisnallvoid
18507a984708SDavid Chisnalldeque<_Tp, _Allocator>::push_back(value_type&& __v)
18517a984708SDavid Chisnall{
18527a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
18537a984708SDavid Chisnall    if (__back_spare() == 0)
18547a984708SDavid Chisnall        __add_back_capacity();
18557a984708SDavid Chisnall    // __back_spare() >= 1
18567a984708SDavid Chisnall    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
18577a984708SDavid Chisnall    ++__base::size();
18587a984708SDavid Chisnall}
18597a984708SDavid Chisnall
18607a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18617a984708SDavid Chisnalltemplate <class... _Args>
186298221d2eSDimitry Andric#if _LIBCPP_STD_VER > 14
1863aed8d94eSDimitry Andrictypename deque<_Tp, _Allocator>::reference
186498221d2eSDimitry Andric#else
186598221d2eSDimitry Andricvoid
186698221d2eSDimitry Andric#endif
18677a984708SDavid Chisnalldeque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
18687a984708SDavid Chisnall{
18697a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
18707a984708SDavid Chisnall    if (__back_spare() == 0)
18717a984708SDavid Chisnall        __add_back_capacity();
18727a984708SDavid Chisnall    // __back_spare() >= 1
1873aed8d94eSDimitry Andric    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()),
1874aed8d94eSDimitry Andric                              _VSTD::forward<_Args>(__args)...);
18757a984708SDavid Chisnall    ++__base::size();
187698221d2eSDimitry Andric#if _LIBCPP_STD_VER > 14
1877aed8d94eSDimitry Andric    return *--__base::end();
187898221d2eSDimitry Andric#endif
18797a984708SDavid Chisnall}
18807a984708SDavid Chisnall
18817a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18827a984708SDavid Chisnallvoid
18837a984708SDavid Chisnalldeque<_Tp, _Allocator>::push_front(value_type&& __v)
18847a984708SDavid Chisnall{
18857a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
18867a984708SDavid Chisnall    if (__front_spare() == 0)
18877a984708SDavid Chisnall        __add_front_capacity();
18887a984708SDavid Chisnall    // __front_spare() >= 1
18897a984708SDavid Chisnall    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
18907a984708SDavid Chisnall    --__base::__start_;
18917a984708SDavid Chisnall    ++__base::size();
18927a984708SDavid Chisnall}
18937a984708SDavid Chisnall
18947a984708SDavid Chisnall
18957a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
18967a984708SDavid Chisnalltemplate <class... _Args>
189798221d2eSDimitry Andric#if _LIBCPP_STD_VER > 14
1898aed8d94eSDimitry Andrictypename deque<_Tp, _Allocator>::reference
189998221d2eSDimitry Andric#else
190098221d2eSDimitry Andricvoid
190198221d2eSDimitry Andric#endif
19027a984708SDavid Chisnalldeque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
19037a984708SDavid Chisnall{
19047a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
19057a984708SDavid Chisnall    if (__front_spare() == 0)
19067a984708SDavid Chisnall        __add_front_capacity();
19077a984708SDavid Chisnall    // __front_spare() >= 1
19087a984708SDavid Chisnall    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
19097a984708SDavid Chisnall    --__base::__start_;
19107a984708SDavid Chisnall    ++__base::size();
191198221d2eSDimitry Andric#if _LIBCPP_STD_VER > 14
1912aed8d94eSDimitry Andric    return *__base::begin();
191398221d2eSDimitry Andric#endif
19147a984708SDavid Chisnall}
19157a984708SDavid Chisnall
1916540d2a8bSDimitry Andrictemplate <class _Tp, class _Allocator>
1917540d2a8bSDimitry Andrictypename deque<_Tp, _Allocator>::iterator
1918540d2a8bSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
1919540d2a8bSDimitry Andric{
1920540d2a8bSDimitry Andric    size_type __pos = __p - __base::begin();
1921540d2a8bSDimitry Andric    size_type __to_end = __base::size() - __pos;
1922540d2a8bSDimitry Andric    allocator_type& __a = __base::__alloc();
1923540d2a8bSDimitry Andric    if (__pos < __to_end)
1924540d2a8bSDimitry Andric    {   // insert by shifting things backward
1925540d2a8bSDimitry Andric        if (__front_spare() == 0)
1926540d2a8bSDimitry Andric            __add_front_capacity();
1927540d2a8bSDimitry Andric        // __front_spare() >= 1
1928540d2a8bSDimitry Andric        if (__pos == 0)
1929540d2a8bSDimitry Andric        {
1930540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
1931540d2a8bSDimitry Andric            --__base::__start_;
1932540d2a8bSDimitry Andric            ++__base::size();
1933540d2a8bSDimitry Andric        }
1934540d2a8bSDimitry Andric        else
1935540d2a8bSDimitry Andric        {
1936540d2a8bSDimitry Andric            iterator __b = __base::begin();
1937540d2a8bSDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
1938540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1939540d2a8bSDimitry Andric            --__base::__start_;
1940540d2a8bSDimitry Andric            ++__base::size();
1941540d2a8bSDimitry Andric            if (__pos > 1)
1942540d2a8bSDimitry Andric                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
1943540d2a8bSDimitry Andric            *__b = _VSTD::move(__v);
1944540d2a8bSDimitry Andric        }
1945540d2a8bSDimitry Andric    }
1946540d2a8bSDimitry Andric    else
1947540d2a8bSDimitry Andric    {   // insert by shifting things forward
1948540d2a8bSDimitry Andric        if (__back_spare() == 0)
1949540d2a8bSDimitry Andric            __add_back_capacity();
1950540d2a8bSDimitry Andric        // __back_capacity >= 1
1951540d2a8bSDimitry Andric        size_type __de = __base::size() - __pos;
1952540d2a8bSDimitry Andric        if (__de == 0)
1953540d2a8bSDimitry Andric        {
1954540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
1955540d2a8bSDimitry Andric            ++__base::size();
1956540d2a8bSDimitry Andric        }
1957540d2a8bSDimitry Andric        else
1958540d2a8bSDimitry Andric        {
1959540d2a8bSDimitry Andric            iterator __e = __base::end();
1960540d2a8bSDimitry Andric            iterator __em1 = _VSTD::prev(__e);
1961540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
1962540d2a8bSDimitry Andric            ++__base::size();
1963540d2a8bSDimitry Andric            if (__de > 1)
1964540d2a8bSDimitry Andric                __e = _VSTD::move_backward(__e - __de, __em1, __e);
1965540d2a8bSDimitry Andric            *--__e = _VSTD::move(__v);
1966540d2a8bSDimitry Andric        }
1967540d2a8bSDimitry Andric    }
1968540d2a8bSDimitry Andric    return __base::begin() + __pos;
1969540d2a8bSDimitry Andric}
1970540d2a8bSDimitry Andric
1971540d2a8bSDimitry Andrictemplate <class _Tp, class _Allocator>
1972540d2a8bSDimitry Andrictemplate <class... _Args>
1973540d2a8bSDimitry Andrictypename deque<_Tp, _Allocator>::iterator
1974540d2a8bSDimitry Andricdeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
1975540d2a8bSDimitry Andric{
1976540d2a8bSDimitry Andric    size_type __pos = __p - __base::begin();
1977540d2a8bSDimitry Andric    size_type __to_end = __base::size() - __pos;
1978540d2a8bSDimitry Andric    allocator_type& __a = __base::__alloc();
1979540d2a8bSDimitry Andric    if (__pos < __to_end)
1980540d2a8bSDimitry Andric    {   // insert by shifting things backward
1981540d2a8bSDimitry Andric        if (__front_spare() == 0)
1982540d2a8bSDimitry Andric            __add_front_capacity();
1983540d2a8bSDimitry Andric        // __front_spare() >= 1
1984540d2a8bSDimitry Andric        if (__pos == 0)
1985540d2a8bSDimitry Andric        {
1986540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
1987540d2a8bSDimitry Andric            --__base::__start_;
1988540d2a8bSDimitry Andric            ++__base::size();
1989540d2a8bSDimitry Andric        }
1990540d2a8bSDimitry Andric        else
1991540d2a8bSDimitry Andric        {
1992540d2a8bSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
1993540d2a8bSDimitry Andric            iterator __b = __base::begin();
1994540d2a8bSDimitry Andric            iterator __bm1 = _VSTD::prev(__b);
1995540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
1996540d2a8bSDimitry Andric            --__base::__start_;
1997540d2a8bSDimitry Andric            ++__base::size();
1998540d2a8bSDimitry Andric            if (__pos > 1)
1999540d2a8bSDimitry Andric                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
2000540d2a8bSDimitry Andric            *__b = _VSTD::move(__tmp.get());
2001540d2a8bSDimitry Andric        }
2002540d2a8bSDimitry Andric    }
2003540d2a8bSDimitry Andric    else
2004540d2a8bSDimitry Andric    {   // insert by shifting things forward
2005540d2a8bSDimitry Andric        if (__back_spare() == 0)
2006540d2a8bSDimitry Andric            __add_back_capacity();
2007540d2a8bSDimitry Andric        // __back_capacity >= 1
2008540d2a8bSDimitry Andric        size_type __de = __base::size() - __pos;
2009540d2a8bSDimitry Andric        if (__de == 0)
2010540d2a8bSDimitry Andric        {
2011540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
2012540d2a8bSDimitry Andric            ++__base::size();
2013540d2a8bSDimitry Andric        }
2014540d2a8bSDimitry Andric        else
2015540d2a8bSDimitry Andric        {
2016540d2a8bSDimitry Andric            __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...);
2017540d2a8bSDimitry Andric            iterator __e = __base::end();
2018540d2a8bSDimitry Andric            iterator __em1 = _VSTD::prev(__e);
2019540d2a8bSDimitry Andric            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
2020540d2a8bSDimitry Andric            ++__base::size();
2021540d2a8bSDimitry Andric            if (__de > 1)
2022540d2a8bSDimitry Andric                __e = _VSTD::move_backward(__e - __de, __em1, __e);
2023540d2a8bSDimitry Andric            *--__e = _VSTD::move(__tmp.get());
2024540d2a8bSDimitry Andric        }
2025540d2a8bSDimitry Andric    }
2026540d2a8bSDimitry Andric    return __base::begin() + __pos;
2027540d2a8bSDimitry Andric}
2028540d2a8bSDimitry Andric
2029540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
2030540d2a8bSDimitry Andric
20317a984708SDavid Chisnall
20327a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
20337a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
20347a984708SDavid Chisnalldeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
20357a984708SDavid Chisnall{
20367a984708SDavid Chisnall    size_type __pos = __p - __base::begin();
20377a984708SDavid Chisnall    size_type __to_end = __base::size() - __pos;
20387a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
20397a984708SDavid Chisnall    if (__pos < __to_end)
20407a984708SDavid Chisnall    {   // insert by shifting things backward
20417a984708SDavid Chisnall        if (__front_spare() == 0)
20427a984708SDavid Chisnall            __add_front_capacity();
20437a984708SDavid Chisnall        // __front_spare() >= 1
20447a984708SDavid Chisnall        if (__pos == 0)
20457a984708SDavid Chisnall        {
20467a984708SDavid Chisnall            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
20477a984708SDavid Chisnall            --__base::__start_;
20487a984708SDavid Chisnall            ++__base::size();
20497a984708SDavid Chisnall        }
20507a984708SDavid Chisnall        else
20517a984708SDavid Chisnall        {
20527a984708SDavid Chisnall            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
20537a984708SDavid Chisnall            iterator __b = __base::begin();
20547a984708SDavid Chisnall            iterator __bm1 = _VSTD::prev(__b);
20557a984708SDavid Chisnall            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
20567a984708SDavid Chisnall                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
20577a984708SDavid Chisnall            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
20587a984708SDavid Chisnall            --__base::__start_;
20597a984708SDavid Chisnall            ++__base::size();
20607a984708SDavid Chisnall            if (__pos > 1)
20617a984708SDavid Chisnall                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
20627a984708SDavid Chisnall            *__b = *__vt;
20637a984708SDavid Chisnall        }
20647a984708SDavid Chisnall    }
20657a984708SDavid Chisnall    else
20667a984708SDavid Chisnall    {   // insert by shifting things forward
20677a984708SDavid Chisnall        if (__back_spare() == 0)
20687a984708SDavid Chisnall            __add_back_capacity();
20697a984708SDavid Chisnall        // __back_capacity >= 1
20707a984708SDavid Chisnall        size_type __de = __base::size() - __pos;
20717a984708SDavid Chisnall        if (__de == 0)
20727a984708SDavid Chisnall        {
20737a984708SDavid Chisnall            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
20747a984708SDavid Chisnall            ++__base::size();
20757a984708SDavid Chisnall        }
20767a984708SDavid Chisnall        else
20777a984708SDavid Chisnall        {
20787a984708SDavid Chisnall            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
20797a984708SDavid Chisnall            iterator __e = __base::end();
20807a984708SDavid Chisnall            iterator __em1 = _VSTD::prev(__e);
20817a984708SDavid Chisnall            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
20827a984708SDavid Chisnall                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
20837a984708SDavid Chisnall            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
20847a984708SDavid Chisnall            ++__base::size();
20857a984708SDavid Chisnall            if (__de > 1)
20867a984708SDavid Chisnall                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
20877a984708SDavid Chisnall            *--__e = *__vt;
20887a984708SDavid Chisnall        }
20897a984708SDavid Chisnall    }
20907a984708SDavid Chisnall    return __base::begin() + __pos;
20917a984708SDavid Chisnall}
20927a984708SDavid Chisnall
20937a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
20947a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
20957a984708SDavid Chisnalldeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
20967a984708SDavid Chisnall{
20977a984708SDavid Chisnall    size_type __pos = __p - __base::begin();
20987a984708SDavid Chisnall    size_type __to_end = __base::size() - __pos;
20997a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
21007a984708SDavid Chisnall    if (__pos < __to_end)
21017a984708SDavid Chisnall    {   // insert by shifting things backward
21027a984708SDavid Chisnall        if (__n > __front_spare())
21037a984708SDavid Chisnall            __add_front_capacity(__n - __front_spare());
21047a984708SDavid Chisnall        // __n <= __front_spare()
21057a984708SDavid Chisnall        iterator __old_begin = __base::begin();
21067a984708SDavid Chisnall        iterator __i = __old_begin;
21077a984708SDavid Chisnall        if (__n > __pos)
21087a984708SDavid Chisnall        {
21097a984708SDavid Chisnall            for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
21107a984708SDavid Chisnall                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
21117a984708SDavid Chisnall            __n = __pos;
21127a984708SDavid Chisnall        }
21137a984708SDavid Chisnall        if (__n > 0)
21147a984708SDavid Chisnall        {
21157a984708SDavid Chisnall            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
21167a984708SDavid Chisnall            iterator __obn = __old_begin + __n;
21177a984708SDavid Chisnall            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
21187a984708SDavid Chisnall            if (__n < __pos)
21197a984708SDavid Chisnall                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
21207a984708SDavid Chisnall            _VSTD::fill_n(__old_begin, __n, *__vt);
21217a984708SDavid Chisnall        }
21227a984708SDavid Chisnall    }
21237a984708SDavid Chisnall    else
21247a984708SDavid Chisnall    {   // insert by shifting things forward
21257a984708SDavid Chisnall        size_type __back_capacity = __back_spare();
21267a984708SDavid Chisnall        if (__n > __back_capacity)
21277a984708SDavid Chisnall            __add_back_capacity(__n - __back_capacity);
21287a984708SDavid Chisnall        // __n <= __back_capacity
21297a984708SDavid Chisnall        iterator __old_end = __base::end();
21307a984708SDavid Chisnall        iterator __i = __old_end;
21317a984708SDavid Chisnall        size_type __de = __base::size() - __pos;
21327a984708SDavid Chisnall        if (__n > __de)
21337a984708SDavid Chisnall        {
21347a984708SDavid Chisnall            for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
21357a984708SDavid Chisnall                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
21367a984708SDavid Chisnall            __n = __de;
21377a984708SDavid Chisnall        }
21387a984708SDavid Chisnall        if (__n > 0)
21397a984708SDavid Chisnall        {
21407a984708SDavid Chisnall            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
21417a984708SDavid Chisnall            iterator __oen = __old_end - __n;
21427a984708SDavid Chisnall            __move_construct_and_check(__oen, __old_end, __i, __vt);
21437a984708SDavid Chisnall            if (__n < __de)
21447a984708SDavid Chisnall                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
21457a984708SDavid Chisnall            _VSTD::fill_n(__old_end - __n, __n, *__vt);
21467a984708SDavid Chisnall        }
21477a984708SDavid Chisnall    }
21487a984708SDavid Chisnall    return __base::begin() + __pos;
21497a984708SDavid Chisnall}
21507a984708SDavid Chisnall
21517a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
21527a984708SDavid Chisnalltemplate <class _InputIter>
21537a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
21547a984708SDavid Chisnalldeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
21557a984708SDavid Chisnall                               typename enable_if<__is_input_iterator<_InputIter>::value
2156854fa44bSDimitry Andric                                               &&!__is_forward_iterator<_InputIter>::value>::type*)
21577a984708SDavid Chisnall{
21587a984708SDavid Chisnall    __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
21597a984708SDavid Chisnall    __buf.__construct_at_end(__f, __l);
21607a984708SDavid Chisnall    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
21617a984708SDavid Chisnall    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
21627a984708SDavid Chisnall}
21637a984708SDavid Chisnall
21647a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
2165854fa44bSDimitry Andrictemplate <class _ForwardIterator>
2166854fa44bSDimitry Andrictypename deque<_Tp, _Allocator>::iterator
2167854fa44bSDimitry Andricdeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
2168854fa44bSDimitry Andric                               typename enable_if<__is_forward_iterator<_ForwardIterator>::value
2169854fa44bSDimitry Andric                                               &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type*)
2170854fa44bSDimitry Andric{
2171854fa44bSDimitry Andric    size_type __n = _VSTD::distance(__f, __l);
2172854fa44bSDimitry Andric    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
2173854fa44bSDimitry Andric    __buf.__construct_at_end(__f, __l);
2174854fa44bSDimitry Andric    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
2175854fa44bSDimitry Andric    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
2176854fa44bSDimitry Andric}
2177854fa44bSDimitry Andric
2178854fa44bSDimitry Andrictemplate <class _Tp, class _Allocator>
21797a984708SDavid Chisnalltemplate <class _BiIter>
21807a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
21817a984708SDavid Chisnalldeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
21827a984708SDavid Chisnall                               typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*)
21837a984708SDavid Chisnall{
21847a984708SDavid Chisnall    size_type __n = _VSTD::distance(__f, __l);
21857a984708SDavid Chisnall    size_type __pos = __p - __base::begin();
21867a984708SDavid Chisnall    size_type __to_end = __base::size() - __pos;
21877a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
21887a984708SDavid Chisnall    if (__pos < __to_end)
21897a984708SDavid Chisnall    {   // insert by shifting things backward
21907a984708SDavid Chisnall        if (__n > __front_spare())
21917a984708SDavid Chisnall            __add_front_capacity(__n - __front_spare());
21927a984708SDavid Chisnall        // __n <= __front_spare()
21937a984708SDavid Chisnall        iterator __old_begin = __base::begin();
21947a984708SDavid Chisnall        iterator __i = __old_begin;
21957a984708SDavid Chisnall        _BiIter __m = __f;
21967a984708SDavid Chisnall        if (__n > __pos)
21977a984708SDavid Chisnall        {
21987a984708SDavid Chisnall            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
21997a984708SDavid Chisnall            for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
22007a984708SDavid Chisnall                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
22017a984708SDavid Chisnall            __n = __pos;
22027a984708SDavid Chisnall        }
22037a984708SDavid Chisnall        if (__n > 0)
22047a984708SDavid Chisnall        {
22057a984708SDavid Chisnall            iterator __obn = __old_begin + __n;
22067a984708SDavid Chisnall            for (iterator __j = __obn; __j != __old_begin;)
22077a984708SDavid Chisnall            {
22087a984708SDavid Chisnall                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
22097a984708SDavid Chisnall                --__base::__start_;
22107a984708SDavid Chisnall                ++__base::size();
22117a984708SDavid Chisnall            }
22127a984708SDavid Chisnall            if (__n < __pos)
22137a984708SDavid Chisnall                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
22147a984708SDavid Chisnall            _VSTD::copy(__m, __l, __old_begin);
22157a984708SDavid Chisnall        }
22167a984708SDavid Chisnall    }
22177a984708SDavid Chisnall    else
22187a984708SDavid Chisnall    {   // insert by shifting things forward
22197a984708SDavid Chisnall        size_type __back_capacity = __back_spare();
22207a984708SDavid Chisnall        if (__n > __back_capacity)
22217a984708SDavid Chisnall            __add_back_capacity(__n - __back_capacity);
22227a984708SDavid Chisnall        // __n <= __back_capacity
22237a984708SDavid Chisnall        iterator __old_end = __base::end();
22247a984708SDavid Chisnall        iterator __i = __old_end;
22257a984708SDavid Chisnall        _BiIter __m = __l;
22267a984708SDavid Chisnall        size_type __de = __base::size() - __pos;
22277a984708SDavid Chisnall        if (__n > __de)
22287a984708SDavid Chisnall        {
22297a984708SDavid Chisnall            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
2230d72607e9SDimitry Andric            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())
22317a984708SDavid Chisnall                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
22327a984708SDavid Chisnall            __n = __de;
22337a984708SDavid Chisnall        }
22347a984708SDavid Chisnall        if (__n > 0)
22357a984708SDavid Chisnall        {
22367a984708SDavid Chisnall            iterator __oen = __old_end - __n;
22377a984708SDavid Chisnall            for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
22387a984708SDavid Chisnall                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
22397a984708SDavid Chisnall            if (__n < __de)
22407a984708SDavid Chisnall                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
22417a984708SDavid Chisnall            _VSTD::copy_backward(__f, __m, __old_end);
22427a984708SDavid Chisnall        }
22437a984708SDavid Chisnall    }
22447a984708SDavid Chisnall    return __base::begin() + __pos;
22457a984708SDavid Chisnall}
22467a984708SDavid Chisnall
22477a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
22487a984708SDavid Chisnalltemplate <class _InpIter>
22497a984708SDavid Chisnallvoid
22507a984708SDavid Chisnalldeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
22517a984708SDavid Chisnall                                 typename enable_if<__is_input_iterator<_InpIter>::value &&
22527a984708SDavid Chisnall                                                   !__is_forward_iterator<_InpIter>::value>::type*)
22537a984708SDavid Chisnall{
22547a984708SDavid Chisnall    for (; __f != __l; ++__f)
2255d4419f6fSDimitry Andric#ifdef _LIBCPP_CXX03_LANG
22567a984708SDavid Chisnall        push_back(*__f);
2257d4419f6fSDimitry Andric#else
2258d4419f6fSDimitry Andric        emplace_back(*__f);
2259d4419f6fSDimitry Andric#endif
22607a984708SDavid Chisnall}
22617a984708SDavid Chisnall
22627a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
22637a984708SDavid Chisnalltemplate <class _ForIter>
22647a984708SDavid Chisnallvoid
22657a984708SDavid Chisnalldeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
22667a984708SDavid Chisnall                                 typename enable_if<__is_forward_iterator<_ForIter>::value>::type*)
22677a984708SDavid Chisnall{
22687a984708SDavid Chisnall    size_type __n = _VSTD::distance(__f, __l);
22697a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
22707a984708SDavid Chisnall    size_type __back_capacity = __back_spare();
22717a984708SDavid Chisnall    if (__n > __back_capacity)
22727a984708SDavid Chisnall        __add_back_capacity(__n - __back_capacity);
22737a984708SDavid Chisnall    // __n <= __back_capacity
2274d72607e9SDimitry Andric    for (iterator __i = __base::end(); __f != __l; ++__i, (void) ++__f, ++__base::size())
22757a984708SDavid Chisnall        __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f);
22767a984708SDavid Chisnall}
22777a984708SDavid Chisnall
22787a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
22797a984708SDavid Chisnallvoid
22807a984708SDavid Chisnalldeque<_Tp, _Allocator>::__append(size_type __n)
22817a984708SDavid Chisnall{
22827a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
22837a984708SDavid Chisnall    size_type __back_capacity = __back_spare();
22847a984708SDavid Chisnall    if (__n > __back_capacity)
22857a984708SDavid Chisnall        __add_back_capacity(__n - __back_capacity);
22867a984708SDavid Chisnall    // __n <= __back_capacity
22877a984708SDavid Chisnall    for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
22887a984708SDavid Chisnall        __alloc_traits::construct(__a, _VSTD::addressof(*__i));
22897a984708SDavid Chisnall}
22907a984708SDavid Chisnall
22917a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
22927a984708SDavid Chisnallvoid
22937a984708SDavid Chisnalldeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
22947a984708SDavid Chisnall{
22957a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
22967a984708SDavid Chisnall    size_type __back_capacity = __back_spare();
22977a984708SDavid Chisnall    if (__n > __back_capacity)
22987a984708SDavid Chisnall        __add_back_capacity(__n - __back_capacity);
22997a984708SDavid Chisnall    // __n <= __back_capacity
23007a984708SDavid Chisnall    for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
23017a984708SDavid Chisnall        __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
23027a984708SDavid Chisnall}
23037a984708SDavid Chisnall
23047a984708SDavid Chisnall// Create front capacity for one block of elements.
23057a984708SDavid Chisnall// Strong guarantee.  Either do it or don't touch anything.
23067a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
23077a984708SDavid Chisnallvoid
23087a984708SDavid Chisnalldeque<_Tp, _Allocator>::__add_front_capacity()
23097a984708SDavid Chisnall{
23107a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
23117a984708SDavid Chisnall    if (__back_spare() >= __base::__block_size)
23127a984708SDavid Chisnall    {
23137a984708SDavid Chisnall        __base::__start_ += __base::__block_size;
23147a984708SDavid Chisnall        pointer __pt = __base::__map_.back();
23157a984708SDavid Chisnall        __base::__map_.pop_back();
23167a984708SDavid Chisnall        __base::__map_.push_front(__pt);
23177a984708SDavid Chisnall    }
23187a984708SDavid Chisnall    // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
23197a984708SDavid Chisnall    else if (__base::__map_.size() < __base::__map_.capacity())
23207a984708SDavid Chisnall    {   // we can put the new buffer into the map, but don't shift things around
23217a984708SDavid Chisnall        // until all buffers are allocated.  If we throw, we don't need to fix
23227a984708SDavid Chisnall        // anything up (any added buffers are undetectible)
23237a984708SDavid Chisnall        if (__base::__map_.__front_spare() > 0)
23247a984708SDavid Chisnall            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
23257a984708SDavid Chisnall        else
23267a984708SDavid Chisnall        {
23277a984708SDavid Chisnall            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
23287a984708SDavid Chisnall            // Done allocating, reorder capacity
23297a984708SDavid Chisnall            pointer __pt = __base::__map_.back();
23307a984708SDavid Chisnall            __base::__map_.pop_back();
23317a984708SDavid Chisnall            __base::__map_.push_front(__pt);
23327a984708SDavid Chisnall        }
23337a984708SDavid Chisnall        __base::__start_ = __base::__map_.size() == 1 ?
23347a984708SDavid Chisnall                               __base::__block_size / 2 :
23357a984708SDavid Chisnall                               __base::__start_ + __base::__block_size;
23367a984708SDavid Chisnall    }
23377a984708SDavid Chisnall    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
23387a984708SDavid Chisnall    else
23397a984708SDavid Chisnall    {
23407a984708SDavid Chisnall        __split_buffer<pointer, typename __base::__pointer_allocator&>
23417a984708SDavid Chisnall            __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
23427a984708SDavid Chisnall                  0, __base::__map_.__alloc());
2343854fa44bSDimitry Andric
2344854fa44bSDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
2345854fa44bSDimitry Andric        unique_ptr<pointer, _Dp> __hold(
2346854fa44bSDimitry Andric            __alloc_traits::allocate(__a, __base::__block_size),
2347854fa44bSDimitry Andric                _Dp(__a, __base::__block_size));
2348854fa44bSDimitry Andric        __buf.push_back(__hold.get());
2349854fa44bSDimitry Andric        __hold.release();
2350854fa44bSDimitry Andric
23517a984708SDavid Chisnall        for (typename __base::__map_pointer __i = __base::__map_.begin();
23527a984708SDavid Chisnall                __i != __base::__map_.end(); ++__i)
23537a984708SDavid Chisnall            __buf.push_back(*__i);
23547a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
23557a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
23567a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
23577a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
23587a984708SDavid Chisnall        __base::__start_ = __base::__map_.size() == 1 ?
23597a984708SDavid Chisnall                               __base::__block_size / 2 :
23607a984708SDavid Chisnall                               __base::__start_ + __base::__block_size;
23617a984708SDavid Chisnall    }
23627a984708SDavid Chisnall}
23637a984708SDavid Chisnall
23647a984708SDavid Chisnall// Create front capacity for __n elements.
23657a984708SDavid Chisnall// Strong guarantee.  Either do it or don't touch anything.
23667a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
23677a984708SDavid Chisnallvoid
23687a984708SDavid Chisnalldeque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
23697a984708SDavid Chisnall{
23707a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
23717a984708SDavid Chisnall    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
23727a984708SDavid Chisnall    // Number of unused blocks at back:
23737a984708SDavid Chisnall    size_type __back_capacity = __back_spare() / __base::__block_size;
23747a984708SDavid Chisnall    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need
23757a984708SDavid Chisnall    __nb -= __back_capacity;  // number of blocks need to allocate
23767a984708SDavid Chisnall    // If __nb == 0, then we have sufficient capacity.
23777a984708SDavid Chisnall    if (__nb == 0)
23787a984708SDavid Chisnall    {
23797a984708SDavid Chisnall        __base::__start_ += __base::__block_size * __back_capacity;
23807a984708SDavid Chisnall        for (; __back_capacity > 0; --__back_capacity)
23817a984708SDavid Chisnall        {
23827a984708SDavid Chisnall            pointer __pt = __base::__map_.back();
23837a984708SDavid Chisnall            __base::__map_.pop_back();
23847a984708SDavid Chisnall            __base::__map_.push_front(__pt);
23857a984708SDavid Chisnall        }
23867a984708SDavid Chisnall    }
23877a984708SDavid Chisnall    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
23887a984708SDavid Chisnall    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
23897a984708SDavid Chisnall    {   // we can put the new buffers into the map, but don't shift things around
23907a984708SDavid Chisnall        // until all buffers are allocated.  If we throw, we don't need to fix
23917a984708SDavid Chisnall        // anything up (any added buffers are undetectible)
23927a984708SDavid Chisnall        for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
23937a984708SDavid Chisnall        {
23947a984708SDavid Chisnall            if (__base::__map_.__front_spare() == 0)
23957a984708SDavid Chisnall                break;
23967a984708SDavid Chisnall            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
23977a984708SDavid Chisnall        }
23987a984708SDavid Chisnall        for (; __nb > 0; --__nb, ++__back_capacity)
23997a984708SDavid Chisnall            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
24007a984708SDavid Chisnall        // Done allocating, reorder capacity
24017a984708SDavid Chisnall        __base::__start_ += __back_capacity * __base::__block_size;
24027a984708SDavid Chisnall        for (; __back_capacity > 0; --__back_capacity)
24037a984708SDavid Chisnall        {
24047a984708SDavid Chisnall            pointer __pt = __base::__map_.back();
24057a984708SDavid Chisnall            __base::__map_.pop_back();
24067a984708SDavid Chisnall            __base::__map_.push_front(__pt);
24077a984708SDavid Chisnall        }
24087a984708SDavid Chisnall    }
24097a984708SDavid Chisnall    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
24107a984708SDavid Chisnall    else
24117a984708SDavid Chisnall    {
24127a984708SDavid Chisnall        size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
24137a984708SDavid Chisnall        __split_buffer<pointer, typename __base::__pointer_allocator&>
24147a984708SDavid Chisnall            __buf(max<size_type>(2* __base::__map_.capacity(),
24157a984708SDavid Chisnall                                 __nb + __base::__map_.size()),
24167a984708SDavid Chisnall                  0, __base::__map_.__alloc());
24177a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
24187a984708SDavid Chisnall        try
24197a984708SDavid Chisnall        {
24207a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
24217a984708SDavid Chisnall            for (; __nb > 0; --__nb)
24227a984708SDavid Chisnall                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
24237a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
24247a984708SDavid Chisnall        }
24257a984708SDavid Chisnall        catch (...)
24267a984708SDavid Chisnall        {
24277a984708SDavid Chisnall            for (typename __base::__map_pointer __i = __buf.begin();
24287a984708SDavid Chisnall                    __i != __buf.end(); ++__i)
24297a984708SDavid Chisnall                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
24307a984708SDavid Chisnall            throw;
24317a984708SDavid Chisnall        }
24327a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
24337a984708SDavid Chisnall        for (; __back_capacity > 0; --__back_capacity)
24347a984708SDavid Chisnall        {
24357a984708SDavid Chisnall            __buf.push_back(__base::__map_.back());
24367a984708SDavid Chisnall            __base::__map_.pop_back();
24377a984708SDavid Chisnall        }
24387a984708SDavid Chisnall        for (typename __base::__map_pointer __i = __base::__map_.begin();
24397a984708SDavid Chisnall                __i != __base::__map_.end(); ++__i)
24407a984708SDavid Chisnall            __buf.push_back(*__i);
24417a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
24427a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
24437a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
24447a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
24457a984708SDavid Chisnall        __base::__start_ += __ds;
24467a984708SDavid Chisnall    }
24477a984708SDavid Chisnall}
24487a984708SDavid Chisnall
24497a984708SDavid Chisnall// Create back capacity for one block of elements.
24507a984708SDavid Chisnall// Strong guarantee.  Either do it or don't touch anything.
24517a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
24527a984708SDavid Chisnallvoid
24537a984708SDavid Chisnalldeque<_Tp, _Allocator>::__add_back_capacity()
24547a984708SDavid Chisnall{
24557a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
24567a984708SDavid Chisnall    if (__front_spare() >= __base::__block_size)
24577a984708SDavid Chisnall    {
24587a984708SDavid Chisnall        __base::__start_ -= __base::__block_size;
24597a984708SDavid Chisnall        pointer __pt = __base::__map_.front();
24607a984708SDavid Chisnall        __base::__map_.pop_front();
24617a984708SDavid Chisnall        __base::__map_.push_back(__pt);
24627a984708SDavid Chisnall    }
24637a984708SDavid Chisnall    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
24647a984708SDavid Chisnall    else if (__base::__map_.size() < __base::__map_.capacity())
24657a984708SDavid Chisnall    {   // we can put the new buffer into the map, but don't shift things around
24667a984708SDavid Chisnall        // until it is allocated.  If we throw, we don't need to fix
24677a984708SDavid Chisnall        // anything up (any added buffers are undetectible)
24687a984708SDavid Chisnall        if (__base::__map_.__back_spare() != 0)
24697a984708SDavid Chisnall            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
24707a984708SDavid Chisnall        else
24717a984708SDavid Chisnall        {
24727a984708SDavid Chisnall            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
24737a984708SDavid Chisnall            // Done allocating, reorder capacity
24747a984708SDavid Chisnall            pointer __pt = __base::__map_.front();
24757a984708SDavid Chisnall            __base::__map_.pop_front();
24767a984708SDavid Chisnall            __base::__map_.push_back(__pt);
24777a984708SDavid Chisnall        }
24787a984708SDavid Chisnall    }
24797a984708SDavid Chisnall    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
24807a984708SDavid Chisnall    else
24817a984708SDavid Chisnall    {
24827a984708SDavid Chisnall        __split_buffer<pointer, typename __base::__pointer_allocator&>
24837a984708SDavid Chisnall            __buf(max<size_type>(2* __base::__map_.capacity(), 1),
24847a984708SDavid Chisnall                  __base::__map_.size(),
24857a984708SDavid Chisnall                  __base::__map_.__alloc());
2486854fa44bSDimitry Andric
2487854fa44bSDimitry Andric        typedef __allocator_destructor<_Allocator> _Dp;
2488854fa44bSDimitry Andric        unique_ptr<pointer, _Dp> __hold(
2489854fa44bSDimitry Andric            __alloc_traits::allocate(__a, __base::__block_size),
2490854fa44bSDimitry Andric                _Dp(__a, __base::__block_size));
2491854fa44bSDimitry Andric        __buf.push_back(__hold.get());
2492854fa44bSDimitry Andric        __hold.release();
2493854fa44bSDimitry Andric
24947a984708SDavid Chisnall        for (typename __base::__map_pointer __i = __base::__map_.end();
24957a984708SDavid Chisnall                __i != __base::__map_.begin();)
24967a984708SDavid Chisnall            __buf.push_front(*--__i);
24977a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
24987a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
24997a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
25007a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
25017a984708SDavid Chisnall    }
25027a984708SDavid Chisnall}
25037a984708SDavid Chisnall
25047a984708SDavid Chisnall// Create back capacity for __n elements.
25057a984708SDavid Chisnall// Strong guarantee.  Either do it or don't touch anything.
25067a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
25077a984708SDavid Chisnallvoid
25087a984708SDavid Chisnalldeque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
25097a984708SDavid Chisnall{
25107a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
25117a984708SDavid Chisnall    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
25127a984708SDavid Chisnall    // Number of unused blocks at front:
25137a984708SDavid Chisnall    size_type __front_capacity = __front_spare() / __base::__block_size;
25147a984708SDavid Chisnall    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need
25157a984708SDavid Chisnall    __nb -= __front_capacity;  // number of blocks need to allocate
25167a984708SDavid Chisnall    // If __nb == 0, then we have sufficient capacity.
25177a984708SDavid Chisnall    if (__nb == 0)
25187a984708SDavid Chisnall    {
25197a984708SDavid Chisnall        __base::__start_ -= __base::__block_size * __front_capacity;
25207a984708SDavid Chisnall        for (; __front_capacity > 0; --__front_capacity)
25217a984708SDavid Chisnall        {
25227a984708SDavid Chisnall            pointer __pt = __base::__map_.front();
25237a984708SDavid Chisnall            __base::__map_.pop_front();
25247a984708SDavid Chisnall            __base::__map_.push_back(__pt);
25257a984708SDavid Chisnall        }
25267a984708SDavid Chisnall    }
25277a984708SDavid Chisnall    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
25287a984708SDavid Chisnall    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
25297a984708SDavid Chisnall    {   // we can put the new buffers into the map, but don't shift things around
25307a984708SDavid Chisnall        // until all buffers are allocated.  If we throw, we don't need to fix
25317a984708SDavid Chisnall        // anything up (any added buffers are undetectible)
25327a984708SDavid Chisnall        for (; __nb > 0; --__nb)
25337a984708SDavid Chisnall        {
25347a984708SDavid Chisnall            if (__base::__map_.__back_spare() == 0)
25357a984708SDavid Chisnall                break;
25367a984708SDavid Chisnall            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
25377a984708SDavid Chisnall        }
25387a984708SDavid Chisnall        for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
25397a984708SDavid Chisnall                                 __base::__block_size - (__base::__map_.size() == 1))
25407a984708SDavid Chisnall            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
25417a984708SDavid Chisnall        // Done allocating, reorder capacity
25427a984708SDavid Chisnall        __base::__start_ -= __base::__block_size * __front_capacity;
25437a984708SDavid Chisnall        for (; __front_capacity > 0; --__front_capacity)
25447a984708SDavid Chisnall        {
25457a984708SDavid Chisnall            pointer __pt = __base::__map_.front();
25467a984708SDavid Chisnall            __base::__map_.pop_front();
25477a984708SDavid Chisnall            __base::__map_.push_back(__pt);
25487a984708SDavid Chisnall        }
25497a984708SDavid Chisnall    }
25507a984708SDavid Chisnall    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
25517a984708SDavid Chisnall    else
25527a984708SDavid Chisnall    {
25537a984708SDavid Chisnall        size_type __ds = __front_capacity * __base::__block_size;
25547a984708SDavid Chisnall        __split_buffer<pointer, typename __base::__pointer_allocator&>
25557a984708SDavid Chisnall            __buf(max<size_type>(2* __base::__map_.capacity(),
25567a984708SDavid Chisnall                                 __nb + __base::__map_.size()),
25577a984708SDavid Chisnall                  __base::__map_.size() - __front_capacity,
25587a984708SDavid Chisnall                  __base::__map_.__alloc());
25597a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
25607a984708SDavid Chisnall        try
25617a984708SDavid Chisnall        {
25627a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
25637a984708SDavid Chisnall            for (; __nb > 0; --__nb)
25647a984708SDavid Chisnall                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
25657a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
25667a984708SDavid Chisnall        }
25677a984708SDavid Chisnall        catch (...)
25687a984708SDavid Chisnall        {
25697a984708SDavid Chisnall            for (typename __base::__map_pointer __i = __buf.begin();
25707a984708SDavid Chisnall                    __i != __buf.end(); ++__i)
25717a984708SDavid Chisnall                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
25727a984708SDavid Chisnall            throw;
25737a984708SDavid Chisnall        }
25747a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
25757a984708SDavid Chisnall        for (; __front_capacity > 0; --__front_capacity)
25767a984708SDavid Chisnall        {
25777a984708SDavid Chisnall            __buf.push_back(__base::__map_.front());
25787a984708SDavid Chisnall            __base::__map_.pop_front();
25797a984708SDavid Chisnall        }
25807a984708SDavid Chisnall        for (typename __base::__map_pointer __i = __base::__map_.end();
25817a984708SDavid Chisnall                __i != __base::__map_.begin();)
25827a984708SDavid Chisnall            __buf.push_front(*--__i);
25837a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
25847a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
25857a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
25867a984708SDavid Chisnall        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
25877a984708SDavid Chisnall        __base::__start_ -= __ds;
25887a984708SDavid Chisnall    }
25897a984708SDavid Chisnall}
25907a984708SDavid Chisnall
25917a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
25927a984708SDavid Chisnallvoid
25937a984708SDavid Chisnalldeque<_Tp, _Allocator>::pop_front()
25947a984708SDavid Chisnall{
25957a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
25964bab9fd9SDavid Chisnall    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
25977a984708SDavid Chisnall                                                    __base::__start_ / __base::__block_size) +
25984bab9fd9SDavid Chisnall                                                    __base::__start_ % __base::__block_size));
25997a984708SDavid Chisnall    --__base::size();
26007a984708SDavid Chisnall    if (++__base::__start_ >= 2 * __base::__block_size)
26017a984708SDavid Chisnall    {
26027a984708SDavid Chisnall        __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
26037a984708SDavid Chisnall        __base::__map_.pop_front();
26047a984708SDavid Chisnall        __base::__start_ -= __base::__block_size;
26057a984708SDavid Chisnall    }
26067a984708SDavid Chisnall}
26077a984708SDavid Chisnall
26087a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
26097a984708SDavid Chisnallvoid
26107a984708SDavid Chisnalldeque<_Tp, _Allocator>::pop_back()
26117a984708SDavid Chisnall{
2612*b5893f02SDimitry Andric    _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque");
26137a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
26147a984708SDavid Chisnall    size_type __p = __base::size() + __base::__start_ - 1;
26154bab9fd9SDavid Chisnall    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
26167a984708SDavid Chisnall                                                    __p / __base::__block_size) +
26174bab9fd9SDavid Chisnall                                                    __p % __base::__block_size));
26187a984708SDavid Chisnall    --__base::size();
26197a984708SDavid Chisnall    if (__back_spare() >= 2 * __base::__block_size)
26207a984708SDavid Chisnall    {
26217a984708SDavid Chisnall        __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
26227a984708SDavid Chisnall        __base::__map_.pop_back();
26237a984708SDavid Chisnall    }
26247a984708SDavid Chisnall}
26257a984708SDavid Chisnall
26267a984708SDavid Chisnall// move assign [__f, __l) to [__r, __r + (__l-__f)).
26277a984708SDavid Chisnall// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
26287a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
26297a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
26307a984708SDavid Chisnalldeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
26317a984708SDavid Chisnall                                         const_pointer& __vt)
26327a984708SDavid Chisnall{
26337a984708SDavid Chisnall    // as if
26347a984708SDavid Chisnall    //   for (; __f != __l; ++__f, ++__r)
26357a984708SDavid Chisnall    //       *__r = _VSTD::move(*__f);
26367a984708SDavid Chisnall    difference_type __n = __l - __f;
26377a984708SDavid Chisnall    while (__n > 0)
26387a984708SDavid Chisnall    {
26397a984708SDavid Chisnall        pointer __fb = __f.__ptr_;
26407a984708SDavid Chisnall        pointer __fe = *__f.__m_iter_ + __base::__block_size;
26417a984708SDavid Chisnall        difference_type __bs = __fe - __fb;
26427a984708SDavid Chisnall        if (__bs > __n)
26437a984708SDavid Chisnall        {
26447a984708SDavid Chisnall            __bs = __n;
26457a984708SDavid Chisnall            __fe = __fb + __bs;
26467a984708SDavid Chisnall        }
26477a984708SDavid Chisnall        if (__fb <= __vt && __vt < __fe)
26484bab9fd9SDavid Chisnall            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
26497a984708SDavid Chisnall        __r = _VSTD::move(__fb, __fe, __r);
26507a984708SDavid Chisnall        __n -= __bs;
26517a984708SDavid Chisnall        __f += __bs;
26527a984708SDavid Chisnall    }
26537a984708SDavid Chisnall    return __r;
26547a984708SDavid Chisnall}
26557a984708SDavid Chisnall
26567a984708SDavid Chisnall// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
26577a984708SDavid Chisnall// If __vt points into [__f, __l), then add (__r - __l) to __vt.
26587a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
26597a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
26607a984708SDavid Chisnalldeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
26617a984708SDavid Chisnall                                                  const_pointer& __vt)
26627a984708SDavid Chisnall{
26637a984708SDavid Chisnall    // as if
26647a984708SDavid Chisnall    //   while (__f != __l)
26657a984708SDavid Chisnall    //       *--__r = _VSTD::move(*--__l);
26667a984708SDavid Chisnall    difference_type __n = __l - __f;
26677a984708SDavid Chisnall    while (__n > 0)
26687a984708SDavid Chisnall    {
26697a984708SDavid Chisnall        --__l;
26707a984708SDavid Chisnall        pointer __lb = *__l.__m_iter_;
26717a984708SDavid Chisnall        pointer __le = __l.__ptr_ + 1;
26727a984708SDavid Chisnall        difference_type __bs = __le - __lb;
26737a984708SDavid Chisnall        if (__bs > __n)
26747a984708SDavid Chisnall        {
26757a984708SDavid Chisnall            __bs = __n;
26767a984708SDavid Chisnall            __lb = __le - __bs;
26777a984708SDavid Chisnall        }
26787a984708SDavid Chisnall        if (__lb <= __vt && __vt < __le)
26794bab9fd9SDavid Chisnall            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
26807a984708SDavid Chisnall        __r = _VSTD::move_backward(__lb, __le, __r);
26817a984708SDavid Chisnall        __n -= __bs;
26827a984708SDavid Chisnall        __l -= __bs - 1;
26837a984708SDavid Chisnall    }
26847a984708SDavid Chisnall    return __r;
26857a984708SDavid Chisnall}
26867a984708SDavid Chisnall
26877a984708SDavid Chisnall// move construct [__f, __l) to [__r, __r + (__l-__f)).
26887a984708SDavid Chisnall// If __vt points into [__f, __l), then add (__r - __f) to __vt.
26897a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
26907a984708SDavid Chisnallvoid
26917a984708SDavid Chisnalldeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
26927a984708SDavid Chisnall                                                   iterator __r, const_pointer& __vt)
26937a984708SDavid Chisnall{
26947a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
26957a984708SDavid Chisnall    // as if
26967a984708SDavid Chisnall    //   for (; __f != __l; ++__r, ++__f, ++__base::size())
26977a984708SDavid Chisnall    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
26987a984708SDavid Chisnall    difference_type __n = __l - __f;
26997a984708SDavid Chisnall    while (__n > 0)
27007a984708SDavid Chisnall    {
27017a984708SDavid Chisnall        pointer __fb = __f.__ptr_;
27027a984708SDavid Chisnall        pointer __fe = *__f.__m_iter_ + __base::__block_size;
27037a984708SDavid Chisnall        difference_type __bs = __fe - __fb;
27047a984708SDavid Chisnall        if (__bs > __n)
27057a984708SDavid Chisnall        {
27067a984708SDavid Chisnall            __bs = __n;
27077a984708SDavid Chisnall            __fe = __fb + __bs;
27087a984708SDavid Chisnall        }
27097a984708SDavid Chisnall        if (__fb <= __vt && __vt < __fe)
27104bab9fd9SDavid Chisnall            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
27117a984708SDavid Chisnall        for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
27127a984708SDavid Chisnall            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
27137a984708SDavid Chisnall        __n -= __bs;
27147a984708SDavid Chisnall        __f += __bs;
27157a984708SDavid Chisnall    }
27167a984708SDavid Chisnall}
27177a984708SDavid Chisnall
27187a984708SDavid Chisnall// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
27197a984708SDavid Chisnall// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
27207a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
27217a984708SDavid Chisnallvoid
27227a984708SDavid Chisnalldeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
27237a984708SDavid Chisnall                                                            iterator __r, const_pointer& __vt)
27247a984708SDavid Chisnall{
27257a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
27267a984708SDavid Chisnall    // as if
27277a984708SDavid Chisnall    //   for (iterator __j = __l; __j != __f;)
27287a984708SDavid Chisnall    //   {
27297a984708SDavid Chisnall    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
27307a984708SDavid Chisnall    //       --__base::__start_;
27317a984708SDavid Chisnall    //       ++__base::size();
27327a984708SDavid Chisnall    //   }
27337a984708SDavid Chisnall    difference_type __n = __l - __f;
27347a984708SDavid Chisnall    while (__n > 0)
27357a984708SDavid Chisnall    {
27367a984708SDavid Chisnall        --__l;
27377a984708SDavid Chisnall        pointer __lb = *__l.__m_iter_;
27387a984708SDavid Chisnall        pointer __le = __l.__ptr_ + 1;
27397a984708SDavid Chisnall        difference_type __bs = __le - __lb;
27407a984708SDavid Chisnall        if (__bs > __n)
27417a984708SDavid Chisnall        {
27427a984708SDavid Chisnall            __bs = __n;
27437a984708SDavid Chisnall            __lb = __le - __bs;
27447a984708SDavid Chisnall        }
27457a984708SDavid Chisnall        if (__lb <= __vt && __vt < __le)
27464bab9fd9SDavid Chisnall            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
27477a984708SDavid Chisnall        while (__le != __lb)
27487a984708SDavid Chisnall        {
27497a984708SDavid Chisnall            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
27507a984708SDavid Chisnall            --__base::__start_;
27517a984708SDavid Chisnall            ++__base::size();
27527a984708SDavid Chisnall        }
27537a984708SDavid Chisnall        __n -= __bs;
27547a984708SDavid Chisnall        __l -= __bs - 1;
27557a984708SDavid Chisnall    }
27567a984708SDavid Chisnall}
27577a984708SDavid Chisnall
27587a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
27597a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
27607a984708SDavid Chisnalldeque<_Tp, _Allocator>::erase(const_iterator __f)
27617a984708SDavid Chisnall{
27627a984708SDavid Chisnall    iterator __b = __base::begin();
27637a984708SDavid Chisnall    difference_type __pos = __f - __b;
27647a984708SDavid Chisnall    iterator __p = __b + __pos;
27657a984708SDavid Chisnall    allocator_type& __a = __base::__alloc();
2766aed8d94eSDimitry Andric    if (static_cast<size_t>(__pos) <= (__base::size() - 1) / 2)
27677a984708SDavid Chisnall    {   // erase from front
27687a984708SDavid Chisnall        _VSTD::move_backward(__b, __p, _VSTD::next(__p));
27697a984708SDavid Chisnall        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
27707a984708SDavid Chisnall        --__base::size();
27717a984708SDavid Chisnall        ++__base::__start_;
27727a984708SDavid Chisnall        if (__front_spare() >= 2 * __base::__block_size)
27737a984708SDavid Chisnall        {
27747a984708SDavid Chisnall            __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
27757a984708SDavid Chisnall            __base::__map_.pop_front();
27767a984708SDavid Chisnall            __base::__start_ -= __base::__block_size;
27777a984708SDavid Chisnall        }
27787a984708SDavid Chisnall    }
27797a984708SDavid Chisnall    else
27807a984708SDavid Chisnall    {   // erase from back
27817a984708SDavid Chisnall        iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);
27827a984708SDavid Chisnall        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
27837a984708SDavid Chisnall        --__base::size();
27847a984708SDavid Chisnall        if (__back_spare() >= 2 * __base::__block_size)
27857a984708SDavid Chisnall        {
27867a984708SDavid Chisnall            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
27877a984708SDavid Chisnall            __base::__map_.pop_back();
27887a984708SDavid Chisnall        }
27897a984708SDavid Chisnall    }
27907a984708SDavid Chisnall    return __base::begin() + __pos;
27917a984708SDavid Chisnall}
27927a984708SDavid Chisnall
27937a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
27947a984708SDavid Chisnalltypename deque<_Tp, _Allocator>::iterator
27957a984708SDavid Chisnalldeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
27967a984708SDavid Chisnall{
27977a984708SDavid Chisnall    difference_type __n = __l - __f;
27987a984708SDavid Chisnall    iterator __b = __base::begin();
27997a984708SDavid Chisnall    difference_type __pos = __f - __b;
28007a984708SDavid Chisnall    iterator __p = __b + __pos;
28017a984708SDavid Chisnall    if (__n > 0)
28027a984708SDavid Chisnall    {
28037a984708SDavid Chisnall        allocator_type& __a = __base::__alloc();
2804aed8d94eSDimitry Andric        if (static_cast<size_t>(__pos) <= (__base::size() - __n) / 2)
28057a984708SDavid Chisnall        {   // erase from front
28067a984708SDavid Chisnall            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
28077a984708SDavid Chisnall            for (; __b != __i; ++__b)
28087a984708SDavid Chisnall                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
28097a984708SDavid Chisnall            __base::size() -= __n;
28107a984708SDavid Chisnall            __base::__start_ += __n;
28117a984708SDavid Chisnall            while (__front_spare() >= 2 * __base::__block_size)
28127a984708SDavid Chisnall            {
28137a984708SDavid Chisnall                __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
28147a984708SDavid Chisnall                __base::__map_.pop_front();
28157a984708SDavid Chisnall                __base::__start_ -= __base::__block_size;
28167a984708SDavid Chisnall            }
28177a984708SDavid Chisnall        }
28187a984708SDavid Chisnall        else
28197a984708SDavid Chisnall        {   // erase from back
28207a984708SDavid Chisnall            iterator __i = _VSTD::move(__p + __n, __base::end(), __p);
28217a984708SDavid Chisnall            for (iterator __e = __base::end(); __i != __e; ++__i)
28227a984708SDavid Chisnall                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
28237a984708SDavid Chisnall            __base::size() -= __n;
28247a984708SDavid Chisnall            while (__back_spare() >= 2 * __base::__block_size)
28257a984708SDavid Chisnall            {
28267a984708SDavid Chisnall                __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
28277a984708SDavid Chisnall                __base::__map_.pop_back();
28287a984708SDavid Chisnall            }
28297a984708SDavid Chisnall        }
28307a984708SDavid Chisnall    }
28317a984708SDavid Chisnall    return __base::begin() + __pos;
28327a984708SDavid Chisnall}
28337a984708SDavid Chisnall
28347a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
28357a984708SDavid Chisnallvoid
28367a984708SDavid Chisnalldeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
28377a984708SDavid Chisnall{
28387a984708SDavid Chisnall    iterator __e = __base::end();
28397a984708SDavid Chisnall    difference_type __n = __e - __f;
28407a984708SDavid Chisnall    if (__n > 0)
28417a984708SDavid Chisnall    {
28427a984708SDavid Chisnall        allocator_type& __a = __base::__alloc();
28437a984708SDavid Chisnall        iterator __b = __base::begin();
28447a984708SDavid Chisnall        difference_type __pos = __f - __b;
28457a984708SDavid Chisnall        for (iterator __p = __b + __pos; __p != __e; ++__p)
28467a984708SDavid Chisnall            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
28477a984708SDavid Chisnall        __base::size() -= __n;
28487a984708SDavid Chisnall        while (__back_spare() >= 2 * __base::__block_size)
28497a984708SDavid Chisnall        {
28507a984708SDavid Chisnall            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
28517a984708SDavid Chisnall            __base::__map_.pop_back();
28527a984708SDavid Chisnall        }
28537a984708SDavid Chisnall    }
28547a984708SDavid Chisnall}
28557a984708SDavid Chisnall
28567a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
28579729cf09SDimitry Andricinline
28587a984708SDavid Chisnallvoid
28597a984708SDavid Chisnalldeque<_Tp, _Allocator>::swap(deque& __c)
2860854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
2861854fa44bSDimitry Andric        _NOEXCEPT
2862854fa44bSDimitry Andric#else
28637a984708SDavid Chisnall        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
28647a984708SDavid Chisnall                    __is_nothrow_swappable<allocator_type>::value)
2865854fa44bSDimitry Andric#endif
28667a984708SDavid Chisnall{
28677a984708SDavid Chisnall    __base::swap(__c);
28687a984708SDavid Chisnall}
28697a984708SDavid Chisnall
28707a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
28719729cf09SDimitry Andricinline
28727a984708SDavid Chisnallvoid
28737a984708SDavid Chisnalldeque<_Tp, _Allocator>::clear() _NOEXCEPT
28747a984708SDavid Chisnall{
28757a984708SDavid Chisnall    __base::clear();
28767a984708SDavid Chisnall}
28777a984708SDavid Chisnall
28787a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
28794f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28807a984708SDavid Chisnallbool
28817a984708SDavid Chisnalloperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28827a984708SDavid Chisnall{
28837a984708SDavid Chisnall    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
28847a984708SDavid Chisnall    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
28857a984708SDavid Chisnall}
28867a984708SDavid Chisnall
28877a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
28884f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28897a984708SDavid Chisnallbool
28907a984708SDavid Chisnalloperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28917a984708SDavid Chisnall{
28927a984708SDavid Chisnall    return !(__x == __y);
28937a984708SDavid Chisnall}
28947a984708SDavid Chisnall
28957a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
28964f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28977a984708SDavid Chisnallbool
28987a984708SDavid Chisnalloperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
28997a984708SDavid Chisnall{
29007a984708SDavid Chisnall    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
29017a984708SDavid Chisnall}
29027a984708SDavid Chisnall
29037a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
29044f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29057a984708SDavid Chisnallbool
29067a984708SDavid Chisnalloperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29077a984708SDavid Chisnall{
29087a984708SDavid Chisnall    return __y < __x;
29097a984708SDavid Chisnall}
29107a984708SDavid Chisnall
29117a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
29124f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29137a984708SDavid Chisnallbool
29147a984708SDavid Chisnalloperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29157a984708SDavid Chisnall{
29167a984708SDavid Chisnall    return !(__x < __y);
29177a984708SDavid Chisnall}
29187a984708SDavid Chisnall
29197a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
29204f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29217a984708SDavid Chisnallbool
29227a984708SDavid Chisnalloperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
29237a984708SDavid Chisnall{
29247a984708SDavid Chisnall    return !(__y < __x);
29257a984708SDavid Chisnall}
29267a984708SDavid Chisnall
29277a984708SDavid Chisnalltemplate <class _Tp, class _Allocator>
29284f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29297a984708SDavid Chisnallvoid
29307a984708SDavid Chisnallswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
29317a984708SDavid Chisnall    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
29327a984708SDavid Chisnall{
29337a984708SDavid Chisnall    __x.swap(__y);
29347a984708SDavid Chisnall}
29357a984708SDavid Chisnall
2936*b5893f02SDimitry Andric#if _LIBCPP_STD_VER > 17
2937*b5893f02SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up>
2938*b5893f02SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2939*b5893f02SDimitry Andricvoid erase(deque<_Tp, _Allocator>& __c, const _Up& __v)
2940*b5893f02SDimitry Andric{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
2941*b5893f02SDimitry Andric
2942*b5893f02SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate>
2943*b5893f02SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2944*b5893f02SDimitry Andricvoid erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred)
2945*b5893f02SDimitry Andric{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
2946*b5893f02SDimitry Andric#endif
2947*b5893f02SDimitry Andric
2948*b5893f02SDimitry Andric
29497a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
29507a984708SDavid Chisnall
2951f9448bf3SDimitry Andric_LIBCPP_POP_MACROS
2952f9448bf3SDimitry Andric
29537a984708SDavid Chisnall#endif  // _LIBCPP_DEQUE
2954