13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===-------------------------- iterator ----------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_ITERATOR
113e519524SHoward Hinnant#define _LIBCPP_ITERATOR
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    iterator synopsis
153e519524SHoward Hinnant
16fe31f11cSChristopher Di Bella#include <concepts>
17fe31f11cSChristopher Di Bella
183e519524SHoward Hinnantnamespace std
193e519524SHoward Hinnant{
20fe31f11cSChristopher Di Bellatemplate<class> struct incrementable_traits;       // since C++20
219816d43cSChristopher Di Bellatemplate<class T>
229816d43cSChristopher Di Bella  using iter_difference_t = see below;             // since C++20
239816d43cSChristopher Di Bella
24f280505aSChristopher Di Bellatemplate<class> struct indirectly_readable_traits; // since C++20
259816d43cSChristopher Di Bellatemplate<class T>
269816d43cSChristopher Di Bella  using iter_value_t = see below;                  // since C++20
273e519524SHoward Hinnant
283e519524SHoward Hinnanttemplate<class Iterator>
299f01ac3bSzoecarverstruct iterator_traits;
303e519524SHoward Hinnant
313e519524SHoward Hinnanttemplate<class T>
329f01ac3bSzoecarver  requires is_object_v<T>                    // since C++20
339f01ac3bSzoecarverstruct iterator_traits<T*>;
343e519524SHoward Hinnant
350148b653SChristopher Di Bellatemplate<dereferenceable T>
360148b653SChristopher Di Bella  using iter_reference_t = decltype(*declval<T&>());
370148b653SChristopher Di Bella
3897e383aaSLouis Dionnenamespace ranges::inline unspecified {
3997e383aaSLouis Dionne    inline constexpr unspecified iter_move = unspecified; // since C++20, nodiscard as an extension
4097e383aaSLouis Dionne}}
4197e383aaSLouis Dionne
4297e383aaSLouis Dionnetemplate<dereferenceable T>
4397e383aaSLouis Dionne  requires ...
4497e383aaSLouis Dionneusing iter_rvalue_reference_t = decltype(ranges::iter_move(declval<T&>())); // since C++20
4597e383aaSLouis Dionne
4657ebf3d0SLouis Dionne// [iterator.concepts], iterator concepts
4757ebf3d0SLouis Dionne// [iterator.concept.readable], concept indirectly_readable
4857ebf3d0SLouis Dionnetemplate<class In>
4957ebf3d0SLouis Dionne  concept indirectly_readable = see below;                      // since C++20
5057ebf3d0SLouis Dionne
5158b29a4eSLouis Dionnetemplate<indirectly_readable T>
5258b29a4eSLouis Dionne  using iter_common_reference_t =
5358b29a4eSLouis Dionne    common_reference_t<iter_reference_t<T>, iter_value_t<T>&>;  // since C++20
5458b29a4eSLouis Dionne
5557ebf3d0SLouis Dionne// [iterator.concept.writable], concept indirectly_writable
5657ebf3d0SLouis Dionnetemplate<class Out, class T>
5757ebf3d0SLouis Dionne  concept indirectly_writable = see below;                // since C++20
5857ebf3d0SLouis Dionne
5918b03b00SMark de Wever// [iterator.concept.winc], concept weakly_incrementable
6022052860SChristopher Di Bellatemplate<class I>
6122052860SChristopher Di Bella  concept weakly_incrementable = see below;                // since C++20
6222052860SChristopher Di Bella
6322052860SChristopher Di Bella// [iterator.concept.inc], concept incrementable
6422052860SChristopher Di Bellatemplate<class I>
6522052860SChristopher Di Bella  concept incrementable = see below;                       // since C++20
6622052860SChristopher Di Bella
6718b03b00SMark de Wever// [iterator.concept.iterator], concept input_or_output_iterator
6838225d69SChristopher Di Bella  template<class I>
6938225d69SChristopher Di Bella    concept input_or_output_iterator = see below;          // since C++20
7038225d69SChristopher Di Bella
7118b03b00SMark de Wever// [iterator.concept.sentinel], concept sentinel_for
7238225d69SChristopher Di Bellatemplate<class S, class I>
7338225d69SChristopher Di Bella  concept sentinel_for = see below;                        // since C++20
7438225d69SChristopher Di Bella
75bdd68357Szoecarver// [iterator.concept.sizedsentinel], concept sized_sentinel_for
76bdd68357Szoecarvertemplate<class S, class I>
77bdd68357Szoecarver  inline constexpr bool disable_sized_sentinel_for = false;
78bdd68357Szoecarver
79bdd68357Szoecarvertemplate<class S, class I>
80bdd68357Szoecarver  concept sized_sentinel_for = see below;
81bdd68357Szoecarver
82c05d1eedSChristopher Di Bella// [iterator.concept.input], concept input_iterator
83c05d1eedSChristopher Di Bellatemplate<class I>
84c05d1eedSChristopher Di Bella  concept input_iterator = see below;                      // since C++20
85c05d1eedSChristopher Di Bella
86fa3e2626SChristopher Di Bella// [iterator.concept.forward], concept forward_iterator
87fa3e2626SChristopher Di Bellatemplate<class I>
88fa3e2626SChristopher Di Bella  concept forward_iterator = see below;                    // since C++20
89fa3e2626SChristopher Di Bella
909c5d86aaSChristopher Di Bella// [iterator.concept.bidir], concept bidirectional_iterator
919c5d86aaSChristopher Di Bellatemplate<class I>
929c5d86aaSChristopher Di Bella  concept bidirectional_iterator = see below;              // since C++20
939c5d86aaSChristopher Di Bella
946ffc41b0Szoecarver// [iterator.concept.random.access], concept random_access_iterator
956ffc41b0Szoecarvertemplate<class I>
966ffc41b0Szoecarver  concept random_access_iterator = see below;              // since C++20
976ffc41b0Szoecarver
9858b29a4eSLouis Dionne// [indirectcallable]
9958b29a4eSLouis Dionne// [indirectcallable.indirectinvocable]
10058b29a4eSLouis Dionnetemplate<class F, class I>
10158b29a4eSLouis Dionne  concept indirectly_unary_invocable = see below;          // since C++20
10258b29a4eSLouis Dionne
10358b29a4eSLouis Dionnetemplate<class F, class I>
10458b29a4eSLouis Dionne  concept indirectly_regular_unary_invocable = see below;  // since C++20
10558b29a4eSLouis Dionne
10658b29a4eSLouis Dionnetemplate<class F, class I>
10758b29a4eSLouis Dionne  concept indirect_unary_predicate = see below;            // since C++20
10858b29a4eSLouis Dionne
10958b29a4eSLouis Dionnetemplate<class F, class I1, class I2>
11058b29a4eSLouis Dionne  concept indirect_binary_predicate = see below;           // since C++20
11158b29a4eSLouis Dionne
11258b29a4eSLouis Dionnetemplate<class F, class I1, class I2 = I1>
11358b29a4eSLouis Dionne  concept indirect_equivalence_relation = see below;       // since C++20
11458b29a4eSLouis Dionne
11558b29a4eSLouis Dionnetemplate<class F, class I1, class I2 = I1>
11658b29a4eSLouis Dionne  concept indirect_strict_weak_order = see below;          // since C++20
11758b29a4eSLouis Dionne
11858b29a4eSLouis Dionnetemplate<class F, class... Is>
11958b29a4eSLouis Dionne  using indirect_result_t = see below;                     // since C++20
12058b29a4eSLouis Dionne
12158b29a4eSLouis Dionne// [projected], projected
12258b29a4eSLouis Dionnetemplate<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
12358b29a4eSLouis Dionne  struct projected;                                        // since C++20
12458b29a4eSLouis Dionne
12558b29a4eSLouis Dionnetemplate<weakly_incrementable I, indirectly_regular_unary_invocable<I> Proj>
12658b29a4eSLouis Dionne  struct incrementable_traits<projected<I, Proj>>;         // since C++20
12758b29a4eSLouis Dionne
128075f2370Szoecarver// [alg.req.ind.move], concept indirectly_movable
129075f2370Szoecarvertemplate<class In, class Out>
130075f2370Szoecarver  concept indirectly_movable = see below;                  // since C++20
131075f2370Szoecarver
132075f2370Szoecarvertemplate<class In, class Out>
133075f2370Szoecarver  concept indirectly_movable_storable = see below;         // since C++20
134075f2370Szoecarver
1353e519524SHoward Hinnanttemplate<class Category, class T, class Distance = ptrdiff_t,
1363e519524SHoward Hinnant         class Pointer = T*, class Reference = T&>
1371055cb91SLouis Dionnestruct iterator                                            // deprecated in C++17
1383e519524SHoward Hinnant{
1393e519524SHoward Hinnant    typedef T         value_type;
1403e519524SHoward Hinnant    typedef Distance  difference_type;
1413e519524SHoward Hinnant    typedef Pointer   pointer;
1423e519524SHoward Hinnant    typedef Reference reference;
1433e519524SHoward Hinnant    typedef Category  iterator_category;
1443e519524SHoward Hinnant};
1453e519524SHoward Hinnant
1463e519524SHoward Hinnantstruct input_iterator_tag  {};
1473e519524SHoward Hinnantstruct output_iterator_tag {};
1483e519524SHoward Hinnantstruct forward_iterator_tag       : public input_iterator_tag         {};
1493e519524SHoward Hinnantstruct bidirectional_iterator_tag : public forward_iterator_tag       {};
1503e519524SHoward Hinnantstruct random_access_iterator_tag : public bidirectional_iterator_tag {};
1513e519524SHoward Hinnant
152f51ee632SMarshall Clow// 27.4.3, iterator operations
15312b01ab7SLouis Dionnetemplate <class InputIterator, class Distance>  // constexpr in C++17
15412b01ab7SLouis Dionne  constexpr void advance(InputIterator& i, Distance n);
1553e519524SHoward Hinnant
156f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
157f51ee632SMarshall Clow  constexpr typename iterator_traits<InputIterator>::difference_type
1583e519524SHoward Hinnant    distance(InputIterator first, InputIterator last);
1593e519524SHoward Hinnant
160f51ee632SMarshall Clowtemplate <class InputIterator>  // constexpr in C++17
161f51ee632SMarshall Clow  constexpr InputIterator next(InputIterator x,
162f51ee632SMarshall Clowtypename iterator_traits<InputIterator>::difference_type n = 1);
163f51ee632SMarshall Clow
164f51ee632SMarshall Clowtemplate <class BidirectionalIterator>  // constexpr in C++17
165f51ee632SMarshall Clow  constexpr BidirectionalIterator prev(BidirectionalIterator x,
166f51ee632SMarshall Clow    typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
167f51ee632SMarshall Clow
16836d0fdf9SChristopher Di Bella// [range.iter.ops], range iterator operations
16936d0fdf9SChristopher Di Bellanamespace ranges {
17036d0fdf9SChristopher Di Bella  // [range.iter.op.advance], ranges::advance
17136d0fdf9SChristopher Di Bella  template<input_or_output_iterator I>
17236d0fdf9SChristopher Di Bella    constexpr void advance(I& i, iter_difference_t<I> n);                          // since C++20
17336d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
17436d0fdf9SChristopher Di Bella    constexpr void advance(I& i, S bound);                                         // since C++20
17536d0fdf9SChristopher Di Bella  template<input_or_output_iterator I, sentinel_for<I> S>
17636d0fdf9SChristopher Di Bella    constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound); // since C++20
17736d0fdf9SChristopher Di Bella}
17836d0fdf9SChristopher Di Bella
1793e519524SHoward Hinnanttemplate <class Iterator>
1803e519524SHoward Hinnantclass reverse_iterator
1811055cb91SLouis Dionne    : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17
1823e519524SHoward Hinnant                      typename iterator_traits<Iterator>::value_type,
1833e519524SHoward Hinnant                      typename iterator_traits<Iterator>::difference_type,
1843e519524SHoward Hinnant                      typename iterator_traits<Iterator>::pointer,
1853e519524SHoward Hinnant                      typename iterator_traits<Iterator>::reference>
1863e519524SHoward Hinnant{
1873e519524SHoward Hinnantprotected:
1883e519524SHoward Hinnant    Iterator current;
1893e519524SHoward Hinnantpublic:
1903e519524SHoward Hinnant    typedef Iterator                                            iterator_type;
1913e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::difference_type difference_type;
1923e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::reference       reference;
1933e519524SHoward Hinnant    typedef typename iterator_traits<Iterator>::pointer         pointer;
1943e519524SHoward Hinnant
1951b8f260eSMarshall Clow    constexpr reverse_iterator();
1961b8f260eSMarshall Clow    constexpr explicit reverse_iterator(Iterator x);
1971b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
1981b8f260eSMarshall Clow    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
1991b8f260eSMarshall Clow    constexpr Iterator base() const;
2001b8f260eSMarshall Clow    constexpr reference operator*() const;
2011b8f260eSMarshall Clow    constexpr pointer   operator->() const;
2021b8f260eSMarshall Clow    constexpr reverse_iterator& operator++();
2031b8f260eSMarshall Clow    constexpr reverse_iterator  operator++(int);
2041b8f260eSMarshall Clow    constexpr reverse_iterator& operator--();
2051b8f260eSMarshall Clow    constexpr reverse_iterator  operator--(int);
2061b8f260eSMarshall Clow    constexpr reverse_iterator  operator+ (difference_type n) const;
2071b8f260eSMarshall Clow    constexpr reverse_iterator& operator+=(difference_type n);
2081b8f260eSMarshall Clow    constexpr reverse_iterator  operator- (difference_type n) const;
2091b8f260eSMarshall Clow    constexpr reverse_iterator& operator-=(difference_type n);
2101b8f260eSMarshall Clow    constexpr reference         operator[](difference_type n) const;
2113e519524SHoward Hinnant};
2123e519524SHoward Hinnant
2133e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2141b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2153e519524SHoward Hinnantoperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2163e519524SHoward Hinnant
2173e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2181b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2193e519524SHoward Hinnantoperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2203e519524SHoward Hinnant
2213e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2221b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2233e519524SHoward Hinnantoperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2243e519524SHoward Hinnant
2253e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2261b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2273e519524SHoward Hinnantoperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2283e519524SHoward Hinnant
2293e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2301b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2313e519524SHoward Hinnantoperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2323e519524SHoward Hinnant
2333e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2341b8f260eSMarshall Clowconstexpr bool                          // constexpr in C++17
2353e519524SHoward Hinnantoperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
2363e519524SHoward Hinnant
2373e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2>
2381b8f260eSMarshall Clowconstexpr auto
239947ce6b5SMarshall Clowoperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
2401b8f260eSMarshall Clow-> decltype(__y.base() - __x.base());   // constexpr in C++17
2413e519524SHoward Hinnant
2423e519524SHoward Hinnanttemplate <class Iterator>
2431b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator>
2441b8f260eSMarshall Clowoperator+(typename reverse_iterator<Iterator>::difference_type n,
2451b8f260eSMarshall Clow          const reverse_iterator<Iterator>& x);   // constexpr in C++17
2463e519524SHoward Hinnant
2471b8f260eSMarshall Clowtemplate <class Iterator>
2481b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
2496a640a18SMarshall Clow
2503e519524SHoward Hinnanttemplate <class Container>
2513e519524SHoward Hinnantclass back_insert_iterator
25241bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
2533e519524SHoward Hinnant{
2543e519524SHoward Hinnantprotected:
2553e519524SHoward Hinnant    Container* container;
2563e519524SHoward Hinnantpublic:
2573e519524SHoward Hinnant    typedef Container                   container_type;
2583e519524SHoward Hinnant    typedef void                        value_type;
25941bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
26041bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
2618892b4eeSEric Fiselier    typedef void                        reference;
2623e519524SHoward Hinnant    typedef void                        pointer;
2633e519524SHoward Hinnant
26406e2b737SArthur O'Dwyer    explicit back_insert_iterator(Container& x);  // constexpr in C++20
26506e2b737SArthur O'Dwyer    back_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
26606e2b737SArthur O'Dwyer    back_insert_iterator& operator*();  // constexpr in C++20
26706e2b737SArthur O'Dwyer    back_insert_iterator& operator++();  // constexpr in C++20
26806e2b737SArthur O'Dwyer    back_insert_iterator  operator++(int);  // constexpr in C++20
2693e519524SHoward Hinnant};
2703e519524SHoward Hinnant
27106e2b737SArthur O'Dwyertemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x);  // constexpr in C++20
2723e519524SHoward Hinnant
2733e519524SHoward Hinnanttemplate <class Container>
2743e519524SHoward Hinnantclass front_insert_iterator
27541bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
2763e519524SHoward Hinnant{
2773e519524SHoward Hinnantprotected:
2783e519524SHoward Hinnant    Container* container;
2793e519524SHoward Hinnantpublic:
2803e519524SHoward Hinnant    typedef Container                    container_type;
2813e519524SHoward Hinnant    typedef void                         value_type;
28241bdf64dSLouis Dionne    typedef void                         difference_type; // until C++20
28341bdf64dSLouis Dionne    typedef ptrdiff_t                    difference_type; // since C++20
2848892b4eeSEric Fiselier    typedef void                         reference;
2853e519524SHoward Hinnant    typedef void                         pointer;
2863e519524SHoward Hinnant
28706e2b737SArthur O'Dwyer    explicit front_insert_iterator(Container& x);  // constexpr in C++20
28806e2b737SArthur O'Dwyer    front_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
28906e2b737SArthur O'Dwyer    front_insert_iterator& operator*();  // constexpr in C++20
29006e2b737SArthur O'Dwyer    front_insert_iterator& operator++();  // constexpr in C++20
29106e2b737SArthur O'Dwyer    front_insert_iterator  operator++(int);  // constexpr in C++20
2923e519524SHoward Hinnant};
2933e519524SHoward Hinnant
29406e2b737SArthur O'Dwyertemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x);  // constexpr in C++20
2953e519524SHoward Hinnant
2963e519524SHoward Hinnanttemplate <class Container>
2973e519524SHoward Hinnantclass insert_iterator
29841bdf64dSLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
2993e519524SHoward Hinnant{
3003e519524SHoward Hinnantprotected:
3013e519524SHoward Hinnant    Container* container;
3023e519524SHoward Hinnant    typename Container::iterator iter;
3033e519524SHoward Hinnantpublic:
3043e519524SHoward Hinnant    typedef Container              container_type;
3053e519524SHoward Hinnant    typedef void                   value_type;
30641bdf64dSLouis Dionne    typedef void                   difference_type; // until C++20
30741bdf64dSLouis Dionne    typedef ptrdiff_t              difference_type; // since C++20
3088892b4eeSEric Fiselier    typedef void                   reference;
3093e519524SHoward Hinnant    typedef void                   pointer;
3103e519524SHoward Hinnant
31106e2b737SArthur O'Dwyer    insert_iterator(Container& x, typename Container::iterator i);  // constexpr in C++20
31206e2b737SArthur O'Dwyer    insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
31306e2b737SArthur O'Dwyer    insert_iterator& operator*();  // constexpr in C++20
31406e2b737SArthur O'Dwyer    insert_iterator& operator++();  // constexpr in C++20
31506e2b737SArthur O'Dwyer    insert_iterator& operator++(int);  // constexpr in C++20
3163e519524SHoward Hinnant};
3173e519524SHoward Hinnant
3183e519524SHoward Hinnanttemplate <class Container, class Iterator>
31906e2b737SArthur O'Dwyerinsert_iterator<Container> inserter(Container& x, Iterator i);  // constexpr in C++20
3203e519524SHoward Hinnant
321947ce6b5SMarshall Clowtemplate <class Iterator>
322947ce6b5SMarshall Clowclass move_iterator {
323947ce6b5SMarshall Clowpublic:
324947ce6b5SMarshall Clow    typedef Iterator                                              iterator_type;
325947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::difference_type   difference_type;
326947ce6b5SMarshall Clow    typedef Iterator                                              pointer;
327947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::value_type        value_type;
328947ce6b5SMarshall Clow    typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
329947ce6b5SMarshall Clow    typedef value_type&&                                          reference;
330947ce6b5SMarshall Clow
331720ef472SMarshall Clow    constexpr move_iterator();  // all the constexprs are in C++17
332720ef472SMarshall Clow    constexpr explicit move_iterator(Iterator i);
333720ef472SMarshall Clow    template <class U>
334720ef472SMarshall Clow      constexpr move_iterator(const move_iterator<U>& u);
335720ef472SMarshall Clow    template <class U>
336720ef472SMarshall Clow      constexpr move_iterator& operator=(const move_iterator<U>& u);
337720ef472SMarshall Clow    constexpr iterator_type base() const;
338720ef472SMarshall Clow    constexpr reference operator*() const;
339720ef472SMarshall Clow    constexpr pointer operator->() const;
340720ef472SMarshall Clow    constexpr move_iterator& operator++();
341720ef472SMarshall Clow    constexpr move_iterator operator++(int);
342720ef472SMarshall Clow    constexpr move_iterator& operator--();
343720ef472SMarshall Clow    constexpr move_iterator operator--(int);
344720ef472SMarshall Clow    constexpr move_iterator operator+(difference_type n) const;
345720ef472SMarshall Clow    constexpr move_iterator& operator+=(difference_type n);
346720ef472SMarshall Clow    constexpr move_iterator operator-(difference_type n) const;
347720ef472SMarshall Clow    constexpr move_iterator& operator-=(difference_type n);
348720ef472SMarshall Clow    constexpr unspecified operator[](difference_type n) const;
349947ce6b5SMarshall Clowprivate:
350947ce6b5SMarshall Clow    Iterator current; // exposition only
351947ce6b5SMarshall Clow};
352947ce6b5SMarshall Clow
353947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
354720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
355947ce6b5SMarshall Clowoperator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
356947ce6b5SMarshall Clow
357947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
358720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
359947ce6b5SMarshall Clowoperator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
360947ce6b5SMarshall Clow
361947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
362720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
363947ce6b5SMarshall Clowoperator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
364947ce6b5SMarshall Clow
365947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
366720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
367947ce6b5SMarshall Clowoperator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
368947ce6b5SMarshall Clow
369947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
370720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
371947ce6b5SMarshall Clowoperator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
372947ce6b5SMarshall Clow
373947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
374720ef472SMarshall Clowconstexpr bool   // constexpr in C++17
375947ce6b5SMarshall Clowoperator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
376947ce6b5SMarshall Clow
377947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2>
378720ef472SMarshall Clowconstexpr auto   // constexpr in C++17
379947ce6b5SMarshall Clowoperator-(const move_iterator<Iterator1>& x,
380947ce6b5SMarshall Clow          const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
381947ce6b5SMarshall Clow
382947ce6b5SMarshall Clowtemplate <class Iterator>
383720ef472SMarshall Clowconstexpr move_iterator<Iterator> operator+(   // constexpr in C++17
384720ef472SMarshall Clow            typename move_iterator<Iterator>::difference_type n,
385947ce6b5SMarshall Clow            const move_iterator<Iterator>& x);
386947ce6b5SMarshall Clow
387720ef472SMarshall Clowtemplate <class Iterator>   // constexpr in C++17
388720ef472SMarshall Clowconstexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
389947ce6b5SMarshall Clow
390065cf3f9Szoecarver// [default.sentinel], default sentinel
391065cf3f9Szoecarverstruct default_sentinel_t;
392065cf3f9Szoecarverinline constexpr default_sentinel_t default_sentinel{};
393947ce6b5SMarshall Clow
3943e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
3953e519524SHoward Hinnantclass istream_iterator
3961055cb91SLouis Dionne    : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
3973e519524SHoward Hinnant{
3983e519524SHoward Hinnantpublic:
39941bdf64dSLouis Dionne    typedef input_iterator_tag           iterator_category;
40041bdf64dSLouis Dionne    typedef T                            value_type;
40141bdf64dSLouis Dionne    typedef Distance                     difference_type;
40241bdf64dSLouis Dionne    typedef const T*                     pointer;
40341bdf64dSLouis Dionne    typedef const T&                     reference;
40441bdf64dSLouis Dionne
4053e519524SHoward Hinnant    typedef charT                        char_type;
4063e519524SHoward Hinnant    typedef traits                       traits_type;
4073e519524SHoward Hinnant    typedef basic_istream<charT, traits> istream_type;
4083e519524SHoward Hinnant
40960d5e0e0SMarshall Clow    constexpr istream_iterator();
4103e519524SHoward Hinnant    istream_iterator(istream_type& s);
4113e519524SHoward Hinnant    istream_iterator(const istream_iterator& x);
4123e519524SHoward Hinnant    ~istream_iterator();
4133e519524SHoward Hinnant
4143e519524SHoward Hinnant    const T& operator*() const;
4153e519524SHoward Hinnant    const T* operator->() const;
4163e519524SHoward Hinnant    istream_iterator& operator++();
4173e519524SHoward Hinnant    istream_iterator  operator++(int);
4183e519524SHoward Hinnant};
4193e519524SHoward Hinnant
4203e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
4213e519524SHoward Hinnantbool operator==(const istream_iterator<T,charT,traits,Distance>& x,
4223e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
4233e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance>
4243e519524SHoward Hinnantbool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
4253e519524SHoward Hinnant                const istream_iterator<T,charT,traits,Distance>& y);
4263e519524SHoward Hinnant
4273e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT> >
4283e519524SHoward Hinnantclass ostream_iterator
4291055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
4303e519524SHoward Hinnant{
4313e519524SHoward Hinnantpublic:
43241bdf64dSLouis Dionne    typedef output_iterator_tag         iterator_category;
43341bdf64dSLouis Dionne    typedef void                        value_type;
43441bdf64dSLouis Dionne    typedef void                        difference_type; // until C++20
43541bdf64dSLouis Dionne    typedef ptrdiff_t                   difference_type; // since C++20
43641bdf64dSLouis Dionne    typedef void                        pointer;
43741bdf64dSLouis Dionne    typedef void                        reference;
43841bdf64dSLouis Dionne
4393e519524SHoward Hinnant    typedef charT char_type;
4403e519524SHoward Hinnant    typedef traits traits_type;
4413e519524SHoward Hinnant    typedef basic_ostream<charT,traits> ostream_type;
4423e519524SHoward Hinnant
4433e519524SHoward Hinnant    ostream_iterator(ostream_type& s);
4443e519524SHoward Hinnant    ostream_iterator(ostream_type& s, const charT* delimiter);
4453e519524SHoward Hinnant    ostream_iterator(const ostream_iterator& x);
4463e519524SHoward Hinnant    ~ostream_iterator();
4473e519524SHoward Hinnant    ostream_iterator& operator=(const T& value);
4483e519524SHoward Hinnant
4493e519524SHoward Hinnant    ostream_iterator& operator*();
4503e519524SHoward Hinnant    ostream_iterator& operator++();
4513e519524SHoward Hinnant    ostream_iterator& operator++(int);
4523e519524SHoward Hinnant};
4533e519524SHoward Hinnant
4543e519524SHoward Hinnanttemplate<class charT, class traits = char_traits<charT> >
4553e519524SHoward Hinnantclass istreambuf_iterator
45641bdf64dSLouis Dionne    : public iterator<input_iterator_tag, charT, traits::off_type, unspecified, charT> // until C++17
4573e519524SHoward Hinnant{
4583e519524SHoward Hinnantpublic:
45941bdf64dSLouis Dionne    typedef input_iterator_tag              iterator_category;
46041bdf64dSLouis Dionne    typedef charT                           value_type;
46141bdf64dSLouis Dionne    typedef traits::off_type                difference_type;
46241bdf64dSLouis Dionne    typedef unspecified                     pointer;
46341bdf64dSLouis Dionne    typedef charT                           reference;
46441bdf64dSLouis Dionne
4653e519524SHoward Hinnant    typedef charT                           char_type;
4663e519524SHoward Hinnant    typedef traits                          traits_type;
46741bdf64dSLouis Dionne    typedef traits::int_type                int_type;
4683e519524SHoward Hinnant    typedef basic_streambuf<charT, traits>  streambuf_type;
4693e519524SHoward Hinnant    typedef basic_istream<charT, traits>    istream_type;
4703e519524SHoward Hinnant
4718e882dcbSHoward Hinnant    istreambuf_iterator() noexcept;
4728e882dcbSHoward Hinnant    istreambuf_iterator(istream_type& s) noexcept;
4738e882dcbSHoward Hinnant    istreambuf_iterator(streambuf_type* s) noexcept;
4748e882dcbSHoward Hinnant    istreambuf_iterator(a-private-type) noexcept;
4753e519524SHoward Hinnant
4763e519524SHoward Hinnant    charT                operator*() const;
4773e519524SHoward Hinnant    pointer operator->() const;
4783e519524SHoward Hinnant    istreambuf_iterator& operator++();
4793e519524SHoward Hinnant    a-private-type       operator++(int);
4803e519524SHoward Hinnant
4813e519524SHoward Hinnant    bool equal(const istreambuf_iterator& b) const;
4823e519524SHoward Hinnant};
4833e519524SHoward Hinnant
4843e519524SHoward Hinnanttemplate <class charT, class traits>
4853e519524SHoward Hinnantbool operator==(const istreambuf_iterator<charT,traits>& a,
4863e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
4873e519524SHoward Hinnanttemplate <class charT, class traits>
4883e519524SHoward Hinnantbool operator!=(const istreambuf_iterator<charT,traits>& a,
4893e519524SHoward Hinnant                const istreambuf_iterator<charT,traits>& b);
4903e519524SHoward Hinnant
4913e519524SHoward Hinnanttemplate <class charT, class traits = char_traits<charT> >
4923e519524SHoward Hinnantclass ostreambuf_iterator
4931055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
4943e519524SHoward Hinnant{
4953e519524SHoward Hinnantpublic:
49641bdf64dSLouis Dionne    typedef output_iterator_tag            iterator_category;
49741bdf64dSLouis Dionne    typedef void                           value_type;
49841bdf64dSLouis Dionne    typedef void                           difference_type; // until C++20
49941bdf64dSLouis Dionne    typedef ptrdiff_t                      difference_type; // since C++20
50041bdf64dSLouis Dionne    typedef void                           pointer;
50141bdf64dSLouis Dionne    typedef void                           reference;
50241bdf64dSLouis Dionne
5033e519524SHoward Hinnant    typedef charT                          char_type;
5043e519524SHoward Hinnant    typedef traits                         traits_type;
5053e519524SHoward Hinnant    typedef basic_streambuf<charT, traits> streambuf_type;
5063e519524SHoward Hinnant    typedef basic_ostream<charT, traits>   ostream_type;
5073e519524SHoward Hinnant
5088e882dcbSHoward Hinnant    ostreambuf_iterator(ostream_type& s) noexcept;
5098e882dcbSHoward Hinnant    ostreambuf_iterator(streambuf_type* s) noexcept;
5103e519524SHoward Hinnant    ostreambuf_iterator& operator=(charT c);
5113e519524SHoward Hinnant    ostreambuf_iterator& operator*();
5123e519524SHoward Hinnant    ostreambuf_iterator& operator++();
5133e519524SHoward Hinnant    ostreambuf_iterator& operator++(int);
5148e882dcbSHoward Hinnant    bool failed() const noexcept;
5153e519524SHoward Hinnant};
5163e519524SHoward Hinnant
517020b623aSMarshall Clowtemplate <class C> constexpr auto begin(C& c) -> decltype(c.begin());
518020b623aSMarshall Clowtemplate <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
519020b623aSMarshall Clowtemplate <class C> constexpr auto end(C& c) -> decltype(c.end());
520020b623aSMarshall Clowtemplate <class C> constexpr auto end(const C& c) -> decltype(c.end());
521020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* begin(T (&array)[N]);
522020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* end(T (&array)[N]);
5233e519524SHoward Hinnant
524020b623aSMarshall Clowtemplate <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c));        // C++14
525020b623aSMarshall Clowtemplate <class C> auto constexpr cend(const C& c) -> decltype(std::end(c));            // C++14
526020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
527020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
528020b623aSMarshall Clowtemplate <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
529020b623aSMarshall Clowtemplate <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
530020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
531020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il);   // C++14
532020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
533020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
534020b623aSMarshall Clowtemplate <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
535020b623aSMarshall Clowtemplate <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
5361e548c72SMarshall Clow
537ad755104SMarshall Clow// 24.8, container access:
538ad755104SMarshall Clowtemplate <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
539ad755104SMarshall Clowtemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
5407d3986eaSMarshall Clow
5417d3986eaSMarshall Clowtemplate <class C> constexpr auto ssize(const C& c)
5427d3986eaSMarshall Clow    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;                    // C++20
5437d3986eaSMarshall Clowtemplate <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
5447d3986eaSMarshall Clow
545ad755104SMarshall Clowtemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
546ad755104SMarshall Clowtemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
547ad755104SMarshall Clowtemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
548ad755104SMarshall Clowtemplate <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
549ad755104SMarshall Clowtemplate <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
550ad755104SMarshall Clowtemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
551ad755104SMarshall Clowtemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
552ad755104SMarshall Clow
5533e519524SHoward Hinnant}  // std
5543e519524SHoward Hinnant
5553e519524SHoward Hinnant*/
5563e519524SHoward Hinnant
5573e519524SHoward Hinnant#include <__config>
5585f51fb34SArthur O'Dwyer#include <__debug>
559c204c130SMarshall Clow#include <__functional_base>
56036d0fdf9SChristopher Di Bella#include <__iterator/advance.h>
561*f32f3db9SLouis Dionne#include <__iterator/back_insert_iterator.h>
56257ebf3d0SLouis Dionne#include <__iterator/concepts.h>
563065cf3f9Szoecarver#include <__iterator/default_sentinel.h>
564*f32f3db9SLouis Dionne#include <__iterator/front_insert_iterator.h>
565e0adf7e0Szoecarver#include <__iterator/incrementable_traits.h>
566*f32f3db9SLouis Dionne#include <__iterator/insert_iterator.h>
567*f32f3db9SLouis Dionne#include <__iterator/istream_iterator.h>
568*f32f3db9SLouis Dionne#include <__iterator/istreambuf_iterator.h>
56997e383aaSLouis Dionne#include <__iterator/iter_move.h>
57040d6d2c4Szoecarver#include <__iterator/iter_swap.h>
571120fa829Szoecarver#include <__iterator/iterator_traits.h>
572*f32f3db9SLouis Dionne#include <__iterator/iterator.h>
573*f32f3db9SLouis Dionne#include <__iterator/move_iterator.h>
574857fa7b7SChristopher Di Bella#include <__iterator/next.h>
575*f32f3db9SLouis Dionne#include <__iterator/ostream_iterator.h>
576*f32f3db9SLouis Dionne#include <__iterator/ostreambuf_iterator.h>
5770dc7fd1bSChristopher Di Bella#include <__iterator/prev.h>
57858b29a4eSLouis Dionne#include <__iterator/projected.h>
579e0adf7e0Szoecarver#include <__iterator/readable_traits.h>
580*f32f3db9SLouis Dionne#include <__iterator/reverse_iterator.h>
581*f32f3db9SLouis Dionne#include <__iterator/wrap_iter.h>
582f992cfbaSLouis Dionne#include <__memory/addressof.h>
583d41c6d51SArthur O'Dwyer#include <__memory/pointer_traits.h>
5846adbc83eSChristopher Di Bella#include <__utility/forward.h>
5855f51fb34SArthur O'Dwyer#include <compare>
5865f51fb34SArthur O'Dwyer#include <concepts> // Mandated by the Standard.
5875f51fb34SArthur O'Dwyer#include <cstddef>
5885f51fb34SArthur O'Dwyer#include <initializer_list>
5895f51fb34SArthur O'Dwyer#include <type_traits>
590f56972e2SMarshall Clow#include <version>
591b5c63a2eSHoward Hinnant
592073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5933e519524SHoward Hinnant#pragma GCC system_header
594073458b1SHoward Hinnant#endif
5953e519524SHoward Hinnant
5963e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
597fe31f11cSChristopher Di Bella
5983e519524SHoward Hinnanttemplate <class _InputIter>
599f51ee632SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6003e519524SHoward Hinnanttypename iterator_traits<_InputIter>::difference_type
6013e519524SHoward Hinnant__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
6023e519524SHoward Hinnant{
6033e519524SHoward Hinnant    typename iterator_traits<_InputIter>::difference_type __r(0);
6043e519524SHoward Hinnant    for (; __first != __last; ++__first)
6053e519524SHoward Hinnant        ++__r;
6063e519524SHoward Hinnant    return __r;
6073e519524SHoward Hinnant}
6083e519524SHoward Hinnant
6093e519524SHoward Hinnanttemplate <class _RandIter>
610f51ee632SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6113e519524SHoward Hinnanttypename iterator_traits<_RandIter>::difference_type
6123e519524SHoward Hinnant__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
6133e519524SHoward Hinnant{
6143e519524SHoward Hinnant    return __last - __first;
6153e519524SHoward Hinnant}
6163e519524SHoward Hinnant
6173e519524SHoward Hinnanttemplate <class _InputIter>
618f51ee632SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6193e519524SHoward Hinnanttypename iterator_traits<_InputIter>::difference_type
6203e519524SHoward Hinnantdistance(_InputIter __first, _InputIter __last)
6213e519524SHoward Hinnant{
622c0428b3cSArthur O'Dwyer    return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
6233e519524SHoward Hinnant}
6243e519524SHoward Hinnant
6253772a46aSMarshall Clowtemplate <class _Tp, size_t _Np>
6262ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
6273772a46aSMarshall Clow_Tp*
6283772a46aSMarshall Clowbegin(_Tp (&__array)[_Np])
6293772a46aSMarshall Clow{
6303772a46aSMarshall Clow    return __array;
6313772a46aSMarshall Clow}
6323772a46aSMarshall Clow
6333772a46aSMarshall Clowtemplate <class _Tp, size_t _Np>
6342ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
6353772a46aSMarshall Clow_Tp*
6363772a46aSMarshall Clowend(_Tp (&__array)[_Np])
6373772a46aSMarshall Clow{
6383772a46aSMarshall Clow    return __array + _Np;
6393772a46aSMarshall Clow}
6403772a46aSMarshall Clow
64154613ab4SEric Fiselier#if !defined(_LIBCPP_CXX03_LANG)
642c66a611bSMarshall Clow
643c003db1fSHoward Hinnanttemplate <class _Cp>
6442ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6453e519524SHoward Hinnantauto
646c003db1fSHoward Hinnantbegin(_Cp& __c) -> decltype(__c.begin())
6473e519524SHoward Hinnant{
6483e519524SHoward Hinnant    return __c.begin();
6493e519524SHoward Hinnant}
6503e519524SHoward Hinnant
651c003db1fSHoward Hinnanttemplate <class _Cp>
6522ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6533e519524SHoward Hinnantauto
654c003db1fSHoward Hinnantbegin(const _Cp& __c) -> decltype(__c.begin())
6553e519524SHoward Hinnant{
6563e519524SHoward Hinnant    return __c.begin();
6573e519524SHoward Hinnant}
6583e519524SHoward Hinnant
659c003db1fSHoward Hinnanttemplate <class _Cp>
6602ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6613e519524SHoward Hinnantauto
662c003db1fSHoward Hinnantend(_Cp& __c) -> decltype(__c.end())
6633e519524SHoward Hinnant{
6643e519524SHoward Hinnant    return __c.end();
6653e519524SHoward Hinnant}
6663e519524SHoward Hinnant
667c003db1fSHoward Hinnanttemplate <class _Cp>
6682ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6693e519524SHoward Hinnantauto
670c003db1fSHoward Hinnantend(const _Cp& __c) -> decltype(__c.end())
6713e519524SHoward Hinnant{
6723e519524SHoward Hinnant    return __c.end();
6733e519524SHoward Hinnant}
6743e519524SHoward Hinnant
6751e548c72SMarshall Clow#if _LIBCPP_STD_VER > 11
6761e548c72SMarshall Clow
6773772a46aSMarshall Clowtemplate <class _Tp, size_t _Np>
6782ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6793772a46aSMarshall Clowreverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
6803772a46aSMarshall Clow{
6813772a46aSMarshall Clow    return reverse_iterator<_Tp*>(__array + _Np);
6823772a46aSMarshall Clow}
6833772a46aSMarshall Clow
6843772a46aSMarshall Clowtemplate <class _Tp, size_t _Np>
6852ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6863772a46aSMarshall Clowreverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
6873772a46aSMarshall Clow{
6883772a46aSMarshall Clow    return reverse_iterator<_Tp*>(__array);
6893772a46aSMarshall Clow}
6903772a46aSMarshall Clow
6913772a46aSMarshall Clowtemplate <class _Ep>
6922ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6933772a46aSMarshall Clowreverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
6943772a46aSMarshall Clow{
6953772a46aSMarshall Clow    return reverse_iterator<const _Ep*>(__il.end());
6963772a46aSMarshall Clow}
6973772a46aSMarshall Clow
6983772a46aSMarshall Clowtemplate <class _Ep>
6992ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7003772a46aSMarshall Clowreverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
7013772a46aSMarshall Clow{
7023772a46aSMarshall Clow    return reverse_iterator<const _Ep*>(__il.begin());
7033772a46aSMarshall Clow}
7043772a46aSMarshall Clow
7051e548c72SMarshall Clowtemplate <class _Cp>
7062ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
7077725546aSMarshall Clowauto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
7081e548c72SMarshall Clow{
7097725546aSMarshall Clow    return _VSTD::begin(__c);
7101e548c72SMarshall Clow}
7111e548c72SMarshall Clow
7121e548c72SMarshall Clowtemplate <class _Cp>
7132ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
7147725546aSMarshall Clowauto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
7151e548c72SMarshall Clow{
7167725546aSMarshall Clow    return _VSTD::end(__c);
7171e548c72SMarshall Clow}
7181e548c72SMarshall Clow
7191e548c72SMarshall Clowtemplate <class _Cp>
7202ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7211e548c72SMarshall Clowauto rbegin(_Cp& __c) -> decltype(__c.rbegin())
7221e548c72SMarshall Clow{
7231e548c72SMarshall Clow    return __c.rbegin();
7241e548c72SMarshall Clow}
7251e548c72SMarshall Clow
7261e548c72SMarshall Clowtemplate <class _Cp>
7272ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7281e548c72SMarshall Clowauto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
7291e548c72SMarshall Clow{
7301e548c72SMarshall Clow    return __c.rbegin();
7311e548c72SMarshall Clow}
7321e548c72SMarshall Clow
7331e548c72SMarshall Clowtemplate <class _Cp>
7342ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7351e548c72SMarshall Clowauto rend(_Cp& __c) -> decltype(__c.rend())
7361e548c72SMarshall Clow{
7371e548c72SMarshall Clow    return __c.rend();
7381e548c72SMarshall Clow}
7391e548c72SMarshall Clow
7401e548c72SMarshall Clowtemplate <class _Cp>
7412ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7421e548c72SMarshall Clowauto rend(const _Cp& __c) -> decltype(__c.rend())
7431e548c72SMarshall Clow{
7441e548c72SMarshall Clow    return __c.rend();
7451e548c72SMarshall Clow}
7461e548c72SMarshall Clow
7471e548c72SMarshall Clowtemplate <class _Cp>
7482ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7497725546aSMarshall Clowauto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
7501e548c72SMarshall Clow{
7517725546aSMarshall Clow    return _VSTD::rbegin(__c);
7521e548c72SMarshall Clow}
7531e548c72SMarshall Clow
7541e548c72SMarshall Clowtemplate <class _Cp>
7552ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7567725546aSMarshall Clowauto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
7571e548c72SMarshall Clow{
7587725546aSMarshall Clow    return _VSTD::rend(__c);
7591e548c72SMarshall Clow}
7601e548c72SMarshall Clow
7611e548c72SMarshall Clow#endif
7621e548c72SMarshall Clow
7631e548c72SMarshall Clow
76454613ab4SEric Fiselier#else  // defined(_LIBCPP_CXX03_LANG)
7653e519524SHoward Hinnant
766c003db1fSHoward Hinnanttemplate <class _Cp>
7672ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
768c003db1fSHoward Hinnanttypename _Cp::iterator
769c003db1fSHoward Hinnantbegin(_Cp& __c)
7703e519524SHoward Hinnant{
7713e519524SHoward Hinnant    return __c.begin();
7723e519524SHoward Hinnant}
7733e519524SHoward Hinnant
774c003db1fSHoward Hinnanttemplate <class _Cp>
7752ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
776c003db1fSHoward Hinnanttypename _Cp::const_iterator
777c003db1fSHoward Hinnantbegin(const _Cp& __c)
7783e519524SHoward Hinnant{
7793e519524SHoward Hinnant    return __c.begin();
7803e519524SHoward Hinnant}
7813e519524SHoward Hinnant
782c003db1fSHoward Hinnanttemplate <class _Cp>
7832ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
784c003db1fSHoward Hinnanttypename _Cp::iterator
785c003db1fSHoward Hinnantend(_Cp& __c)
7863e519524SHoward Hinnant{
7873e519524SHoward Hinnant    return __c.end();
7883e519524SHoward Hinnant}
7893e519524SHoward Hinnant
790c003db1fSHoward Hinnanttemplate <class _Cp>
7912ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
792c003db1fSHoward Hinnanttypename _Cp::const_iterator
793c003db1fSHoward Hinnantend(const _Cp& __c)
7943e519524SHoward Hinnant{
7953e519524SHoward Hinnant    return __c.end();
7963e519524SHoward Hinnant}
7973e519524SHoward Hinnant
79854613ab4SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
7993e519524SHoward Hinnant
800ad755104SMarshall Clow#if _LIBCPP_STD_VER > 14
801d1dcda19SMarshall Clow
802d1dcda19SMarshall Clow// #if _LIBCPP_STD_VER > 11
803d1dcda19SMarshall Clow// template <>
804d1dcda19SMarshall Clow// struct _LIBCPP_TEMPLATE_VIS plus<void>
805d1dcda19SMarshall Clow// {
806d1dcda19SMarshall Clow//     template <class _T1, class _T2>
807d1dcda19SMarshall Clow//     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
808d1dcda19SMarshall Clow//     auto operator()(_T1&& __t, _T2&& __u) const
809d1dcda19SMarshall Clow//     _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
810d1dcda19SMarshall Clow//     -> decltype        (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
811d1dcda19SMarshall Clow//         { return        _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
812d1dcda19SMarshall Clow//     typedef void is_transparent;
813d1dcda19SMarshall Clow// };
814d1dcda19SMarshall Clow// #endif
815d1dcda19SMarshall Clow
81688d21343SMarshall Clowtemplate <class _Cont>
8172ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
818d1dcda19SMarshall Clowconstexpr auto size(const _Cont& __c)
819d1dcda19SMarshall Clow_NOEXCEPT_(noexcept(__c.size()))
820d1dcda19SMarshall Clow-> decltype        (__c.size())
821d1dcda19SMarshall Clow{ return            __c.size(); }
822ad755104SMarshall Clow
82388d21343SMarshall Clowtemplate <class _Tp, size_t _Sz>
8242ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
825fd838227SEric Fiselierconstexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
826ad755104SMarshall Clow
8277d3986eaSMarshall Clow#if _LIBCPP_STD_VER > 17
8287d3986eaSMarshall Clowtemplate <class _Cont>
8292ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
8307d3986eaSMarshall Clowconstexpr auto ssize(const _Cont& __c)
8317d3986eaSMarshall Clow_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
8327d3986eaSMarshall Clow->                              common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
8337d3986eaSMarshall Clow{ return            static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
8347d3986eaSMarshall Clow
8357d3986eaSMarshall Clowtemplate <class _Tp, ptrdiff_t _Sz>
8362ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
8377d3986eaSMarshall Clowconstexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
8387d3986eaSMarshall Clow#endif
8397d3986eaSMarshall Clow
84088d21343SMarshall Clowtemplate <class _Cont>
8412ffa1705SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
842d1dcda19SMarshall Clowconstexpr auto empty(const _Cont& __c)
843d1dcda19SMarshall Clow_NOEXCEPT_(noexcept(__c.empty()))
844d1dcda19SMarshall Clow-> decltype        (__c.empty())
845d1dcda19SMarshall Clow{ return            __c.empty(); }
846ad755104SMarshall Clow
84788d21343SMarshall Clowtemplate <class _Tp, size_t _Sz>
8482ffa1705SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
849fd838227SEric Fiselierconstexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
850ad755104SMarshall Clow
851ad755104SMarshall Clowtemplate <class _Ep>
8522ffa1705SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
853ad755104SMarshall Clowconstexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
854ad755104SMarshall Clow
85588d21343SMarshall Clowtemplate <class _Cont> constexpr
8562ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
857d1dcda19SMarshall Clowauto data(_Cont& __c)
858d1dcda19SMarshall Clow_NOEXCEPT_(noexcept(__c.data()))
859d1dcda19SMarshall Clow-> decltype        (__c.data())
860d1dcda19SMarshall Clow{ return            __c.data(); }
861ad755104SMarshall Clow
86288d21343SMarshall Clowtemplate <class _Cont> constexpr
8632ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
864d1dcda19SMarshall Clowauto data(const _Cont& __c)
865d1dcda19SMarshall Clow_NOEXCEPT_(noexcept(__c.data()))
866d1dcda19SMarshall Clow-> decltype        (__c.data())
867d1dcda19SMarshall Clow{ return            __c.data(); }
868ad755104SMarshall Clow
86988d21343SMarshall Clowtemplate <class _Tp, size_t _Sz>
8702ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
87188d21343SMarshall Clowconstexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
872ad755104SMarshall Clow
873ad755104SMarshall Clowtemplate <class _Ep>
8742ffa1705SMarshall Clow_LIBCPP_INLINE_VISIBILITY
875ad755104SMarshall Clowconstexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
876ad755104SMarshall Clow#endif
877ad755104SMarshall Clow
8782ac6babcSArthur O'Dwyertemplate <class _Container, class _Predicate>
8792ac6babcSArthur O'Dwyertypename _Container::size_type
8802ac6babcSArthur O'Dwyer__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
8812ac6babcSArthur O'Dwyer  typename _Container::size_type __old_size = __c.size();
8822ac6babcSArthur O'Dwyer
8832ac6babcSArthur O'Dwyer  const typename _Container::iterator __last = __c.end();
8842ac6babcSArthur O'Dwyer  for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
8852ac6babcSArthur O'Dwyer    if (__pred(*__iter))
8862ac6babcSArthur O'Dwyer      __iter = __c.erase(__iter);
8872ac6babcSArthur O'Dwyer    else
8882ac6babcSArthur O'Dwyer      ++__iter;
8892ac6babcSArthur O'Dwyer  }
8902ac6babcSArthur O'Dwyer
8912ac6babcSArthur O'Dwyer  return __old_size - __c.size();
8922ac6babcSArthur O'Dwyer}
893ad755104SMarshall Clow
8943e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
8953e519524SHoward Hinnant
8963e519524SHoward Hinnant#endif // _LIBCPP_ITERATOR
897