1// -*- C++ -*-
2//===-------------------------- iterator ----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ITERATOR
11#define _LIBCPP_ITERATOR
12
13/*
14    iterator synopsis
15
16#include <concepts>
17
18namespace std
19{
20template<class> struct incrementable_traits;       // since C++20
21template<class T>
22  using iter_difference_t = see below;             // since C++20
23
24template<class> struct indirectly_readable_traits; // since C++20
25template<class T>
26  using iter_value_t = see below;                  // since C++20
27
28template<class Iterator>
29struct iterator_traits;
30
31template<class T>
32  requires is_object_v<T>                    // since C++20
33struct iterator_traits<T*>;
34
35template<dereferenceable T>
36  using iter_reference_t = decltype(*declval<T&>());
37
38namespace ranges::inline unspecified {
39    inline constexpr unspecified iter_move = unspecified; // since C++20, nodiscard as an extension
40}}
41
42template<dereferenceable T>
43  requires ...
44using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<T&>())); // since C++20
45
46// [iterator.concepts], iterator concepts
47// [iterator.concept.readable], concept indirectly_readable
48template<class In>
49  concept indirectly_readable = see below;                // since C++20
50
51// [iterator.concept.writable], concept indirectly_writable
52template<class Out, class T>
53  concept indirectly_writable = see below;                // since C++20
54
55// [iterator.concept.winc], concept weakly_incrementable
56template<class I>
57  concept weakly_incrementable = see below;                // since C++20
58
59// [iterator.concept.inc], concept incrementable
60template<class I>
61  concept incrementable = see below;                       // since C++20
62
63// [iterator.concept.iterator], concept input_or_output_iterator
64  template<class I>
65    concept input_or_output_iterator = see below;          // since C++20
66
67// [iterator.concept.sentinel], concept sentinel_for
68template<class S, class I>
69  concept sentinel_for = see below;                        // since C++20
70
71// [iterator.concept.sizedsentinel], concept sized_sentinel_for
72template<class S, class I>
73  inline constexpr bool disable_sized_sentinel_for = false;
74
75template<class S, class I>
76  concept sized_sentinel_for = see below;
77
78template<class Category, class T, class Distance = ptrdiff_t,
79         class Pointer = T*, class Reference = T&>
80struct iterator
81{
82    typedef T         value_type;
83    typedef Distance  difference_type;
84    typedef Pointer   pointer;
85    typedef Reference reference;
86    typedef Category  iterator_category;
87};
88
89struct input_iterator_tag  {};
90struct output_iterator_tag {};
91struct forward_iterator_tag       : public input_iterator_tag         {};
92struct bidirectional_iterator_tag : public forward_iterator_tag       {};
93struct random_access_iterator_tag : public bidirectional_iterator_tag {};
94
95// 27.4.3, iterator operations
96template <class InputIterator, class Distance>  // constexpr in C++17
97  constexpr void advance(InputIterator& i, Distance n);
98
99template <class InputIterator>  // constexpr in C++17
100  constexpr typename iterator_traits<InputIterator>::difference_type
101    distance(InputIterator first, InputIterator last);
102
103template <class InputIterator>  // constexpr in C++17
104  constexpr InputIterator next(InputIterator x,
105typename iterator_traits<InputIterator>::difference_type n = 1);
106
107template <class BidirectionalIterator>  // constexpr in C++17
108  constexpr BidirectionalIterator prev(BidirectionalIterator x,
109    typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
110
111template <class Iterator>
112class reverse_iterator
113    : public iterator<typename iterator_traits<Iterator>::iterator_category,
114                      typename iterator_traits<Iterator>::value_type,
115                      typename iterator_traits<Iterator>::difference_type,
116                      typename iterator_traits<Iterator>::pointer,
117                      typename iterator_traits<Iterator>::reference>
118{
119protected:
120    Iterator current;
121public:
122    typedef Iterator                                            iterator_type;
123    typedef typename iterator_traits<Iterator>::difference_type difference_type;
124    typedef typename iterator_traits<Iterator>::reference       reference;
125    typedef typename iterator_traits<Iterator>::pointer         pointer;
126
127    constexpr reverse_iterator();
128    constexpr explicit reverse_iterator(Iterator x);
129    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
130    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
131    constexpr Iterator base() const;
132    constexpr reference operator*() const;
133    constexpr pointer   operator->() const;
134    constexpr reverse_iterator& operator++();
135    constexpr reverse_iterator  operator++(int);
136    constexpr reverse_iterator& operator--();
137    constexpr reverse_iterator  operator--(int);
138    constexpr reverse_iterator  operator+ (difference_type n) const;
139    constexpr reverse_iterator& operator+=(difference_type n);
140    constexpr reverse_iterator  operator- (difference_type n) const;
141    constexpr reverse_iterator& operator-=(difference_type n);
142    constexpr reference         operator[](difference_type n) const;
143};
144
145template <class Iterator1, class Iterator2>
146constexpr bool                          // constexpr in C++17
147operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
148
149template <class Iterator1, class Iterator2>
150constexpr bool                          // constexpr in C++17
151operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
152
153template <class Iterator1, class Iterator2>
154constexpr bool                          // constexpr in C++17
155operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
156
157template <class Iterator1, class Iterator2>
158constexpr bool                          // constexpr in C++17
159operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
160
161template <class Iterator1, class Iterator2>
162constexpr bool                          // constexpr in C++17
163operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
164
165template <class Iterator1, class Iterator2>
166constexpr bool                          // constexpr in C++17
167operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
168
169template <class Iterator1, class Iterator2>
170constexpr auto
171operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
172-> decltype(__y.base() - __x.base());   // constexpr in C++17
173
174template <class Iterator>
175constexpr reverse_iterator<Iterator>
176operator+(typename reverse_iterator<Iterator>::difference_type n,
177          const reverse_iterator<Iterator>& x);   // constexpr in C++17
178
179template <class Iterator>
180constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
181
182template <class Container>
183class back_insert_iterator
184{
185protected:
186    Container* container;
187public:
188    typedef Container                   container_type;
189    typedef void                        value_type;
190    typedef void                        difference_type;
191    typedef void                        reference;
192    typedef void                        pointer;
193
194    explicit back_insert_iterator(Container& x);  // constexpr in C++20
195    back_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
196    back_insert_iterator& operator*();  // constexpr in C++20
197    back_insert_iterator& operator++();  // constexpr in C++20
198    back_insert_iterator  operator++(int);  // constexpr in C++20
199};
200
201template <class Container> back_insert_iterator<Container> back_inserter(Container& x);  // constexpr in C++20
202
203template <class Container>
204class front_insert_iterator
205{
206protected:
207    Container* container;
208public:
209    typedef Container                    container_type;
210    typedef void                         value_type;
211    typedef void                         difference_type;
212    typedef void                         reference;
213    typedef void                         pointer;
214
215    explicit front_insert_iterator(Container& x);  // constexpr in C++20
216    front_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
217    front_insert_iterator& operator*();  // constexpr in C++20
218    front_insert_iterator& operator++();  // constexpr in C++20
219    front_insert_iterator  operator++(int);  // constexpr in C++20
220};
221
222template <class Container> front_insert_iterator<Container> front_inserter(Container& x);  // constexpr in C++20
223
224template <class Container>
225class insert_iterator
226{
227protected:
228    Container* container;
229    typename Container::iterator iter;
230public:
231    typedef Container              container_type;
232    typedef void                   value_type;
233    typedef void                   difference_type;
234    typedef void                   reference;
235    typedef void                   pointer;
236
237    insert_iterator(Container& x, typename Container::iterator i);  // constexpr in C++20
238    insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
239    insert_iterator& operator*();  // constexpr in C++20
240    insert_iterator& operator++();  // constexpr in C++20
241    insert_iterator& operator++(int);  // constexpr in C++20
242};
243
244template <class Container, class Iterator>
245insert_iterator<Container> inserter(Container& x, Iterator i);  // constexpr in C++20
246
247template <class Iterator>
248class move_iterator {
249public:
250    typedef Iterator                                              iterator_type;
251    typedef typename iterator_traits<Iterator>::difference_type   difference_type;
252    typedef Iterator                                              pointer;
253    typedef typename iterator_traits<Iterator>::value_type        value_type;
254    typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
255    typedef value_type&&                                          reference;
256
257    constexpr move_iterator();  // all the constexprs are in C++17
258    constexpr explicit move_iterator(Iterator i);
259    template <class U>
260      constexpr move_iterator(const move_iterator<U>& u);
261    template <class U>
262      constexpr move_iterator& operator=(const move_iterator<U>& u);
263    constexpr iterator_type base() const;
264    constexpr reference operator*() const;
265    constexpr pointer operator->() const;
266    constexpr move_iterator& operator++();
267    constexpr move_iterator operator++(int);
268    constexpr move_iterator& operator--();
269    constexpr move_iterator operator--(int);
270    constexpr move_iterator operator+(difference_type n) const;
271    constexpr move_iterator& operator+=(difference_type n);
272    constexpr move_iterator operator-(difference_type n) const;
273    constexpr move_iterator& operator-=(difference_type n);
274    constexpr unspecified operator[](difference_type n) const;
275private:
276    Iterator current; // exposition only
277};
278
279template <class Iterator1, class Iterator2>
280constexpr bool   // constexpr in C++17
281operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
282
283template <class Iterator1, class Iterator2>
284constexpr bool   // constexpr in C++17
285operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
286
287template <class Iterator1, class Iterator2>
288constexpr bool   // constexpr in C++17
289operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
290
291template <class Iterator1, class Iterator2>
292constexpr bool   // constexpr in C++17
293operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
294
295template <class Iterator1, class Iterator2>
296constexpr bool   // constexpr in C++17
297operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
298
299template <class Iterator1, class Iterator2>
300constexpr bool   // constexpr in C++17
301operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
302
303template <class Iterator1, class Iterator2>
304constexpr auto   // constexpr in C++17
305operator-(const move_iterator<Iterator1>& x,
306          const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
307
308template <class Iterator>
309constexpr move_iterator<Iterator> operator+(   // constexpr in C++17
310            typename move_iterator<Iterator>::difference_type n,
311            const move_iterator<Iterator>& x);
312
313template <class Iterator>   // constexpr in C++17
314constexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
315
316
317template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
318class istream_iterator
319    : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
320{
321public:
322    typedef charT char_type;
323    typedef traits traits_type;
324    typedef basic_istream<charT,traits> istream_type;
325
326    constexpr istream_iterator();
327    istream_iterator(istream_type& s);
328    istream_iterator(const istream_iterator& x);
329    ~istream_iterator();
330
331    const T& operator*() const;
332    const T* operator->() const;
333    istream_iterator& operator++();
334    istream_iterator  operator++(int);
335};
336
337template <class T, class charT, class traits, class Distance>
338bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
339                const istream_iterator<T,charT,traits,Distance>& y);
340template <class T, class charT, class traits, class Distance>
341bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
342                const istream_iterator<T,charT,traits,Distance>& y);
343
344template <class T, class charT = char, class traits = char_traits<charT> >
345class ostream_iterator
346    : public iterator<output_iterator_tag, void, void, void ,void>
347{
348public:
349    typedef charT char_type;
350    typedef traits traits_type;
351    typedef basic_ostream<charT,traits> ostream_type;
352
353    ostream_iterator(ostream_type& s);
354    ostream_iterator(ostream_type& s, const charT* delimiter);
355    ostream_iterator(const ostream_iterator& x);
356    ~ostream_iterator();
357    ostream_iterator& operator=(const T& value);
358
359    ostream_iterator& operator*();
360    ostream_iterator& operator++();
361    ostream_iterator& operator++(int);
362};
363
364template<class charT, class traits = char_traits<charT> >
365class istreambuf_iterator
366    : public iterator<input_iterator_tag, charT,
367                      typename traits::off_type, unspecified,
368                      charT>
369{
370public:
371    typedef charT                         char_type;
372    typedef traits                        traits_type;
373    typedef typename traits::int_type     int_type;
374    typedef basic_streambuf<charT,traits> streambuf_type;
375    typedef basic_istream<charT,traits>   istream_type;
376
377    istreambuf_iterator() noexcept;
378    istreambuf_iterator(istream_type& s) noexcept;
379    istreambuf_iterator(streambuf_type* s) noexcept;
380    istreambuf_iterator(a-private-type) noexcept;
381
382    charT                operator*() const;
383    pointer operator->() const;
384    istreambuf_iterator& operator++();
385    a-private-type       operator++(int);
386
387    bool equal(const istreambuf_iterator& b) const;
388};
389
390template <class charT, class traits>
391bool operator==(const istreambuf_iterator<charT,traits>& a,
392                const istreambuf_iterator<charT,traits>& b);
393template <class charT, class traits>
394bool operator!=(const istreambuf_iterator<charT,traits>& a,
395                const istreambuf_iterator<charT,traits>& b);
396
397template <class charT, class traits = char_traits<charT> >
398class ostreambuf_iterator
399    : public iterator<output_iterator_tag, void, void, void, void>
400{
401public:
402    typedef charT                         char_type;
403    typedef traits                        traits_type;
404    typedef basic_streambuf<charT,traits> streambuf_type;
405    typedef basic_ostream<charT,traits>   ostream_type;
406
407    ostreambuf_iterator(ostream_type& s) noexcept;
408    ostreambuf_iterator(streambuf_type* s) noexcept;
409    ostreambuf_iterator& operator=(charT c);
410    ostreambuf_iterator& operator*();
411    ostreambuf_iterator& operator++();
412    ostreambuf_iterator& operator++(int);
413    bool failed() const noexcept;
414};
415
416template <class C> constexpr auto begin(C& c) -> decltype(c.begin());
417template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
418template <class C> constexpr auto end(C& c) -> decltype(c.end());
419template <class C> constexpr auto end(const C& c) -> decltype(c.end());
420template <class T, size_t N> constexpr T* begin(T (&array)[N]);
421template <class T, size_t N> constexpr T* end(T (&array)[N]);
422
423template <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c));        // C++14
424template <class C> auto constexpr cend(const C& c) -> decltype(std::end(c));            // C++14
425template <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
426template <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
427template <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
428template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
429template <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
430template <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il);   // C++14
431template <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
432template <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
433template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
434template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
435
436// 24.8, container access:
437template <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
438template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
439
440template <class C> constexpr auto ssize(const C& c)
441    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;                    // C++20
442template <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
443
444template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
445template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
446template <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
447template <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
448template <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
449template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
450template <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
451
452}  // std
453
454*/
455
456#include <__config>
457#include <__debug>
458#include <__functional_base>
459#include <__iterator/concepts.h>
460#include <__iterator/incrementable_traits.h>
461#include <__iterator/iter_move.h>
462#include <__iterator/iterator_traits.h>
463#include <__iterator/readable_traits.h>
464#include <__memory/addressof.h>
465#include <__memory/pointer_traits.h>
466#include <compare>
467#include <concepts> // Mandated by the Standard.
468#include <cstddef>
469#include <initializer_list>
470#include <iosfwd> // for forward declarations of vector and string
471#include <type_traits>
472#include <version>
473
474#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
475#pragma GCC system_header
476#endif
477
478_LIBCPP_BEGIN_NAMESPACE_STD
479
480template<class _Category, class _Tp, class _Distance = ptrdiff_t,
481         class _Pointer = _Tp*, class _Reference = _Tp&>
482struct _LIBCPP_TEMPLATE_VIS iterator
483{
484    typedef _Tp        value_type;
485    typedef _Distance  difference_type;
486    typedef _Pointer   pointer;
487    typedef _Reference reference;
488    typedef _Category  iterator_category;
489};
490
491template <class _InputIter>
492inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
493void __advance(_InputIter& __i,
494             typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)
495{
496    for (; __n > 0; --__n)
497        ++__i;
498}
499
500template <class _BiDirIter>
501inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
502void __advance(_BiDirIter& __i,
503             typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag)
504{
505    if (__n >= 0)
506        for (; __n > 0; --__n)
507            ++__i;
508    else
509        for (; __n < 0; ++__n)
510            --__i;
511}
512
513template <class _RandIter>
514inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
515void __advance(_RandIter& __i,
516             typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)
517{
518   __i += __n;
519}
520
521template <class _InputIter, class _Distance>
522inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
523void advance(_InputIter& __i, _Distance __orig_n)
524{
525    _LIBCPP_ASSERT(__orig_n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
526                   "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
527    typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
528    _IntegralSize __n = __orig_n;
529    _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
530}
531
532template <class _InputIter>
533inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
534typename iterator_traits<_InputIter>::difference_type
535__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
536{
537    typename iterator_traits<_InputIter>::difference_type __r(0);
538    for (; __first != __last; ++__first)
539        ++__r;
540    return __r;
541}
542
543template <class _RandIter>
544inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
545typename iterator_traits<_RandIter>::difference_type
546__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
547{
548    return __last - __first;
549}
550
551template <class _InputIter>
552inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
553typename iterator_traits<_InputIter>::difference_type
554distance(_InputIter __first, _InputIter __last)
555{
556    return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
557}
558
559template <class _InputIter>
560inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
561typename enable_if
562<
563    __is_cpp17_input_iterator<_InputIter>::value,
564    _InputIter
565>::type
566next(_InputIter __x,
567     typename iterator_traits<_InputIter>::difference_type __n = 1)
568{
569    _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
570                       "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
571
572    _VSTD::advance(__x, __n);
573    return __x;
574}
575
576template <class _InputIter>
577inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
578typename enable_if
579<
580    __is_cpp17_input_iterator<_InputIter>::value,
581    _InputIter
582>::type
583prev(_InputIter __x,
584     typename iterator_traits<_InputIter>::difference_type __n = 1)
585{
586    _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
587                       "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
588    _VSTD::advance(__x, -__n);
589    return __x;
590}
591
592
593template <class _Tp, class = void>
594struct __is_stashing_iterator : false_type {};
595
596template <class _Tp>
597struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
598  : true_type {};
599
600template <class _Iter>
601class _LIBCPP_TEMPLATE_VIS reverse_iterator
602    : public iterator<typename iterator_traits<_Iter>::iterator_category,
603                      typename iterator_traits<_Iter>::value_type,
604                      typename iterator_traits<_Iter>::difference_type,
605                      typename iterator_traits<_Iter>::pointer,
606                      typename iterator_traits<_Iter>::reference>
607{
608private:
609    /*mutable*/ _Iter __t;  // no longer used as of LWG #2360, not removed due to ABI break
610
611    static_assert(!__is_stashing_iterator<_Iter>::value,
612      "The specified iterator type cannot be used with reverse_iterator; "
613      "Using stashing iterators with reverse_iterator causes undefined behavior");
614
615protected:
616    _Iter current;
617public:
618    typedef _Iter                                            iterator_type;
619    typedef typename iterator_traits<_Iter>::difference_type difference_type;
620    typedef typename iterator_traits<_Iter>::reference       reference;
621    typedef typename iterator_traits<_Iter>::pointer         pointer;
622    typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
623        random_access_iterator_tag,
624        typename iterator_traits<_Iter>::iterator_category>  iterator_category;
625#if _LIBCPP_STD_VER > 17
626    typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
627        random_access_iterator_tag,
628        bidirectional_iterator_tag>                          iterator_concept;
629#endif
630
631    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
632    reverse_iterator() : __t(), current() {}
633    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
634    explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
635    template <class _Up>
636        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
637        reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {}
638    template <class _Up>
639        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
640        reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
641            { __t = current = __u.base(); return *this; }
642    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
643    _Iter base() const {return current;}
644    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
645    reference operator*() const {_Iter __tmp = current; return *--__tmp;}
646    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
647    pointer  operator->() const {return _VSTD::addressof(operator*());}
648    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
649    reverse_iterator& operator++() {--current; return *this;}
650    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
651    reverse_iterator  operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
652    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
653    reverse_iterator& operator--() {++current; return *this;}
654    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
655    reverse_iterator  operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
656    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
657    reverse_iterator  operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
658    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
659    reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
660    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
661    reverse_iterator  operator- (difference_type __n) const {return reverse_iterator(current + __n);}
662    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
663    reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
664    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
665    reference         operator[](difference_type __n) const {return *(*this + __n);}
666};
667
668template <class _Iter1, class _Iter2>
669inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
670bool
671operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
672{
673    return __x.base() == __y.base();
674}
675
676template <class _Iter1, class _Iter2>
677inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
678bool
679operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
680{
681    return __x.base() > __y.base();
682}
683
684template <class _Iter1, class _Iter2>
685inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
686bool
687operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
688{
689    return __x.base() != __y.base();
690}
691
692template <class _Iter1, class _Iter2>
693inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
694bool
695operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
696{
697    return __x.base() < __y.base();
698}
699
700template <class _Iter1, class _Iter2>
701inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
702bool
703operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
704{
705    return __x.base() <= __y.base();
706}
707
708template <class _Iter1, class _Iter2>
709inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
710bool
711operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
712{
713    return __x.base() >= __y.base();
714}
715
716#ifndef _LIBCPP_CXX03_LANG
717template <class _Iter1, class _Iter2>
718inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
719auto
720operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
721-> decltype(__y.base() - __x.base())
722{
723    return __y.base() - __x.base();
724}
725#else
726template <class _Iter1, class _Iter2>
727inline _LIBCPP_INLINE_VISIBILITY
728typename reverse_iterator<_Iter1>::difference_type
729operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
730{
731    return __y.base() - __x.base();
732}
733#endif
734
735template <class _Iter>
736inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
737reverse_iterator<_Iter>
738operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
739{
740    return reverse_iterator<_Iter>(__x.base() - __n);
741}
742
743#if _LIBCPP_STD_VER > 11
744template <class _Iter>
745inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
746reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
747{
748    return reverse_iterator<_Iter>(__i);
749}
750#endif
751
752template <class _Container>
753class _LIBCPP_TEMPLATE_VIS back_insert_iterator
754    : public iterator<output_iterator_tag,
755                      void,
756                      void,
757                      void,
758                      void>
759{
760protected:
761    _Container* container;
762public:
763    typedef _Container container_type;
764
765    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
766    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
767        {container->push_back(__value_); return *this;}
768#ifndef _LIBCPP_CXX03_LANG
769    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_)
770        {container->push_back(_VSTD::move(__value_)); return *this;}
771#endif // _LIBCPP_CXX03_LANG
772    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*()     {return *this;}
773    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++()    {return *this;}
774    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator  operator++(int) {return *this;}
775};
776
777template <class _Container>
778inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
779back_insert_iterator<_Container>
780back_inserter(_Container& __x)
781{
782    return back_insert_iterator<_Container>(__x);
783}
784
785template <class _Container>
786class _LIBCPP_TEMPLATE_VIS front_insert_iterator
787    : public iterator<output_iterator_tag,
788                      void,
789                      void,
790                      void,
791                      void>
792{
793protected:
794    _Container* container;
795public:
796    typedef _Container container_type;
797
798    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
799    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
800        {container->push_front(__value_); return *this;}
801#ifndef _LIBCPP_CXX03_LANG
802    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_)
803        {container->push_front(_VSTD::move(__value_)); return *this;}
804#endif // _LIBCPP_CXX03_LANG
805    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*()     {return *this;}
806    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++()    {return *this;}
807    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator  operator++(int) {return *this;}
808};
809
810template <class _Container>
811inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
812front_insert_iterator<_Container>
813front_inserter(_Container& __x)
814{
815    return front_insert_iterator<_Container>(__x);
816}
817
818template <class _Container>
819class _LIBCPP_TEMPLATE_VIS insert_iterator
820    : public iterator<output_iterator_tag,
821                      void,
822                      void,
823                      void,
824                      void>
825{
826protected:
827    _Container* container;
828    typename _Container::iterator iter;
829public:
830    typedef _Container container_type;
831
832    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
833        : container(_VSTD::addressof(__x)), iter(__i) {}
834    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
835        {iter = container->insert(iter, __value_); ++iter; return *this;}
836#ifndef _LIBCPP_CXX03_LANG
837    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_)
838        {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
839#endif // _LIBCPP_CXX03_LANG
840    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*()        {return *this;}
841    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++()       {return *this;}
842    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int)    {return *this;}
843};
844
845template <class _Container>
846inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
847insert_iterator<_Container>
848inserter(_Container& __x, typename _Container::iterator __i)
849{
850    return insert_iterator<_Container>(__x, __i);
851}
852
853template <class _Tp, class _CharT = char,
854          class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
855class _LIBCPP_TEMPLATE_VIS istream_iterator
856    : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
857{
858public:
859    typedef _CharT char_type;
860    typedef _Traits traits_type;
861    typedef basic_istream<_CharT,_Traits> istream_type;
862private:
863    istream_type* __in_stream_;
864    _Tp __value_;
865public:
866    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
867    _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
868        {
869            if (!(*__in_stream_ >> __value_))
870                __in_stream_ = nullptr;
871        }
872
873    _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
874    _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
875    _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
876        {
877            if (!(*__in_stream_ >> __value_))
878                __in_stream_ = nullptr;
879            return *this;
880        }
881    _LIBCPP_INLINE_VISIBILITY istream_iterator  operator++(int)
882        {istream_iterator __t(*this); ++(*this); return __t;}
883
884    template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
885    friend _LIBCPP_INLINE_VISIBILITY
886    bool
887    operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
888               const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
889
890    template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
891    friend _LIBCPP_INLINE_VISIBILITY
892    bool
893    operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
894               const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
895};
896
897template <class _Tp, class _CharT, class _Traits, class _Distance>
898inline _LIBCPP_INLINE_VISIBILITY
899bool
900operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
901           const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
902{
903    return __x.__in_stream_ == __y.__in_stream_;
904}
905
906template <class _Tp, class _CharT, class _Traits, class _Distance>
907inline _LIBCPP_INLINE_VISIBILITY
908bool
909operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
910           const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
911{
912    return !(__x == __y);
913}
914
915template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
916class _LIBCPP_TEMPLATE_VIS ostream_iterator
917    : public iterator<output_iterator_tag, void, void, void, void>
918{
919public:
920    typedef output_iterator_tag             iterator_category;
921    typedef void                            value_type;
922#if _LIBCPP_STD_VER > 17
923    typedef std::ptrdiff_t                  difference_type;
924#else
925    typedef void                            difference_type;
926#endif
927    typedef void                            pointer;
928    typedef void                            reference;
929    typedef _CharT                          char_type;
930    typedef _Traits                         traits_type;
931    typedef basic_ostream<_CharT, _Traits>  ostream_type;
932
933private:
934    ostream_type* __out_stream_;
935    const char_type* __delim_;
936public:
937    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
938        : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
939    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
940        : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
941    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
942        {
943            *__out_stream_ << __value_;
944            if (__delim_)
945                *__out_stream_ << __delim_;
946            return *this;
947        }
948
949    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*()     {return *this;}
950    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++()    {return *this;}
951    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
952};
953
954template<class _CharT, class _Traits>
955class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
956    : public iterator<input_iterator_tag, _CharT,
957                      typename _Traits::off_type, _CharT*,
958                      _CharT>
959{
960public:
961    typedef _CharT                          char_type;
962    typedef _Traits                         traits_type;
963    typedef typename _Traits::int_type      int_type;
964    typedef basic_streambuf<_CharT,_Traits> streambuf_type;
965    typedef basic_istream<_CharT,_Traits>   istream_type;
966private:
967    mutable streambuf_type* __sbuf_;
968
969    class __proxy
970    {
971        char_type __keep_;
972        streambuf_type* __sbuf_;
973        _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
974            : __keep_(__c), __sbuf_(__s) {}
975        friend class istreambuf_iterator;
976    public:
977        _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
978    };
979
980    _LIBCPP_INLINE_VISIBILITY
981    bool __test_for_eof() const
982    {
983        if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
984            __sbuf_ = nullptr;
985        return __sbuf_ == nullptr;
986    }
987public:
988    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
989    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
990        : __sbuf_(__s.rdbuf()) {}
991    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
992        : __sbuf_(__s) {}
993    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
994        : __sbuf_(__p.__sbuf_) {}
995
996    _LIBCPP_INLINE_VISIBILITY char_type  operator*() const
997        {return static_cast<char_type>(__sbuf_->sgetc());}
998    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
999        {
1000            __sbuf_->sbumpc();
1001            return *this;
1002        }
1003    _LIBCPP_INLINE_VISIBILITY __proxy              operator++(int)
1004        {
1005            return __proxy(__sbuf_->sbumpc(), __sbuf_);
1006        }
1007
1008    _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
1009        {return __test_for_eof() == __b.__test_for_eof();}
1010};
1011
1012template <class _CharT, class _Traits>
1013inline _LIBCPP_INLINE_VISIBILITY
1014bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
1015                const istreambuf_iterator<_CharT,_Traits>& __b)
1016                {return __a.equal(__b);}
1017
1018template <class _CharT, class _Traits>
1019inline _LIBCPP_INLINE_VISIBILITY
1020bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
1021                const istreambuf_iterator<_CharT,_Traits>& __b)
1022                {return !__a.equal(__b);}
1023
1024template <class _CharT, class _Traits>
1025class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
1026    : public iterator<output_iterator_tag, void, void, void, void>
1027{
1028public:
1029    typedef output_iterator_tag                 iterator_category;
1030    typedef void                                value_type;
1031#if _LIBCPP_STD_VER > 17
1032    typedef std::ptrdiff_t                      difference_type;
1033#else
1034    typedef void                                difference_type;
1035#endif
1036    typedef void                                pointer;
1037    typedef void                                reference;
1038    typedef _CharT                              char_type;
1039    typedef _Traits                             traits_type;
1040    typedef basic_streambuf<_CharT, _Traits>    streambuf_type;
1041    typedef basic_ostream<_CharT, _Traits>      ostream_type;
1042
1043private:
1044    streambuf_type* __sbuf_;
1045public:
1046    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
1047        : __sbuf_(__s.rdbuf()) {}
1048    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
1049        : __sbuf_(__s) {}
1050    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
1051        {
1052            if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
1053                __sbuf_ = nullptr;
1054            return *this;
1055        }
1056    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*()     {return *this;}
1057    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++()    {return *this;}
1058    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
1059    _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;}
1060
1061    template <class _Ch, class _Tr>
1062    friend
1063    _LIBCPP_HIDDEN
1064    ostreambuf_iterator<_Ch, _Tr>
1065    __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
1066                     const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
1067                     ios_base& __iob, _Ch __fl);
1068};
1069
1070template <class _Iter>
1071class _LIBCPP_TEMPLATE_VIS move_iterator
1072{
1073private:
1074    _Iter __i;
1075public:
1076    typedef _Iter                                            iterator_type;
1077    typedef typename iterator_traits<iterator_type>::value_type value_type;
1078    typedef typename iterator_traits<iterator_type>::difference_type difference_type;
1079    typedef iterator_type pointer;
1080    typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
1081        random_access_iterator_tag,
1082        typename iterator_traits<_Iter>::iterator_category>  iterator_category;
1083#if _LIBCPP_STD_VER > 17
1084    typedef input_iterator_tag                               iterator_concept;
1085#endif
1086
1087#ifndef _LIBCPP_CXX03_LANG
1088    typedef typename iterator_traits<iterator_type>::reference __reference;
1089    typedef typename conditional<
1090            is_reference<__reference>::value,
1091            typename remove_reference<__reference>::type&&,
1092            __reference
1093        >::type reference;
1094#else
1095    typedef typename iterator_traits<iterator_type>::reference reference;
1096#endif
1097
1098    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1099    move_iterator() : __i() {}
1100    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1101    explicit move_iterator(_Iter __x) : __i(__x) {}
1102    template <class _Up>
1103      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1104      move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
1105    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
1106    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1107    reference operator*() const { return static_cast<reference>(*__i); }
1108    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1109    pointer  operator->() const { return __i;}
1110    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1111    move_iterator& operator++() {++__i; return *this;}
1112    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1113    move_iterator  operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;}
1114    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1115    move_iterator& operator--() {--__i; return *this;}
1116    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1117    move_iterator  operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;}
1118    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1119    move_iterator  operator+ (difference_type __n) const {return move_iterator(__i + __n);}
1120    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1121    move_iterator& operator+=(difference_type __n) {__i += __n; return *this;}
1122    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1123    move_iterator  operator- (difference_type __n) const {return move_iterator(__i - __n);}
1124    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1125    move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;}
1126    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1127    reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); }
1128};
1129
1130template <class _Iter1, class _Iter2>
1131inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1132bool
1133operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1134{
1135    return __x.base() == __y.base();
1136}
1137
1138template <class _Iter1, class _Iter2>
1139inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1140bool
1141operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1142{
1143    return __x.base() < __y.base();
1144}
1145
1146template <class _Iter1, class _Iter2>
1147inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1148bool
1149operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1150{
1151    return __x.base() != __y.base();
1152}
1153
1154template <class _Iter1, class _Iter2>
1155inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1156bool
1157operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1158{
1159    return __x.base() > __y.base();
1160}
1161
1162template <class _Iter1, class _Iter2>
1163inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1164bool
1165operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1166{
1167    return __x.base() >= __y.base();
1168}
1169
1170template <class _Iter1, class _Iter2>
1171inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1172bool
1173operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1174{
1175    return __x.base() <= __y.base();
1176}
1177
1178#ifndef _LIBCPP_CXX03_LANG
1179template <class _Iter1, class _Iter2>
1180inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1181auto
1182operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1183-> decltype(__x.base() - __y.base())
1184{
1185    return __x.base() - __y.base();
1186}
1187#else
1188template <class _Iter1, class _Iter2>
1189inline _LIBCPP_INLINE_VISIBILITY
1190typename move_iterator<_Iter1>::difference_type
1191operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
1192{
1193    return __x.base() - __y.base();
1194}
1195#endif
1196
1197template <class _Iter>
1198inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1199move_iterator<_Iter>
1200operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
1201{
1202    return move_iterator<_Iter>(__x.base() + __n);
1203}
1204
1205template <class _Iter>
1206inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1207move_iterator<_Iter>
1208make_move_iterator(_Iter __i)
1209{
1210    return move_iterator<_Iter>(__i);
1211}
1212
1213// __wrap_iter
1214
1215template <class _Iter> class __wrap_iter;
1216
1217template <class _Iter1, class _Iter2>
1218_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1219bool
1220operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1221
1222template <class _Iter1, class _Iter2>
1223_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1224bool
1225operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1226
1227template <class _Iter1, class _Iter2>
1228_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1229bool
1230operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1231
1232template <class _Iter1, class _Iter2>
1233_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1234bool
1235operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1236
1237template <class _Iter1, class _Iter2>
1238_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1239bool
1240operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1241
1242template <class _Iter1, class _Iter2>
1243_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1244bool
1245operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1246
1247#ifndef _LIBCPP_CXX03_LANG
1248template <class _Iter1, class _Iter2>
1249_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1250auto
1251operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1252-> decltype(__x.base() - __y.base());
1253#else
1254template <class _Iter1, class _Iter2>
1255_LIBCPP_INLINE_VISIBILITY
1256typename __wrap_iter<_Iter1>::difference_type
1257operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1258#endif
1259
1260template <class _Iter>
1261_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1262__wrap_iter<_Iter>
1263operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
1264
1265template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op);
1266template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2);
1267template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 move(_Ip, _Ip, _Op);
1268template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 move_backward(_B1, _B1, _B2);
1269
1270template <class _Iter>
1271class __wrap_iter
1272{
1273public:
1274    typedef _Iter                                                      iterator_type;
1275    typedef typename iterator_traits<iterator_type>::value_type        value_type;
1276    typedef typename iterator_traits<iterator_type>::difference_type   difference_type;
1277    typedef typename iterator_traits<iterator_type>::pointer           pointer;
1278    typedef typename iterator_traits<iterator_type>::reference         reference;
1279    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
1280#if _LIBCPP_STD_VER > 17
1281    typedef _If<__is_cpp17_contiguous_iterator<_Iter>::value,
1282                contiguous_iterator_tag, iterator_category>            iterator_concept;
1283#endif
1284
1285private:
1286    iterator_type __i;
1287public:
1288    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
1289#if _LIBCPP_STD_VER > 11
1290                : __i{}
1291#endif
1292    {
1293#if _LIBCPP_DEBUG_LEVEL == 2
1294        __get_db()->__insert_i(this);
1295#endif
1296    }
1297    template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1298        __wrap_iter(const __wrap_iter<_Up>& __u,
1299            typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
1300            : __i(__u.base())
1301    {
1302#if _LIBCPP_DEBUG_LEVEL == 2
1303        __get_db()->__iterator_copy(this, &__u);
1304#endif
1305    }
1306#if _LIBCPP_DEBUG_LEVEL == 2
1307    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1308    __wrap_iter(const __wrap_iter& __x)
1309        : __i(__x.base())
1310    {
1311        __get_db()->__iterator_copy(this, &__x);
1312    }
1313    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1314    __wrap_iter& operator=(const __wrap_iter& __x)
1315    {
1316        if (this != &__x)
1317        {
1318            __get_db()->__iterator_copy(this, &__x);
1319            __i = __x.__i;
1320        }
1321        return *this;
1322    }
1323    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1324    ~__wrap_iter()
1325    {
1326        __get_db()->__erase_i(this);
1327    }
1328#endif
1329    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
1330    {
1331#if _LIBCPP_DEBUG_LEVEL == 2
1332        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
1333                       "Attempted to dereference a non-dereferenceable iterator");
1334#endif
1335        return *__i;
1336    }
1337    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer  operator->() const _NOEXCEPT
1338    {
1339#if _LIBCPP_DEBUG_LEVEL == 2
1340        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
1341                       "Attempted to dereference a non-dereferenceable iterator");
1342#endif
1343        return (pointer)_VSTD::addressof(*__i);
1344    }
1345    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
1346    {
1347#if _LIBCPP_DEBUG_LEVEL == 2
1348        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
1349                       "Attempted to increment non-incrementable iterator");
1350#endif
1351        ++__i;
1352        return *this;
1353    }
1354    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator++(int) _NOEXCEPT
1355        {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
1356
1357    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
1358    {
1359#if _LIBCPP_DEBUG_LEVEL == 2
1360        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
1361                       "Attempted to decrement non-decrementable iterator");
1362#endif
1363        --__i;
1364        return *this;
1365    }
1366    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator--(int) _NOEXCEPT
1367        {__wrap_iter __tmp(*this); --(*this); return __tmp;}
1368    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT
1369        {__wrap_iter __w(*this); __w += __n; return __w;}
1370    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
1371    {
1372#if _LIBCPP_DEBUG_LEVEL == 2
1373        _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
1374                   "Attempted to add/subtract iterator outside of valid range");
1375#endif
1376        __i += __n;
1377        return *this;
1378    }
1379    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator- (difference_type __n) const _NOEXCEPT
1380        {return *this + (-__n);}
1381    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
1382        {*this += -__n; return *this;}
1383    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference    operator[](difference_type __n) const _NOEXCEPT
1384    {
1385#if _LIBCPP_DEBUG_LEVEL == 2
1386        _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
1387                   "Attempted to subscript iterator outside of valid range");
1388#endif
1389        return __i[__n];
1390    }
1391
1392    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
1393
1394private:
1395#if _LIBCPP_DEBUG_LEVEL == 2
1396    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
1397    {
1398        __get_db()->__insert_ic(this, __p);
1399    }
1400#else
1401    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
1402#endif
1403
1404    template <class _Up> friend class __wrap_iter;
1405    template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
1406    template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
1407    template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
1408
1409    template <class _Iter1, class _Iter2>
1410    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1411    bool
1412    operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1413
1414    template <class _Iter1, class _Iter2>
1415    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1416    bool
1417    operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1418
1419    template <class _Iter1, class _Iter2>
1420    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1421    bool
1422    operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1423
1424    template <class _Iter1, class _Iter2>
1425    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1426    bool
1427    operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1428
1429    template <class _Iter1, class _Iter2>
1430    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1431    bool
1432    operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1433
1434    template <class _Iter1, class _Iter2>
1435    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1436    bool
1437    operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1438
1439#ifndef _LIBCPP_CXX03_LANG
1440    template <class _Iter1, class _Iter2>
1441    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1442    auto
1443    operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1444    -> decltype(__x.base() - __y.base());
1445#else
1446    template <class _Iter1, class _Iter2>
1447    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1448    typename __wrap_iter<_Iter1>::difference_type
1449    operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
1450#endif
1451
1452    template <class _Iter1>
1453    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
1454    __wrap_iter<_Iter1>
1455    operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
1456};
1457
1458#if _LIBCPP_STD_VER <= 17
1459template <class _It>
1460struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : __is_cpp17_contiguous_iterator<_It> {};
1461#endif
1462
1463template <class _Iter>
1464_LIBCPP_CONSTEXPR
1465_EnableIf<__is_cpp17_contiguous_iterator<_Iter>::value, decltype(_VSTD::__to_address(declval<_Iter>()))>
1466__to_address(__wrap_iter<_Iter> __w) _NOEXCEPT {
1467    return _VSTD::__to_address(__w.base());
1468}
1469
1470template <class _Iter1, class _Iter2>
1471inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1472bool
1473operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1474{
1475    return __x.base() == __y.base();
1476}
1477
1478template <class _Iter1, class _Iter2>
1479inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1480bool
1481operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1482{
1483#if _LIBCPP_DEBUG_LEVEL == 2
1484    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
1485                   "Attempted to compare incomparable iterators");
1486#endif
1487    return __x.base() < __y.base();
1488}
1489
1490template <class _Iter1, class _Iter2>
1491inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1492bool
1493operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1494{
1495    return !(__x == __y);
1496}
1497
1498template <class _Iter1, class _Iter2>
1499inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1500bool
1501operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1502{
1503    return __y < __x;
1504}
1505
1506template <class _Iter1, class _Iter2>
1507inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1508bool
1509operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1510{
1511    return !(__x < __y);
1512}
1513
1514template <class _Iter1, class _Iter2>
1515inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1516bool
1517operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1518{
1519    return !(__y < __x);
1520}
1521
1522template <class _Iter1>
1523inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1524bool
1525operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1526{
1527    return !(__x == __y);
1528}
1529
1530template <class _Iter1>
1531inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1532bool
1533operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1534{
1535    return __y < __x;
1536}
1537
1538template <class _Iter1>
1539inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1540bool
1541operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1542{
1543    return !(__x < __y);
1544}
1545
1546template <class _Iter1>
1547inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1548bool
1549operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
1550{
1551    return !(__y < __x);
1552}
1553
1554#ifndef _LIBCPP_CXX03_LANG
1555template <class _Iter1, class _Iter2>
1556inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1557auto
1558operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1559-> decltype(__x.base() - __y.base())
1560{
1561#if _LIBCPP_DEBUG_LEVEL == 2
1562    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
1563                   "Attempted to subtract incompatible iterators");
1564#endif
1565    return __x.base() - __y.base();
1566}
1567#else
1568template <class _Iter1, class _Iter2>
1569inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1570typename __wrap_iter<_Iter1>::difference_type
1571operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
1572{
1573#if _LIBCPP_DEBUG_LEVEL == 2
1574    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
1575                   "Attempted to subtract incompatible iterators");
1576#endif
1577    return __x.base() - __y.base();
1578}
1579#endif
1580
1581template <class _Iter>
1582inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
1583__wrap_iter<_Iter>
1584operator+(typename __wrap_iter<_Iter>::difference_type __n,
1585          __wrap_iter<_Iter> __x) _NOEXCEPT
1586{
1587    __x += __n;
1588    return __x;
1589}
1590
1591template <class _Tp, size_t _Np>
1592_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1593_Tp*
1594begin(_Tp (&__array)[_Np])
1595{
1596    return __array;
1597}
1598
1599template <class _Tp, size_t _Np>
1600_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1601_Tp*
1602end(_Tp (&__array)[_Np])
1603{
1604    return __array + _Np;
1605}
1606
1607#if !defined(_LIBCPP_CXX03_LANG)
1608
1609template <class _Cp>
1610_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1611auto
1612begin(_Cp& __c) -> decltype(__c.begin())
1613{
1614    return __c.begin();
1615}
1616
1617template <class _Cp>
1618_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1619auto
1620begin(const _Cp& __c) -> decltype(__c.begin())
1621{
1622    return __c.begin();
1623}
1624
1625template <class _Cp>
1626_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1627auto
1628end(_Cp& __c) -> decltype(__c.end())
1629{
1630    return __c.end();
1631}
1632
1633template <class _Cp>
1634_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1635auto
1636end(const _Cp& __c) -> decltype(__c.end())
1637{
1638    return __c.end();
1639}
1640
1641#if _LIBCPP_STD_VER > 11
1642
1643template <class _Tp, size_t _Np>
1644_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1645reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
1646{
1647    return reverse_iterator<_Tp*>(__array + _Np);
1648}
1649
1650template <class _Tp, size_t _Np>
1651_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1652reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
1653{
1654    return reverse_iterator<_Tp*>(__array);
1655}
1656
1657template <class _Ep>
1658_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1659reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
1660{
1661    return reverse_iterator<const _Ep*>(__il.end());
1662}
1663
1664template <class _Ep>
1665_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1666reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
1667{
1668    return reverse_iterator<const _Ep*>(__il.begin());
1669}
1670
1671template <class _Cp>
1672_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1673auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
1674{
1675    return _VSTD::begin(__c);
1676}
1677
1678template <class _Cp>
1679_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1680auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
1681{
1682    return _VSTD::end(__c);
1683}
1684
1685template <class _Cp>
1686_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1687auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
1688{
1689    return __c.rbegin();
1690}
1691
1692template <class _Cp>
1693_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1694auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
1695{
1696    return __c.rbegin();
1697}
1698
1699template <class _Cp>
1700_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1701auto rend(_Cp& __c) -> decltype(__c.rend())
1702{
1703    return __c.rend();
1704}
1705
1706template <class _Cp>
1707_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1708auto rend(const _Cp& __c) -> decltype(__c.rend())
1709{
1710    return __c.rend();
1711}
1712
1713template <class _Cp>
1714_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1715auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
1716{
1717    return _VSTD::rbegin(__c);
1718}
1719
1720template <class _Cp>
1721_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1722auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
1723{
1724    return _VSTD::rend(__c);
1725}
1726
1727#endif
1728
1729
1730#else  // defined(_LIBCPP_CXX03_LANG)
1731
1732template <class _Cp>
1733_LIBCPP_INLINE_VISIBILITY
1734typename _Cp::iterator
1735begin(_Cp& __c)
1736{
1737    return __c.begin();
1738}
1739
1740template <class _Cp>
1741_LIBCPP_INLINE_VISIBILITY
1742typename _Cp::const_iterator
1743begin(const _Cp& __c)
1744{
1745    return __c.begin();
1746}
1747
1748template <class _Cp>
1749_LIBCPP_INLINE_VISIBILITY
1750typename _Cp::iterator
1751end(_Cp& __c)
1752{
1753    return __c.end();
1754}
1755
1756template <class _Cp>
1757_LIBCPP_INLINE_VISIBILITY
1758typename _Cp::const_iterator
1759end(const _Cp& __c)
1760{
1761    return __c.end();
1762}
1763
1764#endif // !defined(_LIBCPP_CXX03_LANG)
1765
1766#if _LIBCPP_STD_VER > 14
1767
1768// #if _LIBCPP_STD_VER > 11
1769// template <>
1770// struct _LIBCPP_TEMPLATE_VIS plus<void>
1771// {
1772//     template <class _T1, class _T2>
1773//     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
1774//     auto operator()(_T1&& __t, _T2&& __u) const
1775//     _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
1776//     -> decltype        (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
1777//         { return        _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
1778//     typedef void is_transparent;
1779// };
1780// #endif
1781
1782template <class _Cont>
1783_LIBCPP_INLINE_VISIBILITY
1784constexpr auto size(const _Cont& __c)
1785_NOEXCEPT_(noexcept(__c.size()))
1786-> decltype        (__c.size())
1787{ return            __c.size(); }
1788
1789template <class _Tp, size_t _Sz>
1790_LIBCPP_INLINE_VISIBILITY
1791constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
1792
1793#if _LIBCPP_STD_VER > 17
1794template <class _Cont>
1795_LIBCPP_INLINE_VISIBILITY
1796constexpr auto ssize(const _Cont& __c)
1797_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
1798->                              common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
1799{ return            static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
1800
1801template <class _Tp, ptrdiff_t _Sz>
1802_LIBCPP_INLINE_VISIBILITY
1803constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
1804#endif
1805
1806template <class _Cont>
1807_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1808constexpr auto empty(const _Cont& __c)
1809_NOEXCEPT_(noexcept(__c.empty()))
1810-> decltype        (__c.empty())
1811{ return            __c.empty(); }
1812
1813template <class _Tp, size_t _Sz>
1814_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1815constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
1816
1817template <class _Ep>
1818_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1819constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
1820
1821template <class _Cont> constexpr
1822_LIBCPP_INLINE_VISIBILITY
1823auto data(_Cont& __c)
1824_NOEXCEPT_(noexcept(__c.data()))
1825-> decltype        (__c.data())
1826{ return            __c.data(); }
1827
1828template <class _Cont> constexpr
1829_LIBCPP_INLINE_VISIBILITY
1830auto data(const _Cont& __c)
1831_NOEXCEPT_(noexcept(__c.data()))
1832-> decltype        (__c.data())
1833{ return            __c.data(); }
1834
1835template <class _Tp, size_t _Sz>
1836_LIBCPP_INLINE_VISIBILITY
1837constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
1838
1839template <class _Ep>
1840_LIBCPP_INLINE_VISIBILITY
1841constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
1842#endif
1843
1844template <class _Container, class _Predicate>
1845typename _Container::size_type
1846__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
1847  typename _Container::size_type __old_size = __c.size();
1848
1849  const typename _Container::iterator __last = __c.end();
1850  for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
1851    if (__pred(*__iter))
1852      __iter = __c.erase(__iter);
1853    else
1854      ++__iter;
1855  }
1856
1857  return __old_size - __c.size();
1858}
1859
1860_LIBCPP_END_NAMESPACE_STD
1861
1862#endif // _LIBCPP_ITERATOR
1863