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
1558e979460SKonstantin Varlamov// [alg.req.permutable], concept permutable
156eea3d90aSKonstantin Varlamovtemplate<class I>
1578e979460SKonstantin Varlamov  concept permutable = see below;                          // since C++20
158eea3d90aSKonstantin Varlamov
159eea3d90aSKonstantin Varlamov // [alg.req.mergeable], concept mergeable
160eea3d90aSKonstantin Varlamovtemplate<class I1, class I2, class Out,
161eea3d90aSKonstantin Varlamov    class R = ranges::less, class P1 = identity, class P2 = identity>
162eea3d90aSKonstantin Varlamov  concept mergeable = see below;                           // since C++20
163eea3d90aSKonstantin Varlamov
1648e979460SKonstantin Varlamov// [alg.req.sortable], concept sortable
1658e979460SKonstantin Varlamovtemplate<class I, class R = ranges::less, class P = identity>
1668e979460SKonstantin Varlamov  concept sortable = see below;                            // since C++20
1678e979460SKonstantin Varlamov
1681a29403dSzoecarvertemplate<input_or_output_iterator I, sentinel_for<I> S>
1691a29403dSzoecarver  requires (!same_as<I, S> && copyable<I>)
1701a29403dSzoecarverclass common_iterator;                                     // since C++20
1711a29403dSzoecarver
1723e519524SHoward Hinnanttemplate<class Category, class T, class Distance = ptrdiff_t,
1733e519524SHoward Hinnant         class Pointer = T*, class Reference = T&>
1741055cb91SLouis Dionnestruct iterator                                            // deprecated in C++17
1753e519524SHoward Hinnant{
1763e519524SHoward Hinnant    typedef T         value_type;
1773e519524SHoward Hinnant    typedef Distance  difference_type;
1783e519524SHoward Hinnant    typedef Pointer   pointer;
1793e519524SHoward Hinnant    typedef Reference reference;
1803e519524SHoward Hinnant    typedef Category  iterator_category;
1813e519524SHoward Hinnant};
1823e519524SHoward Hinnant
1833e519524SHoward Hinnantstruct input_iterator_tag  {};
1843e519524SHoward Hinnantstruct output_iterator_tag {};
1853e519524SHoward Hinnantstruct forward_iterator_tag       : public input_iterator_tag         {};
1863e519524SHoward Hinnantstruct bidirectional_iterator_tag : public forward_iterator_tag       {};
1873e519524SHoward Hinnantstruct random_access_iterator_tag : public bidirectional_iterator_tag {};
188f681d7d5SKonstantin Varlamovstruct contiguous_iterator_tag    : public random_access_iterator_tag {};
1893e519524SHoward Hinnant
190f51ee632SMarshall Clow// 27.4.3, iterator operations
19112b01ab7SLouis Dionnetemplate <class InputIterator, class Distance>  // constexpr in C++17
19212b01ab7SLouis Dionne  constexpr void advance(InputIterator& i, Distance n);
1933e519524SHoward Hinnant
194f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
195f51ee632SMarshall Clow  constexpr typename iterator_traits<InputIterator>::difference_type
1963e519524SHoward Hinnant    distance(InputIterator first, InputIterator last);
1973e519524SHoward Hinnant
198f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
199f51ee632SMarshall Clow  constexpr InputIterator next(InputIterator x,
200f51ee632SMarshall Clowtypename iterator_traits<InputIterator>::difference_type n = 1);
201f51ee632SMarshall Clow
202f51ee632SMarshall Clowtemplate <class BidirectionalIterator>  // constexpr in C++17
203f51ee632SMarshall Clow  constexpr BidirectionalIterator prev(BidirectionalIterator x,
204f51ee632SMarshall Clow    typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
205f51ee632SMarshall Clow
20636d0fdf9SChristopher Di Bella// [range.iter.ops], range iterator operations
20736d0fdf9SChristopher Di Bellanamespace ranges {
20836d0fdf9SChristopher Di Bella  // [range.iter.op.advance], ranges::advance
20936d0fdf9SChristopher Di Bella  template<input_or_output_iterator I>
21036d0fdf9SChristopher Di Bella    constexpr void advance(I& i, iter_difference_t<I> n);                          // since C++20
21136d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
21236d0fdf9SChristopher Di Bella    constexpr void advance(I& i, S bound);                                         // since C++20
21336d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
21436d0fdf9SChristopher Di Bella    constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound); // since C++20
21536d0fdf9SChristopher Di Bella}
21636d0fdf9SChristopher Di Bella
2173e519524SHoward Hinnanttemplate <class Iterator>
2183e519524SHoward Hinnantclass reverse_iterator
2191055cb91SLouis Dionne    : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17
2203e519524SHoward Hinnant                      typename iterator_traits<Iterator>::value_type,
2213e519524SHoward Hinnant                      typename iterator_traits<Iterator>::difference_type,
2223e519524SHoward Hinnant                      typename iterator_traits<Iterator>::pointer,
2233e519524SHoward Hinnant                      typename iterator_traits<Iterator>::reference>
2243e519524SHoward Hinnant{
2253e519524SHoward Hinnantprotected:
2263e519524SHoward Hinnant    Iterator current;
2273e519524SHoward Hinnantpublic:
228658957c7SKonstantin Varlamov    using iterator_type     = Iterator;
229658957c7SKonstantin Varlamov    using iterator_concept  = see below; // since C++20
230658957c7SKonstantin Varlamov    using iterator_category = typename iterator_traits<Iterator>::iterator_category; // since C++17, until C++20
231658957c7SKonstantin Varlamov    using iterator_category = see below; // since C++20
232658957c7SKonstantin Varlamov    using value_type        = typename iterator_traits<Iterator>::value_type; // since C++17, until C++20
233658957c7SKonstantin Varlamov    using value_type        = iter_value_t<Iterator>; // since C++20
234658957c7SKonstantin Varlamov    using difference_type   = typename iterator_traits<Iterator>::difference_type; // until C++20
235658957c7SKonstantin Varlamov    using difference_type   = iter_difference_t<Iterator>; // since C++20
236658957c7SKonstantin Varlamov    using pointer           = typename iterator_traits<Iterator>::pointer;
237658957c7SKonstantin Varlamov    using reference         = typename iterator_traits<Iterator>::reference; // until C++20
238658957c7SKonstantin Varlamov    using reference         = iter_reference_t<Iterator>; // since C++20
2393e519524SHoward Hinnant
2401b8f260eSMarshall Clow    constexpr reverse_iterator();
2411b8f260eSMarshall Clow    constexpr explicit reverse_iterator(Iterator x);
2421b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
2431b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
2441b8f260eSMarshall Clow    constexpr Iterator base() const;
2451b8f260eSMarshall Clow    constexpr reference operator*() const;
246658957c7SKonstantin Varlamov    constexpr pointer   operator->() const; // until C++20
247658957c7SKonstantin Varlamov    constexpr pointer   operator->() const requires see below; // since C++20
2481b8f260eSMarshall Clow    constexpr reverse_iterator& operator++();
2491b8f260eSMarshall Clow    constexpr reverse_iterator  operator++(int);
2501b8f260eSMarshall Clow    constexpr reverse_iterator& operator--();
2511b8f260eSMarshall Clow    constexpr reverse_iterator  operator--(int);
2521b8f260eSMarshall Clow    constexpr reverse_iterator  operator+ (difference_type n) const;
2531b8f260eSMarshall Clow    constexpr reverse_iterator& operator+=(difference_type n);
2541b8f260eSMarshall Clow    constexpr reverse_iterator  operator- (difference_type n) const;
2551b8f260eSMarshall Clow    constexpr reverse_iterator& operator-=(difference_type n);
256658957c7SKonstantin Varlamov    constexpr unspecified       operator[](difference_type n) const;
257658957c7SKonstantin Varlamov
258658957c7SKonstantin Varlamov    friend constexpr iter_rvalue_reference_t<Iterator>
259658957c7SKonstantin Varlamov      iter_move(const reverse_iterator& i) noexcept(see below);
260658957c7SKonstantin Varlamov    template<indirectly_swappable<Iterator> Iterator2>
261658957c7SKonstantin Varlamov      friend constexpr void
262658957c7SKonstantin Varlamov        iter_swap(const reverse_iterator& x,
263658957c7SKonstantin Varlamov                  const reverse_iterator<Iterator2>& y) noexcept(see below);
2643e519524SHoward Hinnant};
2653e519524SHoward Hinnant
2663e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2671b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2683e519524SHoward Hinnantoperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2693e519524SHoward Hinnant
2703e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2711b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
272658957c7SKonstantin Varlamovoperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2733e519524SHoward Hinnant
2743e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2751b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
276658957c7SKonstantin Varlamovoperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2773e519524SHoward Hinnant
2783e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2791b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2803e519524SHoward Hinnantoperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2813e519524SHoward Hinnant
2823e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2831b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
284658957c7SKonstantin Varlamovoperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2853e519524SHoward Hinnant
2863e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2871b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
288658957c7SKonstantin Varlamovoperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
289658957c7SKonstantin Varlamov
290658957c7SKonstantin Varlamovtemplate<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
291658957c7SKonstantin Varlamov  constexpr compare_three_way_result_t<Iterator1, Iterator2>
292658957c7SKonstantin Varlamov    operator<=>(const reverse_iterator<Iterator1>& x,
293658957c7SKonstantin Varlamov                const reverse_iterator<Iterator2>& y);
2943e519524SHoward Hinnant
2953e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2961b8f260eSMarshall Clowconstexpr auto
297947ce6b5SMarshall Clowoperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
2981b8f260eSMarshall Clow-> decltype(__y.base() - __x.base());   // constexpr in C++17
2993e519524SHoward Hinnant
3003e519524SHoward Hinnanttemplate <class Iterator>
3011b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator>
3021b8f260eSMarshall Clowoperator+(typename reverse_iterator<Iterator>::difference_type n,
3031b8f260eSMarshall Clow          const reverse_iterator<Iterator>& x);   // constexpr in C++17
3043e519524SHoward Hinnant
3051b8f260eSMarshall Clowtemplate <class Iterator>
3061b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
3076a640a18SMarshall Clow
308658957c7SKonstantin Varlamovtemplate<class Iterator1, class Iterator2>
309658957c7SKonstantin Varlamov    requires (!sized_sentinel_for<Iterator1, Iterator2>)
310658957c7SKonstantin Varlamov  inline constexpr bool disable_sized_sentinel_for<reverse_iterator<Iterator1>,
311658957c7SKonstantin Varlamov                                                   reverse_iterator<Iterator2>> = true;
312658957c7SKonstantin Varlamov
3133e519524SHoward Hinnanttemplate <class Container>
3143e519524SHoward Hinnantclass back_insert_iterator
31541bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
3163e519524SHoward Hinnant{
3173e519524SHoward Hinnantprotected:
3183e519524SHoward Hinnant    Container* container;
3193e519524SHoward Hinnantpublic:
3203e519524SHoward Hinnant    typedef Container                   container_type;
3213e519524SHoward Hinnant    typedef void                        value_type;
32241bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
32341bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
3248892b4eeSEric Fiselier    typedef void                        reference;
3253e519524SHoward Hinnant    typedef void                        pointer;
3263e519524SHoward Hinnant
32706e2b737SArthur O'Dwyer    explicit back_insert_iterator(Container& x);  // constexpr in C++20
32806e2b737SArthur O'Dwyer    back_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
32906e2b737SArthur O'Dwyer    back_insert_iterator& operator*();  // constexpr in C++20
33006e2b737SArthur O'Dwyer    back_insert_iterator& operator++();  // constexpr in C++20
33106e2b737SArthur O'Dwyer    back_insert_iterator  operator++(int);  // constexpr in C++20
3323e519524SHoward Hinnant};
3333e519524SHoward Hinnant
33406e2b737SArthur O'Dwyertemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x);  // constexpr in C++20
3353e519524SHoward Hinnant
3363e519524SHoward Hinnanttemplate <class Container>
3373e519524SHoward Hinnantclass front_insert_iterator
33841bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
3393e519524SHoward Hinnant{
3403e519524SHoward Hinnantprotected:
3413e519524SHoward Hinnant    Container* container;
3423e519524SHoward Hinnantpublic:
3433e519524SHoward Hinnant    typedef Container                    container_type;
3443e519524SHoward Hinnant    typedef void                         value_type;
34541bdf64dSLouis Dionne    typedef void                         difference_type; // until C++20
34641bdf64dSLouis Dionne    typedef ptrdiff_t                    difference_type; // since C++20
3478892b4eeSEric Fiselier    typedef void                         reference;
3483e519524SHoward Hinnant    typedef void                         pointer;
3493e519524SHoward Hinnant
35006e2b737SArthur O'Dwyer    explicit front_insert_iterator(Container& x);  // constexpr in C++20
35106e2b737SArthur O'Dwyer    front_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
35206e2b737SArthur O'Dwyer    front_insert_iterator& operator*();  // constexpr in C++20
35306e2b737SArthur O'Dwyer    front_insert_iterator& operator++();  // constexpr in C++20
35406e2b737SArthur O'Dwyer    front_insert_iterator  operator++(int);  // constexpr in C++20
3553e519524SHoward Hinnant};
3563e519524SHoward Hinnant
35706e2b737SArthur O'Dwyertemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x);  // constexpr in C++20
3583e519524SHoward Hinnant
3593e519524SHoward Hinnanttemplate <class Container>
3603e519524SHoward Hinnantclass insert_iterator
36141bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
3623e519524SHoward Hinnant{
3633e519524SHoward Hinnantprotected:
3643e519524SHoward Hinnant    Container* container;
3653e519524SHoward Hinnant    typename Container::iterator iter;
3663e519524SHoward Hinnantpublic:
3673e519524SHoward Hinnant    typedef Container              container_type;
3683e519524SHoward Hinnant    typedef void                   value_type;
36941bdf64dSLouis Dionne    typedef void                   difference_type; // until C++20
37041bdf64dSLouis Dionne    typedef ptrdiff_t              difference_type; // since C++20
3718892b4eeSEric Fiselier    typedef void                   reference;
3723e519524SHoward Hinnant    typedef void                   pointer;
3733e519524SHoward Hinnant
37406e2b737SArthur O'Dwyer    insert_iterator(Container& x, typename Container::iterator i);  // constexpr in C++20
37506e2b737SArthur O'Dwyer    insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
37606e2b737SArthur O'Dwyer    insert_iterator& operator*();  // constexpr in C++20
37706e2b737SArthur O'Dwyer    insert_iterator& operator++();  // constexpr in C++20
37806e2b737SArthur O'Dwyer    insert_iterator& operator++(int);  // constexpr in C++20
3793e519524SHoward Hinnant};
3803e519524SHoward Hinnant
3812151b3d0SKonstantin Varlamovtemplate <class Container>
3822151b3d0SKonstantin Varlamovinsert_iterator<Container> inserter(Container& x, typename Container::iterator i);  // until C++20
3832151b3d0SKonstantin Varlamovtemplate <class Container>
3842151b3d0SKonstantin Varlamovconstexpr insert_iterator<Container> inserter(Container& x, ranges::iterator_t<Container> i);  // since C++20
3853e519524SHoward Hinnant
386947ce6b5SMarshall Clowtemplate <class Iterator>
387947ce6b5SMarshall Clowclass move_iterator {
388947ce6b5SMarshall Clowpublic:
389b06049bcSKonstantin Varlamov    using iterator_type     = Iterator;
390b06049bcSKonstantin Varlamov    using iterator_concept  = input_iterator_tag; // From C++20
391b06049bcSKonstantin Varlamov    using iterator_category = see below; // not always present starting from C++20
392b06049bcSKonstantin Varlamov    using value_type        = iter_value_t<Iterator>; // Until C++20, iterator_traits<Iterator>::value_type
393b06049bcSKonstantin Varlamov    using difference_type   = iter_difference_t<Iterator>; // Until C++20, iterator_traits<Iterator>::difference_type;
394b06049bcSKonstantin Varlamov    using pointer           = Iterator;
395b06049bcSKonstantin Varlamov    using reference         = iter_rvalue_reference_t<Iterator>; // Until C++20, value_type&&
396947ce6b5SMarshall Clow
397720ef472SMarshall Clow    constexpr move_iterator();  // all the constexprs are in C++17
398720ef472SMarshall Clow    constexpr explicit move_iterator(Iterator i);
399720ef472SMarshall Clow    template <class U>
400720ef472SMarshall Clow      constexpr move_iterator(const move_iterator<U>& u);
401720ef472SMarshall Clow    template <class U>
402720ef472SMarshall Clow      constexpr move_iterator& operator=(const move_iterator<U>& u);
403b06049bcSKonstantin Varlamov
404b06049bcSKonstantin Varlamov    constexpr iterator_type base() const; // Until C++20
405b06049bcSKonstantin Varlamov    constexpr const Iterator& base() const & noexcept; // From C++20
406b06049bcSKonstantin Varlamov    constexpr Iterator base() &&; // From C++20
407b06049bcSKonstantin Varlamov
408720ef472SMarshall Clow    constexpr reference operator*() const;
409*79a2b4baSKonstantin Varlamov    constexpr pointer operator->() const; // Deprecated in C++20
410720ef472SMarshall Clow    constexpr move_iterator& operator++();
411b06049bcSKonstantin Varlamov    constexpr auto operator++(int); // Return type was move_iterator until C++20
412720ef472SMarshall Clow    constexpr move_iterator& operator--();
413720ef472SMarshall Clow    constexpr move_iterator operator--(int);
414720ef472SMarshall Clow    constexpr move_iterator operator+(difference_type n) const;
415720ef472SMarshall Clow    constexpr move_iterator& operator+=(difference_type n);
416720ef472SMarshall Clow    constexpr move_iterator operator-(difference_type n) const;
417720ef472SMarshall Clow    constexpr move_iterator& operator-=(difference_type n);
418b06049bcSKonstantin Varlamov    constexpr reference operator[](difference_type n) const; // Return type unspecified until C++20
419b06049bcSKonstantin Varlamov
420b06049bcSKonstantin Varlamov    template<sentinel_for<Iterator> S>
421b06049bcSKonstantin Varlamov      friend constexpr bool
422b06049bcSKonstantin Varlamov        operator==(const move_iterator& x, const move_sentinel<S>& y); // Since C++20
423b06049bcSKonstantin Varlamov    template<sized_sentinel_for<Iterator> S>
424b06049bcSKonstantin Varlamov      friend constexpr iter_difference_t<Iterator>
425b06049bcSKonstantin Varlamov        operator-(const move_sentinel<S>& x, const move_iterator& y); // Since C++20
426b06049bcSKonstantin Varlamov    template<sized_sentinel_for<Iterator> S>
427b06049bcSKonstantin Varlamov      friend constexpr iter_difference_t<Iterator>
428b06049bcSKonstantin Varlamov        operator-(const move_iterator& x, const move_sentinel<S>& y); // Since C++20
429b06049bcSKonstantin Varlamov    friend constexpr iter_rvalue_reference_t<Iterator>
430b06049bcSKonstantin Varlamov      iter_move(const move_iterator& i)
431b06049bcSKonstantin Varlamov        noexcept(noexcept(ranges::iter_move(i.current))); // Since C++20
432b06049bcSKonstantin Varlamov    template<indirectly_swappable<Iterator> Iterator2>
433b06049bcSKonstantin Varlamov      friend constexpr void
434b06049bcSKonstantin Varlamov        iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y)
435b06049bcSKonstantin Varlamov          noexcept(noexcept(ranges::iter_swap(x.current, y.current))); // Since C++20
436b06049bcSKonstantin Varlamov
437947ce6b5SMarshall Clowprivate:
438947ce6b5SMarshall Clow    Iterator current; // exposition only
439947ce6b5SMarshall Clow};
440947ce6b5SMarshall Clow
441947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
442720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
443947ce6b5SMarshall Clowoperator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
444947ce6b5SMarshall Clow
445947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
446720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
447947ce6b5SMarshall Clowoperator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
448947ce6b5SMarshall Clow
449947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
450720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
451947ce6b5SMarshall Clowoperator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
452947ce6b5SMarshall Clow
453947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
454720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
455947ce6b5SMarshall Clowoperator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
456947ce6b5SMarshall Clow
457947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
458720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
459947ce6b5SMarshall Clowoperator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
460947ce6b5SMarshall Clow
461947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
462720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
463947ce6b5SMarshall Clowoperator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
464947ce6b5SMarshall Clow
465947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
466720ef472SMarshall Clowconstexpr auto   // constexpr in C++17
467947ce6b5SMarshall Clowoperator-(const move_iterator<Iterator1>& x,
468947ce6b5SMarshall Clow          const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
469947ce6b5SMarshall Clow
470947ce6b5SMarshall Clowtemplate <class Iterator>
471720ef472SMarshall Clowconstexpr move_iterator<Iterator> operator+(   // constexpr in C++17
472720ef472SMarshall Clow            typename move_iterator<Iterator>::difference_type n,
473947ce6b5SMarshall Clow            const move_iterator<Iterator>& x);
474947ce6b5SMarshall Clow
475720ef472SMarshall Clowtemplate <class Iterator>   // constexpr in C++17
476720ef472SMarshall Clowconstexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
477947ce6b5SMarshall Clow
478b06049bcSKonstantin Varlamovtemplate<semiregular S>
479b06049bcSKonstantin Varlamovclass move_sentinel {
480b06049bcSKonstantin Varlamovpublic:
481b06049bcSKonstantin Varlamov  constexpr move_sentinel();
482b06049bcSKonstantin Varlamov  constexpr explicit move_sentinel(S s);
483b06049bcSKonstantin Varlamov  template<class S2>
484b06049bcSKonstantin Varlamov    requires convertible_to<const S2&, S>
485b06049bcSKonstantin Varlamov      constexpr move_sentinel(const move_sentinel<S2>& s);
486b06049bcSKonstantin Varlamov  template<class S2>
487b06049bcSKonstantin Varlamov    requires assignable_from<S&, const S2&>
488b06049bcSKonstantin Varlamov      constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
489b06049bcSKonstantin Varlamov
490b06049bcSKonstantin Varlamov  constexpr S base() const;
491b06049bcSKonstantin Varlamovprivate:
492b06049bcSKonstantin Varlamov  S last;     // exposition only
493b06049bcSKonstantin Varlamov};
494b06049bcSKonstantin Varlamov
495065cf3f9Szoecarver// [default.sentinel], default sentinel
496065cf3f9Szoecarverstruct default_sentinel_t;
497065cf3f9Szoecarverinline constexpr default_sentinel_t default_sentinel{};
498947ce6b5SMarshall Clow
4998a48e6ddSzoecarver// [iterators.counted], counted iterators
5008a48e6ddSzoecarvertemplate<input_or_output_iterator I> class counted_iterator;
5018a48e6ddSzoecarver
5028a48e6ddSzoecarvertemplate<input_iterator I>
5038a48e6ddSzoecarver  requires see below
5048a48e6ddSzoecarver  struct iterator_traits<counted_iterator<I>>;
5058a48e6ddSzoecarver
5064ac87e33Szoecarver// [unreachable.sentinel], unreachable sentinel
5074ac87e33Szoecarverstruct unreachable_sentinel_t;
5084ac87e33Szoecarverinline constexpr unreachable_sentinel_t unreachable_sentinel{};
5094ac87e33Szoecarver
5103e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
5113e519524SHoward Hinnantclass istream_iterator
5121055cb91SLouis Dionne    : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
5133e519524SHoward Hinnant{
5143e519524SHoward Hinnantpublic:
51541bdf64dSLouis Dionne    typedef input_iterator_tag           iterator_category;
51641bdf64dSLouis Dionne    typedef T                            value_type;
51741bdf64dSLouis Dionne    typedef Distance                     difference_type;
51841bdf64dSLouis Dionne    typedef const T*                     pointer;
51941bdf64dSLouis Dionne    typedef const T&                     reference;
52041bdf64dSLouis Dionne
5213e519524SHoward Hinnant    typedef charT                        char_type;
5223e519524SHoward Hinnant    typedef traits                       traits_type;
5233e519524SHoward Hinnant    typedef basic_istream<charT, traits> istream_type;
5243e519524SHoward Hinnant
52543bc1e56SKonstantin Varlamov    istream_iterator(); // constexpr since C++11
52643bc1e56SKonstantin Varlamov    constexpr istream_iterator(default_sentinel_t); // since C++20
5273e519524SHoward Hinnant    istream_iterator(istream_type& s);
5283e519524SHoward Hinnant    istream_iterator(const istream_iterator& x);
5293e519524SHoward Hinnant    ~istream_iterator();
5303e519524SHoward Hinnant
5313e519524SHoward Hinnant    const T& operator*() const;
5323e519524SHoward Hinnant    const T* operator->() const;
5333e519524SHoward Hinnant    istream_iterator& operator++();
5343e519524SHoward Hinnant    istream_iterator  operator++(int);
53543bc1e56SKonstantin Varlamov    friend bool operator==(const istream_iterator& i, default_sentinel_t); // since C++20
5363e519524SHoward Hinnant};
5373e519524SHoward Hinnant
5383e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
5393e519524SHoward Hinnantbool operator==(const istream_iterator<T,charT,traits,Distance>& x,
5403e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
5413e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
5423e519524SHoward Hinnantbool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
54343bc1e56SKonstantin Varlamov                const istream_iterator<T,charT,traits,Distance>& y); // until C++20
5443e519524SHoward Hinnant
5453e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT> >
5463e519524SHoward Hinnantclass ostream_iterator
5471055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
5483e519524SHoward Hinnant{
5493e519524SHoward Hinnantpublic:
55041bdf64dSLouis Dionne    typedef output_iterator_tag         iterator_category;
55141bdf64dSLouis Dionne    typedef void                        value_type;
55241bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
55341bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
55441bdf64dSLouis Dionne    typedef void                        pointer;
55541bdf64dSLouis Dionne    typedef void                        reference;
55641bdf64dSLouis Dionne
5573e519524SHoward Hinnant    typedef charT char_type;
5583e519524SHoward Hinnant    typedef traits traits_type;
5593e519524SHoward Hinnant    typedef basic_ostream<charT,traits> ostream_type;
5603e519524SHoward Hinnant
5613e519524SHoward Hinnant    ostream_iterator(ostream_type& s);
5623e519524SHoward Hinnant    ostream_iterator(ostream_type& s, const charT* delimiter);
5633e519524SHoward Hinnant    ostream_iterator(const ostream_iterator& x);
5643e519524SHoward Hinnant    ~ostream_iterator();
5653e519524SHoward Hinnant    ostream_iterator& operator=(const T& value);
5663e519524SHoward Hinnant
5673e519524SHoward Hinnant    ostream_iterator& operator*();
5683e519524SHoward Hinnant    ostream_iterator& operator++();
5693e519524SHoward Hinnant    ostream_iterator& operator++(int);
5703e519524SHoward Hinnant};
5713e519524SHoward Hinnant
5723e519524SHoward Hinnanttemplate<class charT, class traits = char_traits<charT> >
5733e519524SHoward Hinnantclass istreambuf_iterator
57441bdf64dSLouis Dionne    : public iterator<input_iterator_tag, charT, traits::off_type, unspecified, charT> // until C++17
5753e519524SHoward Hinnant{
5763e519524SHoward Hinnantpublic:
57741bdf64dSLouis Dionne    typedef input_iterator_tag              iterator_category;
57841bdf64dSLouis Dionne    typedef charT                           value_type;
57941bdf64dSLouis Dionne    typedef traits::off_type                difference_type;
58041bdf64dSLouis Dionne    typedef unspecified                     pointer;
58141bdf64dSLouis Dionne    typedef charT                           reference;
58241bdf64dSLouis Dionne
5833e519524SHoward Hinnant    typedef charT                           char_type;
5843e519524SHoward Hinnant    typedef traits                          traits_type;
58541bdf64dSLouis Dionne    typedef traits::int_type                int_type;
5863e519524SHoward Hinnant    typedef basic_streambuf<charT, traits>  streambuf_type;
5873e519524SHoward Hinnant    typedef basic_istream<charT, traits>    istream_type;
5883e519524SHoward Hinnant
58943bc1e56SKonstantin Varlamov    istreambuf_iterator() noexcept; // constexpr since C++11
59043bc1e56SKonstantin Varlamov    constexpr istreambuf_iterator(default_sentinel_t) noexcept; // since C++20
5918e882dcbSHoward Hinnant    istreambuf_iterator(istream_type& s) noexcept;
5928e882dcbSHoward Hinnant    istreambuf_iterator(streambuf_type* s) noexcept;
5938e882dcbSHoward Hinnant    istreambuf_iterator(a-private-type) noexcept;
5943e519524SHoward Hinnant
5953e519524SHoward Hinnant    charT                operator*() const;
5963e519524SHoward Hinnant    pointer operator->() const;
5973e519524SHoward Hinnant    istreambuf_iterator& operator++();
5983e519524SHoward Hinnant    a-private-type       operator++(int);
5993e519524SHoward Hinnant
6003e519524SHoward Hinnant    bool equal(const istreambuf_iterator& b) const;
60143bc1e56SKonstantin Varlamov    friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); // since C++20
6023e519524SHoward Hinnant};
6033e519524SHoward Hinnant
6043e519524SHoward Hinnanttemplate <class charT, class traits>
6053e519524SHoward Hinnantbool operator==(const istreambuf_iterator<charT,traits>& a,
6063e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
6073e519524SHoward Hinnanttemplate <class charT, class traits>
6083e519524SHoward Hinnantbool operator!=(const istreambuf_iterator<charT,traits>& a,
60943bc1e56SKonstantin Varlamov                const istreambuf_iterator<charT,traits>& b); // until C++20
6103e519524SHoward Hinnant
6113e519524SHoward Hinnanttemplate <class charT, class traits = char_traits<charT> >
6123e519524SHoward Hinnantclass ostreambuf_iterator
6131055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
6143e519524SHoward Hinnant{
6153e519524SHoward Hinnantpublic:
61641bdf64dSLouis Dionne    typedef output_iterator_tag            iterator_category;
61741bdf64dSLouis Dionne    typedef void                           value_type;
61841bdf64dSLouis Dionne    typedef void                           difference_type; // until C++20
61941bdf64dSLouis Dionne    typedef ptrdiff_t                      difference_type; // since C++20
62041bdf64dSLouis Dionne    typedef void                           pointer;
62141bdf64dSLouis Dionne    typedef void                           reference;
62241bdf64dSLouis Dionne
6233e519524SHoward Hinnant    typedef charT                          char_type;
6243e519524SHoward Hinnant    typedef traits                         traits_type;
6253e519524SHoward Hinnant    typedef basic_streambuf<charT, traits> streambuf_type;
6263e519524SHoward Hinnant    typedef basic_ostream<charT, traits>   ostream_type;
6273e519524SHoward Hinnant
6288e882dcbSHoward Hinnant    ostreambuf_iterator(ostream_type& s) noexcept;
6298e882dcbSHoward Hinnant    ostreambuf_iterator(streambuf_type* s) noexcept;
6303e519524SHoward Hinnant    ostreambuf_iterator& operator=(charT c);
6313e519524SHoward Hinnant    ostreambuf_iterator& operator*();
6323e519524SHoward Hinnant    ostreambuf_iterator& operator++();
6333e519524SHoward Hinnant    ostreambuf_iterator& operator++(int);
6348e882dcbSHoward Hinnant    bool failed() const noexcept;
6353e519524SHoward Hinnant};
6363e519524SHoward Hinnant
637020b623aSMarshall Clowtemplate <class C> constexpr auto begin(C& c) -> decltype(c.begin());
638020b623aSMarshall Clowtemplate <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
639020b623aSMarshall Clowtemplate <class C> constexpr auto end(C& c) -> decltype(c.end());
640020b623aSMarshall Clowtemplate <class C> constexpr auto end(const C& c) -> decltype(c.end());
641020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* begin(T (&array)[N]);
642020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* end(T (&array)[N]);
6433e519524SHoward Hinnant
644020b623aSMarshall Clowtemplate <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c));        // C++14
645020b623aSMarshall Clowtemplate <class C> auto constexpr cend(const C& c) -> decltype(std::end(c));            // C++14
646020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
647020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
648020b623aSMarshall Clowtemplate <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
649020b623aSMarshall Clowtemplate <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
650020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
651020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il);   // C++14
652020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
653020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
654020b623aSMarshall Clowtemplate <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
655020b623aSMarshall Clowtemplate <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
6561e548c72SMarshall Clow
657ad755104SMarshall Clow// 24.8, container access:
658ad755104SMarshall Clowtemplate <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
659ad755104SMarshall Clowtemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
6607d3986eaSMarshall Clow
6617d3986eaSMarshall Clowtemplate <class C> constexpr auto ssize(const C& c)
6627d3986eaSMarshall Clow    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;                    // C++20
6637d3986eaSMarshall Clowtemplate <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
6647d3986eaSMarshall Clow
665ad755104SMarshall Clowtemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
666ad755104SMarshall Clowtemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
667ad755104SMarshall Clowtemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
668ad755104SMarshall Clowtemplate <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
669ad755104SMarshall Clowtemplate <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
670ad755104SMarshall Clowtemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
671ad755104SMarshall Clowtemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
672ad755104SMarshall Clow
6733e519524SHoward Hinnant}  // std
6743e519524SHoward Hinnant
6753e519524SHoward Hinnant*/
6763e519524SHoward Hinnant
677385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
6783e519524SHoward Hinnant#include <__config>
6795f51fb34SArthur O'Dwyer#include <__debug>
6808517a26dSChristopher Di Bella#include <__iterator/access.h>
68136d0fdf9SChristopher Di Bella#include <__iterator/advance.h>
682f32f3db9SLouis Dionne#include <__iterator/back_insert_iterator.h>
683633d1d0dSLouis Dionne#include <__iterator/bounded_iter.h>
6841a29403dSzoecarver#include <__iterator/common_iterator.h>
68557ebf3d0SLouis Dionne#include <__iterator/concepts.h>
6868a48e6ddSzoecarver#include <__iterator/counted_iterator.h>
6878517a26dSChristopher Di Bella#include <__iterator/data.h>
688065cf3f9Szoecarver#include <__iterator/default_sentinel.h>
6898517a26dSChristopher Di Bella#include <__iterator/distance.h>
6908517a26dSChristopher Di Bella#include <__iterator/empty.h>
6918517a26dSChristopher Di Bella#include <__iterator/erase_if_container.h>
692f32f3db9SLouis Dionne#include <__iterator/front_insert_iterator.h>
693e0adf7e0Szoecarver#include <__iterator/incrementable_traits.h>
6946d722801SNikolas Klauser#include <__iterator/indirectly_comparable.h>
695f32f3db9SLouis Dionne#include <__iterator/insert_iterator.h>
6968517a26dSChristopher Di Bella#include <__iterator/istream_iterator.h>
6974d81a46fSArthur O'Dwyer#include <__iterator/istreambuf_iterator.h>
69897e383aaSLouis Dionne#include <__iterator/iter_move.h>
69940d6d2c4Szoecarver#include <__iterator/iter_swap.h>
7004d81a46fSArthur O'Dwyer#include <__iterator/iterator.h>
7014d81a46fSArthur O'Dwyer#include <__iterator/iterator_traits.h>
702eea3d90aSKonstantin Varlamov#include <__iterator/mergeable.h>
703f32f3db9SLouis Dionne#include <__iterator/move_iterator.h>
7042fb026eeSArthur O'Dwyer#include <__iterator/move_sentinel.h>
705857fa7b7SChristopher Di Bella#include <__iterator/next.h>
7068517a26dSChristopher Di Bella#include <__iterator/ostream_iterator.h>
7074d81a46fSArthur O'Dwyer#include <__iterator/ostreambuf_iterator.h>
7088f1d8785SKonstantin Varlamov#include <__iterator/permutable.h>
7090dc7fd1bSChristopher Di Bella#include <__iterator/prev.h>
71058b29a4eSLouis Dionne#include <__iterator/projected.h>
711e0adf7e0Szoecarver#include <__iterator/readable_traits.h>
7128517a26dSChristopher Di Bella#include <__iterator/reverse_access.h>
713f32f3db9SLouis Dionne#include <__iterator/reverse_iterator.h>
7148517a26dSChristopher Di Bella#include <__iterator/size.h>
7158e979460SKonstantin Varlamov#include <__iterator/sortable.h>
7164ac87e33Szoecarver#include <__iterator/unreachable_sentinel.h>
717f32f3db9SLouis Dionne#include <__iterator/wrap_iter.h>
718f992cfbaSLouis Dionne#include <__memory/addressof.h>
719d41c6d51SArthur O'Dwyer#include <__memory/pointer_traits.h>
7205f51fb34SArthur O'Dwyer#include <compare>
7215f51fb34SArthur O'Dwyer#include <concepts> // Mandated by the Standard.
7225f51fb34SArthur O'Dwyer#include <cstddef>
7235f51fb34SArthur O'Dwyer#include <initializer_list>
7245f51fb34SArthur O'Dwyer#include <type_traits>
725f56972e2SMarshall Clow#include <version>
726b5c63a2eSHoward Hinnant
727de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
728de4a57cbSLouis Dionne#  include <exception>
729de4a57cbSLouis Dionne#  include <new>
730de4a57cbSLouis Dionne#  include <typeinfo>
731de4a57cbSLouis Dionne#  include <utility>
732de4a57cbSLouis Dionne#endif
733de4a57cbSLouis Dionne
734073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
7353e519524SHoward Hinnant#  pragma GCC system_header
736073458b1SHoward Hinnant#endif
7373e519524SHoward Hinnant
7383e519524SHoward Hinnant#endif // _LIBCPP_ITERATOR
739