13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===-------------------------- iterator ----------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_ITERATOR
113e519524SHoward Hinnant#define _LIBCPP_ITERATOR
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    iterator synopsis
153e519524SHoward Hinnant
16fe31f11cSChristopher Di Bella#include <concepts>
17fe31f11cSChristopher Di Bella
183e519524SHoward Hinnantnamespace std
193e519524SHoward Hinnant{
20fe31f11cSChristopher Di Bellatemplate<class> struct incrementable_traits;       // since C++20
219816d43cSChristopher Di Bellatemplate<class T>
229816d43cSChristopher Di Bella  using iter_difference_t = see below;             // since C++20
239816d43cSChristopher Di Bella
24f280505aSChristopher Di Bellatemplate<class> struct indirectly_readable_traits; // since C++20
259816d43cSChristopher Di Bellatemplate<class T>
269816d43cSChristopher Di Bella  using iter_value_t = see below;                  // since C++20
273e519524SHoward Hinnant
283e519524SHoward Hinnanttemplate<class Iterator>
299f01ac3bSzoecarverstruct iterator_traits;
303e519524SHoward Hinnant
313e519524SHoward Hinnanttemplate<class T>
329f01ac3bSzoecarver  requires is_object_v<T>                    // since C++20
339f01ac3bSzoecarverstruct iterator_traits<T*>;
343e519524SHoward Hinnant
350148b653SChristopher Di Bellatemplate<dereferenceable T>
360148b653SChristopher Di Bella  using iter_reference_t = decltype(*declval<T&>());
370148b653SChristopher Di Bella
3897e383aaSLouis Dionnenamespace ranges::inline unspecified {
3997e383aaSLouis Dionne    inline constexpr unspecified iter_move = unspecified; // since C++20, nodiscard as an extension
4097e383aaSLouis Dionne}}
4197e383aaSLouis Dionne
4297e383aaSLouis Dionnetemplate<dereferenceable T>
4397e383aaSLouis Dionne  requires ...
4497e383aaSLouis Dionneusing iter_rvalue_reference_t = decltype(ranges::iter_move(declval<T&>())); // since C++20
4597e383aaSLouis Dionne
4657ebf3d0SLouis Dionne// [iterator.concepts], iterator concepts
4757ebf3d0SLouis Dionne// [iterator.concept.readable], concept indirectly_readable
4857ebf3d0SLouis Dionnetemplate<class In>
4957ebf3d0SLouis Dionne  concept indirectly_readable = see below;                      // since C++20
5057ebf3d0SLouis Dionne
5158b29a4eSLouis Dionnetemplate<indirectly_readable T>
5258b29a4eSLouis Dionne  using iter_common_reference_t =
5358b29a4eSLouis Dionne    common_reference_t<iter_reference_t<T>, iter_value_t<T>&>;  // since C++20
5458b29a4eSLouis Dionne
5557ebf3d0SLouis Dionne// [iterator.concept.writable], concept indirectly_writable
5657ebf3d0SLouis Dionnetemplate<class Out, class T>
5757ebf3d0SLouis Dionne  concept indirectly_writable = see below;                // since C++20
5857ebf3d0SLouis Dionne
5918b03b00SMark de Wever// [iterator.concept.winc], concept weakly_incrementable
6022052860SChristopher Di Bellatemplate<class I>
6122052860SChristopher Di Bella  concept weakly_incrementable = see below;                // since C++20
6222052860SChristopher Di Bella
6322052860SChristopher Di Bella// [iterator.concept.inc], concept incrementable
6422052860SChristopher Di Bellatemplate<class I>
6522052860SChristopher Di Bella  concept incrementable = see below;                       // since C++20
6622052860SChristopher Di Bella
6718b03b00SMark de Wever// [iterator.concept.iterator], concept input_or_output_iterator
6838225d69SChristopher Di Bella  template<class I>
6938225d69SChristopher Di Bella    concept input_or_output_iterator = see below;          // since C++20
7038225d69SChristopher Di Bella
7118b03b00SMark de Wever// [iterator.concept.sentinel], concept sentinel_for
7238225d69SChristopher Di Bellatemplate<class S, class I>
7338225d69SChristopher Di Bella  concept sentinel_for = see below;                        // since C++20
7438225d69SChristopher Di Bella
75bdd68357Szoecarver// [iterator.concept.sizedsentinel], concept sized_sentinel_for
76bdd68357Szoecarvertemplate<class S, class I>
77bdd68357Szoecarver  inline constexpr bool disable_sized_sentinel_for = false;
78bdd68357Szoecarver
79bdd68357Szoecarvertemplate<class S, class I>
80bdd68357Szoecarver  concept sized_sentinel_for = see below;
81bdd68357Szoecarver
82c05d1eedSChristopher Di Bella// [iterator.concept.input], concept input_iterator
83c05d1eedSChristopher Di Bellatemplate<class I>
84c05d1eedSChristopher Di Bella  concept input_iterator = see below;                      // since C++20
85c05d1eedSChristopher Di Bella
867b28c5d3SLouis Dionne// [iterator.concept.output], concept output_iterator
877b28c5d3SLouis Dionnetemplate<class I, class T>
887b28c5d3SLouis Dionne  concept output_iterator = see below;                     // since C++20
897b28c5d3SLouis Dionne
90fa3e2626SChristopher Di Bella// [iterator.concept.forward], concept forward_iterator
91fa3e2626SChristopher Di Bellatemplate<class I>
92fa3e2626SChristopher Di Bella  concept forward_iterator = see below;                    // since C++20
93fa3e2626SChristopher Di Bella
949c5d86aaSChristopher Di Bella// [iterator.concept.bidir], concept bidirectional_iterator
959c5d86aaSChristopher Di Bellatemplate<class I>
969c5d86aaSChristopher Di Bella  concept bidirectional_iterator = see below;              // since C++20
979c5d86aaSChristopher Di Bella
986ffc41b0Szoecarver// [iterator.concept.random.access], concept random_access_iterator
996ffc41b0Szoecarvertemplate<class I>
1006ffc41b0Szoecarver  concept random_access_iterator = see below;              // since C++20
1016ffc41b0Szoecarver
10258b29a4eSLouis Dionne// [indirectcallable]
10358b29a4eSLouis Dionne// [indirectcallable.indirectinvocable]
10458b29a4eSLouis Dionnetemplate<class F, class I>
10558b29a4eSLouis Dionne  concept indirectly_unary_invocable = see below;          // since C++20
10658b29a4eSLouis Dionne
10758b29a4eSLouis Dionnetemplate<class F, class I>
10858b29a4eSLouis Dionne  concept indirectly_regular_unary_invocable = see below;  // since C++20
10958b29a4eSLouis Dionne
11058b29a4eSLouis Dionnetemplate<class F, class I>
11158b29a4eSLouis Dionne  concept indirect_unary_predicate = see below;            // since C++20
11258b29a4eSLouis Dionne
11358b29a4eSLouis Dionnetemplate<class F, class I1, class I2>
11458b29a4eSLouis Dionne  concept indirect_binary_predicate = see below;           // since C++20
11558b29a4eSLouis Dionne
11658b29a4eSLouis Dionnetemplate<class F, class I1, class I2 = I1>
11758b29a4eSLouis Dionne  concept indirect_equivalence_relation = see below;       // since C++20
11858b29a4eSLouis Dionne
11958b29a4eSLouis Dionnetemplate<class F, class I1, class I2 = I1>
12058b29a4eSLouis Dionne  concept indirect_strict_weak_order = see below;          // since C++20
12158b29a4eSLouis Dionne
12258b29a4eSLouis Dionnetemplate<class F, class... Is>
12358b29a4eSLouis Dionne  using indirect_result_t = see below;                     // since C++20
12458b29a4eSLouis Dionne
12558b29a4eSLouis Dionne// [projected], projected
12658b29a4eSLouis Dionnetemplate<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
12758b29a4eSLouis Dionne  struct projected;                                        // since C++20
12858b29a4eSLouis Dionne
12958b29a4eSLouis Dionnetemplate<weakly_incrementable I, indirectly_regular_unary_invocable<I> Proj>
13058b29a4eSLouis Dionne  struct incrementable_traits<projected<I, Proj>>;         // since C++20
13158b29a4eSLouis Dionne
132075f2370Szoecarver// [alg.req.ind.move], concept indirectly_movable
133075f2370Szoecarvertemplate<class In, class Out>
134075f2370Szoecarver  concept indirectly_movable = see below;                  // since C++20
135075f2370Szoecarver
136075f2370Szoecarvertemplate<class In, class Out>
137075f2370Szoecarver  concept indirectly_movable_storable = see below;         // since C++20
138075f2370Szoecarver
139edc1f0c1Szoecarver// [alg.req.ind.swap], concept indirectly_swappable
140edc1f0c1Szoecarvertemplate<class I1, class I2 = I1>
141edc1f0c1Szoecarver  concept indirectly_swappable = see below;                // since C++20
142edc1f0c1Szoecarver
1431a29403dSzoecarvertemplate<input_or_output_iterator I, sentinel_for<I> S>
1441a29403dSzoecarver  requires (!same_as<I, S> && copyable<I>)
1451a29403dSzoecarverclass common_iterator;                                     // since C++20
1461a29403dSzoecarver
1473e519524SHoward Hinnanttemplate<class Category, class T, class Distance = ptrdiff_t,
1483e519524SHoward Hinnant         class Pointer = T*, class Reference = T&>
1491055cb91SLouis Dionnestruct iterator                                            // deprecated in C++17
1503e519524SHoward Hinnant{
1513e519524SHoward Hinnant    typedef T         value_type;
1523e519524SHoward Hinnant    typedef Distance  difference_type;
1533e519524SHoward Hinnant    typedef Pointer   pointer;
1543e519524SHoward Hinnant    typedef Reference reference;
1553e519524SHoward Hinnant    typedef Category  iterator_category;
1563e519524SHoward Hinnant};
1573e519524SHoward Hinnant
1583e519524SHoward Hinnantstruct input_iterator_tag  {};
1593e519524SHoward Hinnantstruct output_iterator_tag {};
1603e519524SHoward Hinnantstruct forward_iterator_tag       : public input_iterator_tag         {};
1613e519524SHoward Hinnantstruct bidirectional_iterator_tag : public forward_iterator_tag       {};
1623e519524SHoward Hinnantstruct random_access_iterator_tag : public bidirectional_iterator_tag {};
1633e519524SHoward Hinnant
164f51ee632SMarshall Clow// 27.4.3, iterator operations
16512b01ab7SLouis Dionnetemplate <class InputIterator, class Distance>  // constexpr in C++17
16612b01ab7SLouis Dionne  constexpr void advance(InputIterator& i, Distance n);
1673e519524SHoward Hinnant
168f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
169f51ee632SMarshall Clow  constexpr typename iterator_traits<InputIterator>::difference_type
1703e519524SHoward Hinnant    distance(InputIterator first, InputIterator last);
1713e519524SHoward Hinnant
172f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
173f51ee632SMarshall Clow  constexpr InputIterator next(InputIterator x,
174f51ee632SMarshall Clowtypename iterator_traits<InputIterator>::difference_type n = 1);
175f51ee632SMarshall Clow
176f51ee632SMarshall Clowtemplate <class BidirectionalIterator>  // constexpr in C++17
177f51ee632SMarshall Clow  constexpr BidirectionalIterator prev(BidirectionalIterator x,
178f51ee632SMarshall Clow    typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
179f51ee632SMarshall Clow
18036d0fdf9SChristopher Di Bella// [range.iter.ops], range iterator operations
18136d0fdf9SChristopher Di Bellanamespace ranges {
18236d0fdf9SChristopher Di Bella  // [range.iter.op.advance], ranges::advance
18336d0fdf9SChristopher Di Bella  template<input_or_output_iterator I>
18436d0fdf9SChristopher Di Bella    constexpr void advance(I& i, iter_difference_t<I> n);                          // since C++20
18536d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
18636d0fdf9SChristopher Di Bella    constexpr void advance(I& i, S bound);                                         // since C++20
18736d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
18836d0fdf9SChristopher Di Bella    constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound); // since C++20
18936d0fdf9SChristopher Di Bella}
19036d0fdf9SChristopher Di Bella
1913e519524SHoward Hinnanttemplate <class Iterator>
1923e519524SHoward Hinnantclass reverse_iterator
1931055cb91SLouis Dionne    : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17
1943e519524SHoward Hinnant                      typename iterator_traits<Iterator>::value_type,
1953e519524SHoward Hinnant                      typename iterator_traits<Iterator>::difference_type,
1963e519524SHoward Hinnant                      typename iterator_traits<Iterator>::pointer,
1973e519524SHoward Hinnant                      typename iterator_traits<Iterator>::reference>
1983e519524SHoward Hinnant{
1993e519524SHoward Hinnantprotected:
2003e519524SHoward Hinnant    Iterator current;
2013e519524SHoward Hinnantpublic:
2023e519524SHoward Hinnant    typedef Iterator                                            iterator_type;
2033e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::difference_type difference_type;
2043e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::reference       reference;
2053e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::pointer         pointer;
2063e519524SHoward Hinnant
2071b8f260eSMarshall Clow    constexpr reverse_iterator();
2081b8f260eSMarshall Clow    constexpr explicit reverse_iterator(Iterator x);
2091b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
2101b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
2111b8f260eSMarshall Clow    constexpr Iterator base() const;
2121b8f260eSMarshall Clow    constexpr reference operator*() const;
2131b8f260eSMarshall Clow    constexpr pointer   operator->() const;
2141b8f260eSMarshall Clow    constexpr reverse_iterator& operator++();
2151b8f260eSMarshall Clow    constexpr reverse_iterator  operator++(int);
2161b8f260eSMarshall Clow    constexpr reverse_iterator& operator--();
2171b8f260eSMarshall Clow    constexpr reverse_iterator  operator--(int);
2181b8f260eSMarshall Clow    constexpr reverse_iterator  operator+ (difference_type n) const;
2191b8f260eSMarshall Clow    constexpr reverse_iterator& operator+=(difference_type n);
2201b8f260eSMarshall Clow    constexpr reverse_iterator  operator- (difference_type n) const;
2211b8f260eSMarshall Clow    constexpr reverse_iterator& operator-=(difference_type n);
2221b8f260eSMarshall Clow    constexpr reference         operator[](difference_type n) const;
2233e519524SHoward Hinnant};
2243e519524SHoward Hinnant
2253e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2261b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2273e519524SHoward Hinnantoperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2283e519524SHoward Hinnant
2293e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2301b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2313e519524SHoward Hinnantoperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2323e519524SHoward Hinnant
2333e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2341b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2353e519524SHoward Hinnantoperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2363e519524SHoward Hinnant
2373e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2381b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2393e519524SHoward Hinnantoperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2403e519524SHoward Hinnant
2413e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2421b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2433e519524SHoward Hinnantoperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2443e519524SHoward Hinnant
2453e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2461b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2473e519524SHoward Hinnantoperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2483e519524SHoward Hinnant
2493e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2501b8f260eSMarshall Clowconstexpr auto
251947ce6b5SMarshall Clowoperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
2521b8f260eSMarshall Clow-> decltype(__y.base() - __x.base());   // constexpr in C++17
2533e519524SHoward Hinnant
2543e519524SHoward Hinnanttemplate <class Iterator>
2551b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator>
2561b8f260eSMarshall Clowoperator+(typename reverse_iterator<Iterator>::difference_type n,
2571b8f260eSMarshall Clow          const reverse_iterator<Iterator>& x);   // constexpr in C++17
2583e519524SHoward Hinnant
2591b8f260eSMarshall Clowtemplate <class Iterator>
2601b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
2616a640a18SMarshall Clow
2623e519524SHoward Hinnanttemplate <class Container>
2633e519524SHoward Hinnantclass back_insert_iterator
26441bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
2653e519524SHoward Hinnant{
2663e519524SHoward Hinnantprotected:
2673e519524SHoward Hinnant    Container* container;
2683e519524SHoward Hinnantpublic:
2693e519524SHoward Hinnant    typedef Container                   container_type;
2703e519524SHoward Hinnant    typedef void                        value_type;
27141bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
27241bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
2738892b4eeSEric Fiselier    typedef void                        reference;
2743e519524SHoward Hinnant    typedef void                        pointer;
2753e519524SHoward Hinnant
27606e2b737SArthur O'Dwyer    explicit back_insert_iterator(Container& x);  // constexpr in C++20
27706e2b737SArthur O'Dwyer    back_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
27806e2b737SArthur O'Dwyer    back_insert_iterator& operator*();  // constexpr in C++20
27906e2b737SArthur O'Dwyer    back_insert_iterator& operator++();  // constexpr in C++20
28006e2b737SArthur O'Dwyer    back_insert_iterator  operator++(int);  // constexpr in C++20
2813e519524SHoward Hinnant};
2823e519524SHoward Hinnant
28306e2b737SArthur O'Dwyertemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x);  // constexpr in C++20
2843e519524SHoward Hinnant
2853e519524SHoward Hinnanttemplate <class Container>
2863e519524SHoward Hinnantclass front_insert_iterator
28741bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
2883e519524SHoward Hinnant{
2893e519524SHoward Hinnantprotected:
2903e519524SHoward Hinnant    Container* container;
2913e519524SHoward Hinnantpublic:
2923e519524SHoward Hinnant    typedef Container                    container_type;
2933e519524SHoward Hinnant    typedef void                         value_type;
29441bdf64dSLouis Dionne    typedef void                         difference_type; // until C++20
29541bdf64dSLouis Dionne    typedef ptrdiff_t                    difference_type; // since C++20
2968892b4eeSEric Fiselier    typedef void                         reference;
2973e519524SHoward Hinnant    typedef void                         pointer;
2983e519524SHoward Hinnant
29906e2b737SArthur O'Dwyer    explicit front_insert_iterator(Container& x);  // constexpr in C++20
30006e2b737SArthur O'Dwyer    front_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
30106e2b737SArthur O'Dwyer    front_insert_iterator& operator*();  // constexpr in C++20
30206e2b737SArthur O'Dwyer    front_insert_iterator& operator++();  // constexpr in C++20
30306e2b737SArthur O'Dwyer    front_insert_iterator  operator++(int);  // constexpr in C++20
3043e519524SHoward Hinnant};
3053e519524SHoward Hinnant
30606e2b737SArthur O'Dwyertemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x);  // constexpr in C++20
3073e519524SHoward Hinnant
3083e519524SHoward Hinnanttemplate <class Container>
3093e519524SHoward Hinnantclass insert_iterator
31041bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
3113e519524SHoward Hinnant{
3123e519524SHoward Hinnantprotected:
3133e519524SHoward Hinnant    Container* container;
3143e519524SHoward Hinnant    typename Container::iterator iter;
3153e519524SHoward Hinnantpublic:
3163e519524SHoward Hinnant    typedef Container              container_type;
3173e519524SHoward Hinnant    typedef void                   value_type;
31841bdf64dSLouis Dionne    typedef void                   difference_type; // until C++20
31941bdf64dSLouis Dionne    typedef ptrdiff_t              difference_type; // since C++20
3208892b4eeSEric Fiselier    typedef void                   reference;
3213e519524SHoward Hinnant    typedef void                   pointer;
3223e519524SHoward Hinnant
32306e2b737SArthur O'Dwyer    insert_iterator(Container& x, typename Container::iterator i);  // constexpr in C++20
32406e2b737SArthur O'Dwyer    insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
32506e2b737SArthur O'Dwyer    insert_iterator& operator*();  // constexpr in C++20
32606e2b737SArthur O'Dwyer    insert_iterator& operator++();  // constexpr in C++20
32706e2b737SArthur O'Dwyer    insert_iterator& operator++(int);  // constexpr in C++20
3283e519524SHoward Hinnant};
3293e519524SHoward Hinnant
3303e519524SHoward Hinnanttemplate <class Container, class Iterator>
33106e2b737SArthur O'Dwyerinsert_iterator<Container> inserter(Container& x, Iterator i);  // constexpr in C++20
3323e519524SHoward Hinnant
333947ce6b5SMarshall Clowtemplate <class Iterator>
334947ce6b5SMarshall Clowclass move_iterator {
335947ce6b5SMarshall Clowpublic:
336947ce6b5SMarshall Clow    typedef Iterator                                              iterator_type;
337947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::difference_type   difference_type;
338947ce6b5SMarshall Clow    typedef Iterator                                              pointer;
339947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::value_type        value_type;
340947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
341947ce6b5SMarshall Clow    typedef value_type&&                                          reference;
342947ce6b5SMarshall Clow
343720ef472SMarshall Clow    constexpr move_iterator();  // all the constexprs are in C++17
344720ef472SMarshall Clow    constexpr explicit move_iterator(Iterator i);
345720ef472SMarshall Clow    template <class U>
346720ef472SMarshall Clow      constexpr move_iterator(const move_iterator<U>& u);
347720ef472SMarshall Clow    template <class U>
348720ef472SMarshall Clow      constexpr move_iterator& operator=(const move_iterator<U>& u);
349720ef472SMarshall Clow    constexpr iterator_type base() const;
350720ef472SMarshall Clow    constexpr reference operator*() const;
351720ef472SMarshall Clow    constexpr pointer operator->() const;
352720ef472SMarshall Clow    constexpr move_iterator& operator++();
353720ef472SMarshall Clow    constexpr move_iterator operator++(int);
354720ef472SMarshall Clow    constexpr move_iterator& operator--();
355720ef472SMarshall Clow    constexpr move_iterator operator--(int);
356720ef472SMarshall Clow    constexpr move_iterator operator+(difference_type n) const;
357720ef472SMarshall Clow    constexpr move_iterator& operator+=(difference_type n);
358720ef472SMarshall Clow    constexpr move_iterator operator-(difference_type n) const;
359720ef472SMarshall Clow    constexpr move_iterator& operator-=(difference_type n);
360720ef472SMarshall Clow    constexpr unspecified operator[](difference_type n) const;
361947ce6b5SMarshall Clowprivate:
362947ce6b5SMarshall Clow    Iterator current; // exposition only
363947ce6b5SMarshall Clow};
364947ce6b5SMarshall Clow
365947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
366720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
367947ce6b5SMarshall Clowoperator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
368947ce6b5SMarshall Clow
369947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
370720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
371947ce6b5SMarshall Clowoperator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
372947ce6b5SMarshall Clow
373947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
374720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
375947ce6b5SMarshall Clowoperator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
376947ce6b5SMarshall Clow
377947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
378720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
379947ce6b5SMarshall Clowoperator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
380947ce6b5SMarshall Clow
381947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
382720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
383947ce6b5SMarshall Clowoperator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
384947ce6b5SMarshall Clow
385947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
386720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
387947ce6b5SMarshall Clowoperator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
388947ce6b5SMarshall Clow
389947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
390720ef472SMarshall Clowconstexpr auto   // constexpr in C++17
391947ce6b5SMarshall Clowoperator-(const move_iterator<Iterator1>& x,
392947ce6b5SMarshall Clow          const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
393947ce6b5SMarshall Clow
394947ce6b5SMarshall Clowtemplate <class Iterator>
395720ef472SMarshall Clowconstexpr move_iterator<Iterator> operator+(   // constexpr in C++17
396720ef472SMarshall Clow            typename move_iterator<Iterator>::difference_type n,
397947ce6b5SMarshall Clow            const move_iterator<Iterator>& x);
398947ce6b5SMarshall Clow
399720ef472SMarshall Clowtemplate <class Iterator>   // constexpr in C++17
400720ef472SMarshall Clowconstexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
401947ce6b5SMarshall Clow
402065cf3f9Szoecarver// [default.sentinel], default sentinel
403065cf3f9Szoecarverstruct default_sentinel_t;
404065cf3f9Szoecarverinline constexpr default_sentinel_t default_sentinel{};
405947ce6b5SMarshall Clow
406*8a48e6ddSzoecarver// [iterators.counted], counted iterators
407*8a48e6ddSzoecarvertemplate<input_or_output_iterator I> class counted_iterator;
408*8a48e6ddSzoecarver
409*8a48e6ddSzoecarvertemplate<input_iterator I>
410*8a48e6ddSzoecarver  requires see below
411*8a48e6ddSzoecarver  struct iterator_traits<counted_iterator<I>>;
412*8a48e6ddSzoecarver
4133e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
4143e519524SHoward Hinnantclass istream_iterator
4151055cb91SLouis Dionne    : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
4163e519524SHoward Hinnant{
4173e519524SHoward Hinnantpublic:
41841bdf64dSLouis Dionne    typedef input_iterator_tag           iterator_category;
41941bdf64dSLouis Dionne    typedef T                            value_type;
42041bdf64dSLouis Dionne    typedef Distance                     difference_type;
42141bdf64dSLouis Dionne    typedef const T*                     pointer;
42241bdf64dSLouis Dionne    typedef const T&                     reference;
42341bdf64dSLouis Dionne
4243e519524SHoward Hinnant    typedef charT                        char_type;
4253e519524SHoward Hinnant    typedef traits                       traits_type;
4263e519524SHoward Hinnant    typedef basic_istream<charT, traits> istream_type;
4273e519524SHoward Hinnant
42860d5e0e0SMarshall Clow    constexpr istream_iterator();
4293e519524SHoward Hinnant    istream_iterator(istream_type& s);
4303e519524SHoward Hinnant    istream_iterator(const istream_iterator& x);
4313e519524SHoward Hinnant    ~istream_iterator();
4323e519524SHoward Hinnant
4333e519524SHoward Hinnant    const T& operator*() const;
4343e519524SHoward Hinnant    const T* operator->() const;
4353e519524SHoward Hinnant    istream_iterator& operator++();
4363e519524SHoward Hinnant    istream_iterator  operator++(int);
4373e519524SHoward Hinnant};
4383e519524SHoward Hinnant
4393e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
4403e519524SHoward Hinnantbool operator==(const istream_iterator<T,charT,traits,Distance>& x,
4413e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
4423e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
4433e519524SHoward Hinnantbool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
4443e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
4453e519524SHoward Hinnant
4463e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT> >
4473e519524SHoward Hinnantclass ostream_iterator
4481055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
4493e519524SHoward Hinnant{
4503e519524SHoward Hinnantpublic:
45141bdf64dSLouis Dionne    typedef output_iterator_tag         iterator_category;
45241bdf64dSLouis Dionne    typedef void                        value_type;
45341bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
45441bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
45541bdf64dSLouis Dionne    typedef void                        pointer;
45641bdf64dSLouis Dionne    typedef void                        reference;
45741bdf64dSLouis Dionne
4583e519524SHoward Hinnant    typedef charT char_type;
4593e519524SHoward Hinnant    typedef traits traits_type;
4603e519524SHoward Hinnant    typedef basic_ostream<charT,traits> ostream_type;
4613e519524SHoward Hinnant
4623e519524SHoward Hinnant    ostream_iterator(ostream_type& s);
4633e519524SHoward Hinnant    ostream_iterator(ostream_type& s, const charT* delimiter);
4643e519524SHoward Hinnant    ostream_iterator(const ostream_iterator& x);
4653e519524SHoward Hinnant    ~ostream_iterator();
4663e519524SHoward Hinnant    ostream_iterator& operator=(const T& value);
4673e519524SHoward Hinnant
4683e519524SHoward Hinnant    ostream_iterator& operator*();
4693e519524SHoward Hinnant    ostream_iterator& operator++();
4703e519524SHoward Hinnant    ostream_iterator& operator++(int);
4713e519524SHoward Hinnant};
4723e519524SHoward Hinnant
4733e519524SHoward Hinnanttemplate<class charT, class traits = char_traits<charT> >
4743e519524SHoward Hinnantclass istreambuf_iterator
47541bdf64dSLouis Dionne    : public iterator<input_iterator_tag, charT, traits::off_type, unspecified, charT> // until C++17
4763e519524SHoward Hinnant{
4773e519524SHoward Hinnantpublic:
47841bdf64dSLouis Dionne    typedef input_iterator_tag              iterator_category;
47941bdf64dSLouis Dionne    typedef charT                           value_type;
48041bdf64dSLouis Dionne    typedef traits::off_type                difference_type;
48141bdf64dSLouis Dionne    typedef unspecified                     pointer;
48241bdf64dSLouis Dionne    typedef charT                           reference;
48341bdf64dSLouis Dionne
4843e519524SHoward Hinnant    typedef charT                           char_type;
4853e519524SHoward Hinnant    typedef traits                          traits_type;
48641bdf64dSLouis Dionne    typedef traits::int_type                int_type;
4873e519524SHoward Hinnant    typedef basic_streambuf<charT, traits>  streambuf_type;
4883e519524SHoward Hinnant    typedef basic_istream<charT, traits>    istream_type;
4893e519524SHoward Hinnant
4908e882dcbSHoward Hinnant    istreambuf_iterator() noexcept;
4918e882dcbSHoward Hinnant    istreambuf_iterator(istream_type& s) noexcept;
4928e882dcbSHoward Hinnant    istreambuf_iterator(streambuf_type* s) noexcept;
4938e882dcbSHoward Hinnant    istreambuf_iterator(a-private-type) noexcept;
4943e519524SHoward Hinnant
4953e519524SHoward Hinnant    charT                operator*() const;
4963e519524SHoward Hinnant    pointer operator->() const;
4973e519524SHoward Hinnant    istreambuf_iterator& operator++();
4983e519524SHoward Hinnant    a-private-type       operator++(int);
4993e519524SHoward Hinnant
5003e519524SHoward Hinnant    bool equal(const istreambuf_iterator& b) const;
5013e519524SHoward Hinnant};
5023e519524SHoward Hinnant
5033e519524SHoward Hinnanttemplate <class charT, class traits>
5043e519524SHoward Hinnantbool operator==(const istreambuf_iterator<charT,traits>& a,
5053e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
5063e519524SHoward Hinnanttemplate <class charT, class traits>
5073e519524SHoward Hinnantbool operator!=(const istreambuf_iterator<charT,traits>& a,
5083e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
5093e519524SHoward Hinnant
5103e519524SHoward Hinnanttemplate <class charT, class traits = char_traits<charT> >
5113e519524SHoward Hinnantclass ostreambuf_iterator
5121055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
5133e519524SHoward Hinnant{
5143e519524SHoward Hinnantpublic:
51541bdf64dSLouis Dionne    typedef output_iterator_tag            iterator_category;
51641bdf64dSLouis Dionne    typedef void                           value_type;
51741bdf64dSLouis Dionne    typedef void                           difference_type; // until C++20
51841bdf64dSLouis Dionne    typedef ptrdiff_t                      difference_type; // since C++20
51941bdf64dSLouis Dionne    typedef void                           pointer;
52041bdf64dSLouis Dionne    typedef void                           reference;
52141bdf64dSLouis Dionne
5223e519524SHoward Hinnant    typedef charT                          char_type;
5233e519524SHoward Hinnant    typedef traits                         traits_type;
5243e519524SHoward Hinnant    typedef basic_streambuf<charT, traits> streambuf_type;
5253e519524SHoward Hinnant    typedef basic_ostream<charT, traits>   ostream_type;
5263e519524SHoward Hinnant
5278e882dcbSHoward Hinnant    ostreambuf_iterator(ostream_type& s) noexcept;
5288e882dcbSHoward Hinnant    ostreambuf_iterator(streambuf_type* s) noexcept;
5293e519524SHoward Hinnant    ostreambuf_iterator& operator=(charT c);
5303e519524SHoward Hinnant    ostreambuf_iterator& operator*();
5313e519524SHoward Hinnant    ostreambuf_iterator& operator++();
5323e519524SHoward Hinnant    ostreambuf_iterator& operator++(int);
5338e882dcbSHoward Hinnant    bool failed() const noexcept;
5343e519524SHoward Hinnant};
5353e519524SHoward Hinnant
536020b623aSMarshall Clowtemplate <class C> constexpr auto begin(C& c) -> decltype(c.begin());
537020b623aSMarshall Clowtemplate <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
538020b623aSMarshall Clowtemplate <class C> constexpr auto end(C& c) -> decltype(c.end());
539020b623aSMarshall Clowtemplate <class C> constexpr auto end(const C& c) -> decltype(c.end());
540020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* begin(T (&array)[N]);
541020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* end(T (&array)[N]);
5423e519524SHoward Hinnant
543020b623aSMarshall Clowtemplate <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c));        // C++14
544020b623aSMarshall Clowtemplate <class C> auto constexpr cend(const C& c) -> decltype(std::end(c));            // C++14
545020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
546020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
547020b623aSMarshall Clowtemplate <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
548020b623aSMarshall Clowtemplate <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
549020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
550020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il);   // C++14
551020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
552020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
553020b623aSMarshall Clowtemplate <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
554020b623aSMarshall Clowtemplate <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
5551e548c72SMarshall Clow
556ad755104SMarshall Clow// 24.8, container access:
557ad755104SMarshall Clowtemplate <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
558ad755104SMarshall Clowtemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
5597d3986eaSMarshall Clow
5607d3986eaSMarshall Clowtemplate <class C> constexpr auto ssize(const C& c)
5617d3986eaSMarshall Clow    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;                    // C++20
5627d3986eaSMarshall Clowtemplate <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
5637d3986eaSMarshall Clow
564ad755104SMarshall Clowtemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
565ad755104SMarshall Clowtemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
566ad755104SMarshall Clowtemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
567ad755104SMarshall Clowtemplate <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
568ad755104SMarshall Clowtemplate <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
569ad755104SMarshall Clowtemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
570ad755104SMarshall Clowtemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
571ad755104SMarshall Clow
5723e519524SHoward Hinnant}  // std
5733e519524SHoward Hinnant
5743e519524SHoward Hinnant*/
5753e519524SHoward Hinnant
5763e519524SHoward Hinnant#include <__config>
5775f51fb34SArthur O'Dwyer#include <__debug>
578c204c130SMarshall Clow#include <__functional_base>
5798517a26dSChristopher Di Bella#include <__iterator/access.h>
58036d0fdf9SChristopher Di Bella#include <__iterator/advance.h>
581f32f3db9SLouis Dionne#include <__iterator/back_insert_iterator.h>
5821a29403dSzoecarver#include <__iterator/common_iterator.h>
58357ebf3d0SLouis Dionne#include <__iterator/concepts.h>
584*8a48e6ddSzoecarver#include <__iterator/counted_iterator.h>
5858517a26dSChristopher Di Bella#include <__iterator/data.h>
586065cf3f9Szoecarver#include <__iterator/default_sentinel.h>
5878517a26dSChristopher Di Bella#include <__iterator/distance.h>
5888517a26dSChristopher Di Bella#include <__iterator/empty.h>
5898517a26dSChristopher Di Bella#include <__iterator/erase_if_container.h>
590f32f3db9SLouis Dionne#include <__iterator/front_insert_iterator.h>
591e0adf7e0Szoecarver#include <__iterator/incrementable_traits.h>
592f32f3db9SLouis Dionne#include <__iterator/insert_iterator.h>
593f32f3db9SLouis Dionne#include <__iterator/istreambuf_iterator.h>
5948517a26dSChristopher Di Bella#include <__iterator/istream_iterator.h>
5958517a26dSChristopher Di Bella#include <__iterator/iterator.h>
5968517a26dSChristopher Di Bella#include <__iterator/iterator_traits.h>
59797e383aaSLouis Dionne#include <__iterator/iter_move.h>
59840d6d2c4Szoecarver#include <__iterator/iter_swap.h>
599f32f3db9SLouis Dionne#include <__iterator/move_iterator.h>
600857fa7b7SChristopher Di Bella#include <__iterator/next.h>
601f32f3db9SLouis Dionne#include <__iterator/ostreambuf_iterator.h>
6028517a26dSChristopher Di Bella#include <__iterator/ostream_iterator.h>
6030dc7fd1bSChristopher Di Bella#include <__iterator/prev.h>
60458b29a4eSLouis Dionne#include <__iterator/projected.h>
605e0adf7e0Szoecarver#include <__iterator/readable_traits.h>
6068517a26dSChristopher Di Bella#include <__iterator/reverse_access.h>
607f32f3db9SLouis Dionne#include <__iterator/reverse_iterator.h>
6088517a26dSChristopher Di Bella#include <__iterator/size.h>
609f32f3db9SLouis Dionne#include <__iterator/wrap_iter.h>
610f992cfbaSLouis Dionne#include <__memory/addressof.h>
611d41c6d51SArthur O'Dwyer#include <__memory/pointer_traits.h>
6126adbc83eSChristopher Di Bella#include <__utility/forward.h>
6135f51fb34SArthur O'Dwyer#include <compare>
6145f51fb34SArthur O'Dwyer#include <concepts> // Mandated by the Standard.
6155f51fb34SArthur O'Dwyer#include <cstddef>
6165f51fb34SArthur O'Dwyer#include <initializer_list>
6175f51fb34SArthur O'Dwyer#include <type_traits>
618f56972e2SMarshall Clow#include <version>
619b5c63a2eSHoward Hinnant
620073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6213e519524SHoward Hinnant#pragma GCC system_header
622073458b1SHoward Hinnant#endif
6233e519524SHoward Hinnant
6243e519524SHoward Hinnant#endif // _LIBCPP_ITERATOR
625