13e519524SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
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
139e65d3760SKonstantin Varlamov// [alg.req.ind.copy], concept indirectly_copyable
140e65d3760SKonstantin Varlamovtemplate<class In, class Out>
141e65d3760SKonstantin Varlamov  concept indirectly_copyable = see below;                  // since C++20
142e65d3760SKonstantin Varlamov
143e65d3760SKonstantin Varlamovtemplate<class In, class Out>
144e65d3760SKonstantin Varlamov  concept indirectly_copyable_storable = see below;         // since C++20
145e65d3760SKonstantin Varlamov
146edc1f0c1Szoecarver// [alg.req.ind.swap], concept indirectly_swappable
147edc1f0c1Szoecarvertemplate<class I1, class I2 = I1>
148edc1f0c1Szoecarver  concept indirectly_swappable = see below;                // since C++20
149edc1f0c1Szoecarver
1506d722801SNikolas Klausertemplate<class I1, class I2, class R, class P1 = identity,
1516d722801SNikolas Klauser         class P2 = identity>
1526d722801SNikolas Klauser  concept indirectly_comparable =
1536d722801SNikolas Klauser    indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>; // since C++20
1546d722801SNikolas Klauser
1551a29403dSzoecarvertemplate<input_or_output_iterator I, sentinel_for<I> S>
1561a29403dSzoecarver  requires (!same_as<I, S> && copyable<I>)
1571a29403dSzoecarverclass common_iterator;                                     // since C++20
1581a29403dSzoecarver
1593e519524SHoward Hinnanttemplate<class Category, class T, class Distance = ptrdiff_t,
1603e519524SHoward Hinnant         class Pointer = T*, class Reference = T&>
1611055cb91SLouis Dionnestruct iterator                                            // deprecated in C++17
1623e519524SHoward Hinnant{
1633e519524SHoward Hinnant    typedef T         value_type;
1643e519524SHoward Hinnant    typedef Distance  difference_type;
1653e519524SHoward Hinnant    typedef Pointer   pointer;
1663e519524SHoward Hinnant    typedef Reference reference;
1673e519524SHoward Hinnant    typedef Category  iterator_category;
1683e519524SHoward Hinnant};
1693e519524SHoward Hinnant
1703e519524SHoward Hinnantstruct input_iterator_tag  {};
1713e519524SHoward Hinnantstruct output_iterator_tag {};
1723e519524SHoward Hinnantstruct forward_iterator_tag       : public input_iterator_tag         {};
1733e519524SHoward Hinnantstruct bidirectional_iterator_tag : public forward_iterator_tag       {};
1743e519524SHoward Hinnantstruct random_access_iterator_tag : public bidirectional_iterator_tag {};
175f681d7d5SKonstantin Varlamovstruct contiguous_iterator_tag    : public random_access_iterator_tag {};
1763e519524SHoward Hinnant
177f51ee632SMarshall Clow// 27.4.3, iterator operations
17812b01ab7SLouis Dionnetemplate <class InputIterator, class Distance>  // constexpr in C++17
17912b01ab7SLouis Dionne  constexpr void advance(InputIterator& i, Distance n);
1803e519524SHoward Hinnant
181f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
182f51ee632SMarshall Clow  constexpr typename iterator_traits<InputIterator>::difference_type
1833e519524SHoward Hinnant    distance(InputIterator first, InputIterator last);
1843e519524SHoward Hinnant
185f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
186f51ee632SMarshall Clow  constexpr InputIterator next(InputIterator x,
187f51ee632SMarshall Clowtypename iterator_traits<InputIterator>::difference_type n = 1);
188f51ee632SMarshall Clow
189f51ee632SMarshall Clowtemplate <class BidirectionalIterator>  // constexpr in C++17
190f51ee632SMarshall Clow  constexpr BidirectionalIterator prev(BidirectionalIterator x,
191f51ee632SMarshall Clow    typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
192f51ee632SMarshall Clow
19336d0fdf9SChristopher Di Bella// [range.iter.ops], range iterator operations
19436d0fdf9SChristopher Di Bellanamespace ranges {
19536d0fdf9SChristopher Di Bella  // [range.iter.op.advance], ranges::advance
19636d0fdf9SChristopher Di Bella  template<input_or_output_iterator I>
19736d0fdf9SChristopher Di Bella    constexpr void advance(I& i, iter_difference_t<I> n);                          // since C++20
19836d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
19936d0fdf9SChristopher Di Bella    constexpr void advance(I& i, S bound);                                         // since C++20
20036d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
20136d0fdf9SChristopher Di Bella    constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound); // since C++20
20236d0fdf9SChristopher Di Bella}
20336d0fdf9SChristopher Di Bella
2043e519524SHoward Hinnanttemplate <class Iterator>
2053e519524SHoward Hinnantclass reverse_iterator
2061055cb91SLouis Dionne    : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17
2073e519524SHoward Hinnant                      typename iterator_traits<Iterator>::value_type,
2083e519524SHoward Hinnant                      typename iterator_traits<Iterator>::difference_type,
2093e519524SHoward Hinnant                      typename iterator_traits<Iterator>::pointer,
2103e519524SHoward Hinnant                      typename iterator_traits<Iterator>::reference>
2113e519524SHoward Hinnant{
2123e519524SHoward Hinnantprotected:
2133e519524SHoward Hinnant    Iterator current;
2143e519524SHoward Hinnantpublic:
2153e519524SHoward Hinnant    typedef Iterator                                            iterator_type;
2163e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::difference_type difference_type;
2173e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::reference       reference;
2183e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::pointer         pointer;
2193e519524SHoward Hinnant
2201b8f260eSMarshall Clow    constexpr reverse_iterator();
2211b8f260eSMarshall Clow    constexpr explicit reverse_iterator(Iterator x);
2221b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
2231b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
2241b8f260eSMarshall Clow    constexpr Iterator base() const;
2251b8f260eSMarshall Clow    constexpr reference operator*() const;
2261b8f260eSMarshall Clow    constexpr pointer   operator->() const;
2271b8f260eSMarshall Clow    constexpr reverse_iterator& operator++();
2281b8f260eSMarshall Clow    constexpr reverse_iterator  operator++(int);
2291b8f260eSMarshall Clow    constexpr reverse_iterator& operator--();
2301b8f260eSMarshall Clow    constexpr reverse_iterator  operator--(int);
2311b8f260eSMarshall Clow    constexpr reverse_iterator  operator+ (difference_type n) const;
2321b8f260eSMarshall Clow    constexpr reverse_iterator& operator+=(difference_type n);
2331b8f260eSMarshall Clow    constexpr reverse_iterator  operator- (difference_type n) const;
2341b8f260eSMarshall Clow    constexpr reverse_iterator& operator-=(difference_type n);
2351b8f260eSMarshall Clow    constexpr reference         operator[](difference_type n) const;
2363e519524SHoward Hinnant};
2373e519524SHoward Hinnant
2383e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2391b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2403e519524SHoward Hinnantoperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2413e519524SHoward Hinnant
2423e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2431b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2443e519524SHoward Hinnantoperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2453e519524SHoward Hinnant
2463e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2471b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2483e519524SHoward Hinnantoperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2493e519524SHoward Hinnant
2503e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2511b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2523e519524SHoward Hinnantoperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2533e519524SHoward Hinnant
2543e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2551b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2563e519524SHoward Hinnantoperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2573e519524SHoward Hinnant
2583e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2591b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2603e519524SHoward Hinnantoperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2613e519524SHoward Hinnant
2623e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2631b8f260eSMarshall Clowconstexpr auto
264947ce6b5SMarshall Clowoperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
2651b8f260eSMarshall Clow-> decltype(__y.base() - __x.base());   // constexpr in C++17
2663e519524SHoward Hinnant
2673e519524SHoward Hinnanttemplate <class Iterator>
2681b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator>
2691b8f260eSMarshall Clowoperator+(typename reverse_iterator<Iterator>::difference_type n,
2701b8f260eSMarshall Clow          const reverse_iterator<Iterator>& x);   // constexpr in C++17
2713e519524SHoward Hinnant
2721b8f260eSMarshall Clowtemplate <class Iterator>
2731b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
2746a640a18SMarshall Clow
2753e519524SHoward Hinnanttemplate <class Container>
2763e519524SHoward Hinnantclass back_insert_iterator
27741bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
2783e519524SHoward Hinnant{
2793e519524SHoward Hinnantprotected:
2803e519524SHoward Hinnant    Container* container;
2813e519524SHoward Hinnantpublic:
2823e519524SHoward Hinnant    typedef Container                   container_type;
2833e519524SHoward Hinnant    typedef void                        value_type;
28441bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
28541bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
2868892b4eeSEric Fiselier    typedef void                        reference;
2873e519524SHoward Hinnant    typedef void                        pointer;
2883e519524SHoward Hinnant
28906e2b737SArthur O'Dwyer    explicit back_insert_iterator(Container& x);  // constexpr in C++20
29006e2b737SArthur O'Dwyer    back_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
29106e2b737SArthur O'Dwyer    back_insert_iterator& operator*();  // constexpr in C++20
29206e2b737SArthur O'Dwyer    back_insert_iterator& operator++();  // constexpr in C++20
29306e2b737SArthur O'Dwyer    back_insert_iterator  operator++(int);  // constexpr in C++20
2943e519524SHoward Hinnant};
2953e519524SHoward Hinnant
29606e2b737SArthur O'Dwyertemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x);  // constexpr in C++20
2973e519524SHoward Hinnant
2983e519524SHoward Hinnanttemplate <class Container>
2993e519524SHoward Hinnantclass front_insert_iterator
30041bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
3013e519524SHoward Hinnant{
3023e519524SHoward Hinnantprotected:
3033e519524SHoward Hinnant    Container* container;
3043e519524SHoward Hinnantpublic:
3053e519524SHoward Hinnant    typedef Container                    container_type;
3063e519524SHoward Hinnant    typedef void                         value_type;
30741bdf64dSLouis Dionne    typedef void                         difference_type; // until C++20
30841bdf64dSLouis Dionne    typedef ptrdiff_t                    difference_type; // since C++20
3098892b4eeSEric Fiselier    typedef void                         reference;
3103e519524SHoward Hinnant    typedef void                         pointer;
3113e519524SHoward Hinnant
31206e2b737SArthur O'Dwyer    explicit front_insert_iterator(Container& x);  // constexpr in C++20
31306e2b737SArthur O'Dwyer    front_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
31406e2b737SArthur O'Dwyer    front_insert_iterator& operator*();  // constexpr in C++20
31506e2b737SArthur O'Dwyer    front_insert_iterator& operator++();  // constexpr in C++20
31606e2b737SArthur O'Dwyer    front_insert_iterator  operator++(int);  // constexpr in C++20
3173e519524SHoward Hinnant};
3183e519524SHoward Hinnant
31906e2b737SArthur O'Dwyertemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x);  // constexpr in C++20
3203e519524SHoward Hinnant
3213e519524SHoward Hinnanttemplate <class Container>
3223e519524SHoward Hinnantclass insert_iterator
32341bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
3243e519524SHoward Hinnant{
3253e519524SHoward Hinnantprotected:
3263e519524SHoward Hinnant    Container* container;
3273e519524SHoward Hinnant    typename Container::iterator iter;
3283e519524SHoward Hinnantpublic:
3293e519524SHoward Hinnant    typedef Container              container_type;
3303e519524SHoward Hinnant    typedef void                   value_type;
33141bdf64dSLouis Dionne    typedef void                   difference_type; // until C++20
33241bdf64dSLouis Dionne    typedef ptrdiff_t              difference_type; // since C++20
3338892b4eeSEric Fiselier    typedef void                   reference;
3343e519524SHoward Hinnant    typedef void                   pointer;
3353e519524SHoward Hinnant
33606e2b737SArthur O'Dwyer    insert_iterator(Container& x, typename Container::iterator i);  // constexpr in C++20
33706e2b737SArthur O'Dwyer    insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
33806e2b737SArthur O'Dwyer    insert_iterator& operator*();  // constexpr in C++20
33906e2b737SArthur O'Dwyer    insert_iterator& operator++();  // constexpr in C++20
34006e2b737SArthur O'Dwyer    insert_iterator& operator++(int);  // constexpr in C++20
3413e519524SHoward Hinnant};
3423e519524SHoward Hinnant
3433e519524SHoward Hinnanttemplate <class Container, class Iterator>
34406e2b737SArthur O'Dwyerinsert_iterator<Container> inserter(Container& x, Iterator i);  // constexpr in C++20
3453e519524SHoward Hinnant
346947ce6b5SMarshall Clowtemplate <class Iterator>
347947ce6b5SMarshall Clowclass move_iterator {
348947ce6b5SMarshall Clowpublic:
349947ce6b5SMarshall Clow    typedef Iterator                                              iterator_type;
350947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::difference_type   difference_type;
351947ce6b5SMarshall Clow    typedef Iterator                                              pointer;
352947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::value_type        value_type;
353947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
354947ce6b5SMarshall Clow    typedef value_type&&                                          reference;
355947ce6b5SMarshall Clow
356720ef472SMarshall Clow    constexpr move_iterator();  // all the constexprs are in C++17
357720ef472SMarshall Clow    constexpr explicit move_iterator(Iterator i);
358720ef472SMarshall Clow    template <class U>
359720ef472SMarshall Clow      constexpr move_iterator(const move_iterator<U>& u);
360720ef472SMarshall Clow    template <class U>
361720ef472SMarshall Clow      constexpr move_iterator& operator=(const move_iterator<U>& u);
362720ef472SMarshall Clow    constexpr iterator_type base() const;
363720ef472SMarshall Clow    constexpr reference operator*() const;
364720ef472SMarshall Clow    constexpr pointer operator->() const;
365720ef472SMarshall Clow    constexpr move_iterator& operator++();
366720ef472SMarshall Clow    constexpr move_iterator operator++(int);
367720ef472SMarshall Clow    constexpr move_iterator& operator--();
368720ef472SMarshall Clow    constexpr move_iterator operator--(int);
369720ef472SMarshall Clow    constexpr move_iterator operator+(difference_type n) const;
370720ef472SMarshall Clow    constexpr move_iterator& operator+=(difference_type n);
371720ef472SMarshall Clow    constexpr move_iterator operator-(difference_type n) const;
372720ef472SMarshall Clow    constexpr move_iterator& operator-=(difference_type n);
373720ef472SMarshall Clow    constexpr unspecified operator[](difference_type n) const;
374947ce6b5SMarshall Clowprivate:
375947ce6b5SMarshall Clow    Iterator current; // exposition only
376947ce6b5SMarshall Clow};
377947ce6b5SMarshall Clow
378947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
379720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
380947ce6b5SMarshall Clowoperator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
381947ce6b5SMarshall Clow
382947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
383720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
384947ce6b5SMarshall Clowoperator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
385947ce6b5SMarshall Clow
386947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
387720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
388947ce6b5SMarshall Clowoperator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
389947ce6b5SMarshall Clow
390947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
391720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
392947ce6b5SMarshall Clowoperator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
393947ce6b5SMarshall Clow
394947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
395720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
396947ce6b5SMarshall Clowoperator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
397947ce6b5SMarshall Clow
398947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
399720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
400947ce6b5SMarshall Clowoperator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
401947ce6b5SMarshall Clow
402947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
403720ef472SMarshall Clowconstexpr auto   // constexpr in C++17
404947ce6b5SMarshall Clowoperator-(const move_iterator<Iterator1>& x,
405947ce6b5SMarshall Clow          const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
406947ce6b5SMarshall Clow
407947ce6b5SMarshall Clowtemplate <class Iterator>
408720ef472SMarshall Clowconstexpr move_iterator<Iterator> operator+(   // constexpr in C++17
409720ef472SMarshall Clow            typename move_iterator<Iterator>::difference_type n,
410947ce6b5SMarshall Clow            const move_iterator<Iterator>& x);
411947ce6b5SMarshall Clow
412720ef472SMarshall Clowtemplate <class Iterator>   // constexpr in C++17
413720ef472SMarshall Clowconstexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
414947ce6b5SMarshall Clow
415065cf3f9Szoecarver// [default.sentinel], default sentinel
416065cf3f9Szoecarverstruct default_sentinel_t;
417065cf3f9Szoecarverinline constexpr default_sentinel_t default_sentinel{};
418947ce6b5SMarshall Clow
4198a48e6ddSzoecarver// [iterators.counted], counted iterators
4208a48e6ddSzoecarvertemplate<input_or_output_iterator I> class counted_iterator;
4218a48e6ddSzoecarver
4228a48e6ddSzoecarvertemplate<input_iterator I>
4238a48e6ddSzoecarver  requires see below
4248a48e6ddSzoecarver  struct iterator_traits<counted_iterator<I>>;
4258a48e6ddSzoecarver
4264ac87e33Szoecarver// [unreachable.sentinel], unreachable sentinel
4274ac87e33Szoecarverstruct unreachable_sentinel_t;
4284ac87e33Szoecarverinline constexpr unreachable_sentinel_t unreachable_sentinel{};
4294ac87e33Szoecarver
4303e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
4313e519524SHoward Hinnantclass istream_iterator
4321055cb91SLouis Dionne    : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
4333e519524SHoward Hinnant{
4343e519524SHoward Hinnantpublic:
43541bdf64dSLouis Dionne    typedef input_iterator_tag           iterator_category;
43641bdf64dSLouis Dionne    typedef T                            value_type;
43741bdf64dSLouis Dionne    typedef Distance                     difference_type;
43841bdf64dSLouis Dionne    typedef const T*                     pointer;
43941bdf64dSLouis Dionne    typedef const T&                     reference;
44041bdf64dSLouis Dionne
4413e519524SHoward Hinnant    typedef charT                        char_type;
4423e519524SHoward Hinnant    typedef traits                       traits_type;
4433e519524SHoward Hinnant    typedef basic_istream<charT, traits> istream_type;
4443e519524SHoward Hinnant
44560d5e0e0SMarshall Clow    constexpr istream_iterator();
4463e519524SHoward Hinnant    istream_iterator(istream_type& s);
4473e519524SHoward Hinnant    istream_iterator(const istream_iterator& x);
4483e519524SHoward Hinnant    ~istream_iterator();
4493e519524SHoward Hinnant
4503e519524SHoward Hinnant    const T& operator*() const;
4513e519524SHoward Hinnant    const T* operator->() const;
4523e519524SHoward Hinnant    istream_iterator& operator++();
4533e519524SHoward Hinnant    istream_iterator  operator++(int);
4543e519524SHoward Hinnant};
4553e519524SHoward Hinnant
4563e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
4573e519524SHoward Hinnantbool operator==(const istream_iterator<T,charT,traits,Distance>& x,
4583e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
4593e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
4603e519524SHoward Hinnantbool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
4613e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
4623e519524SHoward Hinnant
4633e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT> >
4643e519524SHoward Hinnantclass ostream_iterator
4651055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
4663e519524SHoward Hinnant{
4673e519524SHoward Hinnantpublic:
46841bdf64dSLouis Dionne    typedef output_iterator_tag         iterator_category;
46941bdf64dSLouis Dionne    typedef void                        value_type;
47041bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
47141bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
47241bdf64dSLouis Dionne    typedef void                        pointer;
47341bdf64dSLouis Dionne    typedef void                        reference;
47441bdf64dSLouis Dionne
4753e519524SHoward Hinnant    typedef charT char_type;
4763e519524SHoward Hinnant    typedef traits traits_type;
4773e519524SHoward Hinnant    typedef basic_ostream<charT,traits> ostream_type;
4783e519524SHoward Hinnant
4793e519524SHoward Hinnant    ostream_iterator(ostream_type& s);
4803e519524SHoward Hinnant    ostream_iterator(ostream_type& s, const charT* delimiter);
4813e519524SHoward Hinnant    ostream_iterator(const ostream_iterator& x);
4823e519524SHoward Hinnant    ~ostream_iterator();
4833e519524SHoward Hinnant    ostream_iterator& operator=(const T& value);
4843e519524SHoward Hinnant
4853e519524SHoward Hinnant    ostream_iterator& operator*();
4863e519524SHoward Hinnant    ostream_iterator& operator++();
4873e519524SHoward Hinnant    ostream_iterator& operator++(int);
4883e519524SHoward Hinnant};
4893e519524SHoward Hinnant
4903e519524SHoward Hinnanttemplate<class charT, class traits = char_traits<charT> >
4913e519524SHoward Hinnantclass istreambuf_iterator
49241bdf64dSLouis Dionne    : public iterator<input_iterator_tag, charT, traits::off_type, unspecified, charT> // until C++17
4933e519524SHoward Hinnant{
4943e519524SHoward Hinnantpublic:
49541bdf64dSLouis Dionne    typedef input_iterator_tag              iterator_category;
49641bdf64dSLouis Dionne    typedef charT                           value_type;
49741bdf64dSLouis Dionne    typedef traits::off_type                difference_type;
49841bdf64dSLouis Dionne    typedef unspecified                     pointer;
49941bdf64dSLouis Dionne    typedef charT                           reference;
50041bdf64dSLouis Dionne
5013e519524SHoward Hinnant    typedef charT                           char_type;
5023e519524SHoward Hinnant    typedef traits                          traits_type;
50341bdf64dSLouis Dionne    typedef traits::int_type                int_type;
5043e519524SHoward Hinnant    typedef basic_streambuf<charT, traits>  streambuf_type;
5053e519524SHoward Hinnant    typedef basic_istream<charT, traits>    istream_type;
5063e519524SHoward Hinnant
5078e882dcbSHoward Hinnant    istreambuf_iterator() noexcept;
5088e882dcbSHoward Hinnant    istreambuf_iterator(istream_type& s) noexcept;
5098e882dcbSHoward Hinnant    istreambuf_iterator(streambuf_type* s) noexcept;
5108e882dcbSHoward Hinnant    istreambuf_iterator(a-private-type) noexcept;
5113e519524SHoward Hinnant
5123e519524SHoward Hinnant    charT                operator*() const;
5133e519524SHoward Hinnant    pointer operator->() const;
5143e519524SHoward Hinnant    istreambuf_iterator& operator++();
5153e519524SHoward Hinnant    a-private-type       operator++(int);
5163e519524SHoward Hinnant
5173e519524SHoward Hinnant    bool equal(const istreambuf_iterator& b) const;
5183e519524SHoward Hinnant};
5193e519524SHoward Hinnant
5203e519524SHoward Hinnanttemplate <class charT, class traits>
5213e519524SHoward Hinnantbool operator==(const istreambuf_iterator<charT,traits>& a,
5223e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
5233e519524SHoward Hinnanttemplate <class charT, class traits>
5243e519524SHoward Hinnantbool operator!=(const istreambuf_iterator<charT,traits>& a,
5253e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
5263e519524SHoward Hinnant
5273e519524SHoward Hinnanttemplate <class charT, class traits = char_traits<charT> >
5283e519524SHoward Hinnantclass ostreambuf_iterator
5291055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
5303e519524SHoward Hinnant{
5313e519524SHoward Hinnantpublic:
53241bdf64dSLouis Dionne    typedef output_iterator_tag            iterator_category;
53341bdf64dSLouis Dionne    typedef void                           value_type;
53441bdf64dSLouis Dionne    typedef void                           difference_type; // until C++20
53541bdf64dSLouis Dionne    typedef ptrdiff_t                      difference_type; // since C++20
53641bdf64dSLouis Dionne    typedef void                           pointer;
53741bdf64dSLouis Dionne    typedef void                           reference;
53841bdf64dSLouis Dionne
5393e519524SHoward Hinnant    typedef charT                          char_type;
5403e519524SHoward Hinnant    typedef traits                         traits_type;
5413e519524SHoward Hinnant    typedef basic_streambuf<charT, traits> streambuf_type;
5423e519524SHoward Hinnant    typedef basic_ostream<charT, traits>   ostream_type;
5433e519524SHoward Hinnant
5448e882dcbSHoward Hinnant    ostreambuf_iterator(ostream_type& s) noexcept;
5458e882dcbSHoward Hinnant    ostreambuf_iterator(streambuf_type* s) noexcept;
5463e519524SHoward Hinnant    ostreambuf_iterator& operator=(charT c);
5473e519524SHoward Hinnant    ostreambuf_iterator& operator*();
5483e519524SHoward Hinnant    ostreambuf_iterator& operator++();
5493e519524SHoward Hinnant    ostreambuf_iterator& operator++(int);
5508e882dcbSHoward Hinnant    bool failed() const noexcept;
5513e519524SHoward Hinnant};
5523e519524SHoward Hinnant
553020b623aSMarshall Clowtemplate <class C> constexpr auto begin(C& c) -> decltype(c.begin());
554020b623aSMarshall Clowtemplate <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
555020b623aSMarshall Clowtemplate <class C> constexpr auto end(C& c) -> decltype(c.end());
556020b623aSMarshall Clowtemplate <class C> constexpr auto end(const C& c) -> decltype(c.end());
557020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* begin(T (&array)[N]);
558020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* end(T (&array)[N]);
5593e519524SHoward Hinnant
560020b623aSMarshall Clowtemplate <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c));        // C++14
561020b623aSMarshall Clowtemplate <class C> auto constexpr cend(const C& c) -> decltype(std::end(c));            // C++14
562020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
563020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
564020b623aSMarshall Clowtemplate <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
565020b623aSMarshall Clowtemplate <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
566020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
567020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il);   // C++14
568020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
569020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
570020b623aSMarshall Clowtemplate <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
571020b623aSMarshall Clowtemplate <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
5721e548c72SMarshall Clow
573ad755104SMarshall Clow// 24.8, container access:
574ad755104SMarshall Clowtemplate <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
575ad755104SMarshall Clowtemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
5767d3986eaSMarshall Clow
5777d3986eaSMarshall Clowtemplate <class C> constexpr auto ssize(const C& c)
5787d3986eaSMarshall Clow    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;                    // C++20
5797d3986eaSMarshall Clowtemplate <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
5807d3986eaSMarshall Clow
581ad755104SMarshall Clowtemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
582ad755104SMarshall Clowtemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
583ad755104SMarshall Clowtemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
584ad755104SMarshall Clowtemplate <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
585ad755104SMarshall Clowtemplate <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
586ad755104SMarshall Clowtemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
587ad755104SMarshall Clowtemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
588ad755104SMarshall Clow
5893e519524SHoward Hinnant}  // std
5903e519524SHoward Hinnant
5913e519524SHoward Hinnant*/
5923e519524SHoward Hinnant
5933e519524SHoward Hinnant#include <__config>
5945f51fb34SArthur O'Dwyer#include <__debug>
595c204c130SMarshall Clow#include <__functional_base>
5968517a26dSChristopher Di Bella#include <__iterator/access.h>
59736d0fdf9SChristopher Di Bella#include <__iterator/advance.h>
598f32f3db9SLouis Dionne#include <__iterator/back_insert_iterator.h>
5991a29403dSzoecarver#include <__iterator/common_iterator.h>
60057ebf3d0SLouis Dionne#include <__iterator/concepts.h>
6018a48e6ddSzoecarver#include <__iterator/counted_iterator.h>
6028517a26dSChristopher Di Bella#include <__iterator/data.h>
603065cf3f9Szoecarver#include <__iterator/default_sentinel.h>
6048517a26dSChristopher Di Bella#include <__iterator/distance.h>
6058517a26dSChristopher Di Bella#include <__iterator/empty.h>
6068517a26dSChristopher Di Bella#include <__iterator/erase_if_container.h>
607f32f3db9SLouis Dionne#include <__iterator/front_insert_iterator.h>
608e0adf7e0Szoecarver#include <__iterator/incrementable_traits.h>
6096d722801SNikolas Klauser#include <__iterator/indirectly_comparable.h>
610f32f3db9SLouis Dionne#include <__iterator/insert_iterator.h>
6118517a26dSChristopher Di Bella#include <__iterator/istream_iterator.h>
6124d81a46fSArthur O'Dwyer#include <__iterator/istreambuf_iterator.h>
61397e383aaSLouis Dionne#include <__iterator/iter_move.h>
61440d6d2c4Szoecarver#include <__iterator/iter_swap.h>
6154d81a46fSArthur O'Dwyer#include <__iterator/iterator.h>
6164d81a46fSArthur O'Dwyer#include <__iterator/iterator_traits.h>
617f32f3db9SLouis Dionne#include <__iterator/move_iterator.h>
618857fa7b7SChristopher Di Bella#include <__iterator/next.h>
6198517a26dSChristopher Di Bella#include <__iterator/ostream_iterator.h>
6204d81a46fSArthur O'Dwyer#include <__iterator/ostreambuf_iterator.h>
6210dc7fd1bSChristopher Di Bella#include <__iterator/prev.h>
62258b29a4eSLouis Dionne#include <__iterator/projected.h>
623e0adf7e0Szoecarver#include <__iterator/readable_traits.h>
6248517a26dSChristopher Di Bella#include <__iterator/reverse_access.h>
625f32f3db9SLouis Dionne#include <__iterator/reverse_iterator.h>
6268517a26dSChristopher Di Bella#include <__iterator/size.h>
6274ac87e33Szoecarver#include <__iterator/unreachable_sentinel.h>
628f32f3db9SLouis Dionne#include <__iterator/wrap_iter.h>
629f992cfbaSLouis Dionne#include <__memory/addressof.h>
630d41c6d51SArthur O'Dwyer#include <__memory/pointer_traits.h>
6315f51fb34SArthur O'Dwyer#include <compare>
6325f51fb34SArthur O'Dwyer#include <concepts> // Mandated by the Standard.
6335f51fb34SArthur O'Dwyer#include <cstddef>
6345f51fb34SArthur O'Dwyer#include <initializer_list>
6355f51fb34SArthur O'Dwyer#include <type_traits>
636*ea2206d7SArthur O'Dwyer#include <utility>
637f56972e2SMarshall Clow#include <version>
638b5c63a2eSHoward Hinnant
639073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6403e519524SHoward Hinnant#  pragma GCC system_header
641073458b1SHoward Hinnant#endif
6423e519524SHoward Hinnant
6433e519524SHoward Hinnant#endif // _LIBCPP_ITERATOR
644