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 155*eea3d90aSKonstantin Varlamov// [alg.req.permutable], concept permutable // since C++20 156*eea3d90aSKonstantin Varlamovtemplate<class I> 157*eea3d90aSKonstantin Varlamov concept permutable = see below; 158*eea3d90aSKonstantin Varlamov 159*eea3d90aSKonstantin Varlamov // [alg.req.mergeable], concept mergeable 160*eea3d90aSKonstantin Varlamovtemplate<class I1, class I2, class Out, 161*eea3d90aSKonstantin Varlamov class R = ranges::less, class P1 = identity, class P2 = identity> 162*eea3d90aSKonstantin Varlamov concept mergeable = see below; // since C++20 163*eea3d90aSKonstantin Varlamov 1641a29403dSzoecarvertemplate<input_or_output_iterator I, sentinel_for<I> S> 1651a29403dSzoecarver requires (!same_as<I, S> && copyable<I>) 1661a29403dSzoecarverclass common_iterator; // since C++20 1671a29403dSzoecarver 1683e519524SHoward Hinnanttemplate<class Category, class T, class Distance = ptrdiff_t, 1693e519524SHoward Hinnant class Pointer = T*, class Reference = T&> 1701055cb91SLouis Dionnestruct iterator // deprecated in C++17 1713e519524SHoward Hinnant{ 1723e519524SHoward Hinnant typedef T value_type; 1733e519524SHoward Hinnant typedef Distance difference_type; 1743e519524SHoward Hinnant typedef Pointer pointer; 1753e519524SHoward Hinnant typedef Reference reference; 1763e519524SHoward Hinnant typedef Category iterator_category; 1773e519524SHoward Hinnant}; 1783e519524SHoward Hinnant 1793e519524SHoward Hinnantstruct input_iterator_tag {}; 1803e519524SHoward Hinnantstruct output_iterator_tag {}; 1813e519524SHoward Hinnantstruct forward_iterator_tag : public input_iterator_tag {}; 1823e519524SHoward Hinnantstruct bidirectional_iterator_tag : public forward_iterator_tag {}; 1833e519524SHoward Hinnantstruct random_access_iterator_tag : public bidirectional_iterator_tag {}; 184f681d7d5SKonstantin Varlamovstruct contiguous_iterator_tag : public random_access_iterator_tag {}; 1853e519524SHoward Hinnant 186f51ee632SMarshall Clow// 27.4.3, iterator operations 18712b01ab7SLouis Dionnetemplate <class InputIterator, class Distance> // constexpr in C++17 18812b01ab7SLouis Dionne constexpr void advance(InputIterator& i, Distance n); 1893e519524SHoward Hinnant 190f51ee632SMarshall Clowtemplate <class InputIterator> // constexpr in C++17 191f51ee632SMarshall Clow constexpr typename iterator_traits<InputIterator>::difference_type 1923e519524SHoward Hinnant distance(InputIterator first, InputIterator last); 1933e519524SHoward Hinnant 194f51ee632SMarshall Clowtemplate <class InputIterator> // constexpr in C++17 195f51ee632SMarshall Clow constexpr InputIterator next(InputIterator x, 196f51ee632SMarshall Clowtypename iterator_traits<InputIterator>::difference_type n = 1); 197f51ee632SMarshall Clow 198f51ee632SMarshall Clowtemplate <class BidirectionalIterator> // constexpr in C++17 199f51ee632SMarshall Clow constexpr BidirectionalIterator prev(BidirectionalIterator x, 200f51ee632SMarshall Clow typename iterator_traits<BidirectionalIterator>::difference_type n = 1); 201f51ee632SMarshall Clow 20236d0fdf9SChristopher Di Bella// [range.iter.ops], range iterator operations 20336d0fdf9SChristopher Di Bellanamespace ranges { 20436d0fdf9SChristopher Di Bella // [range.iter.op.advance], ranges::advance 20536d0fdf9SChristopher Di Bella template<input_or_output_iterator I> 20636d0fdf9SChristopher Di Bella constexpr void advance(I& i, iter_difference_t<I> n); // since C++20 20736d0fdf9SChristopher Di Bella template<input_or_output_iterator I, sentinel_for<I> S> 20836d0fdf9SChristopher Di Bella constexpr void advance(I& i, S bound); // since C++20 20936d0fdf9SChristopher Di Bella template<input_or_output_iterator I, sentinel_for<I> S> 21036d0fdf9SChristopher Di Bella constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound); // since C++20 21136d0fdf9SChristopher Di Bella} 21236d0fdf9SChristopher Di Bella 2133e519524SHoward Hinnanttemplate <class Iterator> 2143e519524SHoward Hinnantclass reverse_iterator 2151055cb91SLouis Dionne : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17 2163e519524SHoward Hinnant typename iterator_traits<Iterator>::value_type, 2173e519524SHoward Hinnant typename iterator_traits<Iterator>::difference_type, 2183e519524SHoward Hinnant typename iterator_traits<Iterator>::pointer, 2193e519524SHoward Hinnant typename iterator_traits<Iterator>::reference> 2203e519524SHoward Hinnant{ 2213e519524SHoward Hinnantprotected: 2223e519524SHoward Hinnant Iterator current; 2233e519524SHoward Hinnantpublic: 2243e519524SHoward Hinnant typedef Iterator iterator_type; 2253e519524SHoward Hinnant typedef typename iterator_traits<Iterator>::difference_type difference_type; 2263e519524SHoward Hinnant typedef typename iterator_traits<Iterator>::reference reference; 2273e519524SHoward Hinnant typedef typename iterator_traits<Iterator>::pointer pointer; 2283e519524SHoward Hinnant 2291b8f260eSMarshall Clow constexpr reverse_iterator(); 2301b8f260eSMarshall Clow constexpr explicit reverse_iterator(Iterator x); 2311b8f260eSMarshall Clow template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u); 2321b8f260eSMarshall Clow template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u); 2331b8f260eSMarshall Clow constexpr Iterator base() const; 2341b8f260eSMarshall Clow constexpr reference operator*() const; 2351b8f260eSMarshall Clow constexpr pointer operator->() const; 2361b8f260eSMarshall Clow constexpr reverse_iterator& operator++(); 2371b8f260eSMarshall Clow constexpr reverse_iterator operator++(int); 2381b8f260eSMarshall Clow constexpr reverse_iterator& operator--(); 2391b8f260eSMarshall Clow constexpr reverse_iterator operator--(int); 2401b8f260eSMarshall Clow constexpr reverse_iterator operator+ (difference_type n) const; 2411b8f260eSMarshall Clow constexpr reverse_iterator& operator+=(difference_type n); 2421b8f260eSMarshall Clow constexpr reverse_iterator operator- (difference_type n) const; 2431b8f260eSMarshall Clow constexpr reverse_iterator& operator-=(difference_type n); 2441b8f260eSMarshall Clow constexpr reference operator[](difference_type n) const; 2453e519524SHoward Hinnant}; 2463e519524SHoward Hinnant 2473e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2481b8f260eSMarshall Clowconstexpr bool // constexpr in C++17 2493e519524SHoward Hinnantoperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); 2503e519524SHoward Hinnant 2513e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2521b8f260eSMarshall Clowconstexpr bool // constexpr in C++17 2533e519524SHoward Hinnantoperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); 2543e519524SHoward Hinnant 2553e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2561b8f260eSMarshall Clowconstexpr bool // constexpr in C++17 2573e519524SHoward Hinnantoperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); 2583e519524SHoward Hinnant 2593e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2601b8f260eSMarshall Clowconstexpr bool // constexpr in C++17 2613e519524SHoward Hinnantoperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); 2623e519524SHoward Hinnant 2633e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2641b8f260eSMarshall Clowconstexpr bool // constexpr in C++17 2653e519524SHoward Hinnantoperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); 2663e519524SHoward Hinnant 2673e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2681b8f260eSMarshall Clowconstexpr bool // constexpr in C++17 2693e519524SHoward Hinnantoperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); 2703e519524SHoward Hinnant 2713e519524SHoward Hinnanttemplate <class Iterator1, class Iterator2> 2721b8f260eSMarshall Clowconstexpr auto 273947ce6b5SMarshall Clowoperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) 2741b8f260eSMarshall Clow-> decltype(__y.base() - __x.base()); // constexpr in C++17 2753e519524SHoward Hinnant 2763e519524SHoward Hinnanttemplate <class Iterator> 2771b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator> 2781b8f260eSMarshall Clowoperator+(typename reverse_iterator<Iterator>::difference_type n, 2791b8f260eSMarshall Clow const reverse_iterator<Iterator>& x); // constexpr in C++17 2803e519524SHoward Hinnant 2811b8f260eSMarshall Clowtemplate <class Iterator> 2821b8f260eSMarshall Clowconstexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17 2836a640a18SMarshall Clow 2843e519524SHoward Hinnanttemplate <class Container> 2853e519524SHoward Hinnantclass back_insert_iterator 28641bdf64dSLouis Dionne : public iterator<output_iterator_tag, void, void, void, void> // until C++17 2873e519524SHoward Hinnant{ 2883e519524SHoward Hinnantprotected: 2893e519524SHoward Hinnant Container* container; 2903e519524SHoward Hinnantpublic: 2913e519524SHoward Hinnant typedef Container container_type; 2923e519524SHoward Hinnant typedef void value_type; 29341bdf64dSLouis Dionne typedef void difference_type; // until C++20 29441bdf64dSLouis Dionne typedef ptrdiff_t difference_type; // since C++20 2958892b4eeSEric Fiselier typedef void reference; 2963e519524SHoward Hinnant typedef void pointer; 2973e519524SHoward Hinnant 29806e2b737SArthur O'Dwyer explicit back_insert_iterator(Container& x); // constexpr in C++20 29906e2b737SArthur O'Dwyer back_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20 30006e2b737SArthur O'Dwyer back_insert_iterator& operator*(); // constexpr in C++20 30106e2b737SArthur O'Dwyer back_insert_iterator& operator++(); // constexpr in C++20 30206e2b737SArthur O'Dwyer back_insert_iterator operator++(int); // constexpr in C++20 3033e519524SHoward Hinnant}; 3043e519524SHoward Hinnant 30506e2b737SArthur O'Dwyertemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x); // constexpr in C++20 3063e519524SHoward Hinnant 3073e519524SHoward Hinnanttemplate <class Container> 3083e519524SHoward Hinnantclass front_insert_iterator 30941bdf64dSLouis Dionne : public iterator<output_iterator_tag, void, void, void, void> // until C++17 3103e519524SHoward Hinnant{ 3113e519524SHoward Hinnantprotected: 3123e519524SHoward Hinnant Container* container; 3133e519524SHoward Hinnantpublic: 3143e519524SHoward Hinnant typedef Container container_type; 3153e519524SHoward Hinnant typedef void value_type; 31641bdf64dSLouis Dionne typedef void difference_type; // until C++20 31741bdf64dSLouis Dionne typedef ptrdiff_t difference_type; // since C++20 3188892b4eeSEric Fiselier typedef void reference; 3193e519524SHoward Hinnant typedef void pointer; 3203e519524SHoward Hinnant 32106e2b737SArthur O'Dwyer explicit front_insert_iterator(Container& x); // constexpr in C++20 32206e2b737SArthur O'Dwyer front_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20 32306e2b737SArthur O'Dwyer front_insert_iterator& operator*(); // constexpr in C++20 32406e2b737SArthur O'Dwyer front_insert_iterator& operator++(); // constexpr in C++20 32506e2b737SArthur O'Dwyer front_insert_iterator operator++(int); // constexpr in C++20 3263e519524SHoward Hinnant}; 3273e519524SHoward Hinnant 32806e2b737SArthur O'Dwyertemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x); // constexpr in C++20 3293e519524SHoward Hinnant 3303e519524SHoward Hinnanttemplate <class Container> 3313e519524SHoward Hinnantclass insert_iterator 33241bdf64dSLouis Dionne : public iterator<output_iterator_tag, void, void, void, void> // until C++17 3333e519524SHoward Hinnant{ 3343e519524SHoward Hinnantprotected: 3353e519524SHoward Hinnant Container* container; 3363e519524SHoward Hinnant typename Container::iterator iter; 3373e519524SHoward Hinnantpublic: 3383e519524SHoward Hinnant typedef Container container_type; 3393e519524SHoward Hinnant typedef void value_type; 34041bdf64dSLouis Dionne typedef void difference_type; // until C++20 34141bdf64dSLouis Dionne typedef ptrdiff_t difference_type; // since C++20 3428892b4eeSEric Fiselier typedef void reference; 3433e519524SHoward Hinnant typedef void pointer; 3443e519524SHoward Hinnant 34506e2b737SArthur O'Dwyer insert_iterator(Container& x, typename Container::iterator i); // constexpr in C++20 34606e2b737SArthur O'Dwyer insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20 34706e2b737SArthur O'Dwyer insert_iterator& operator*(); // constexpr in C++20 34806e2b737SArthur O'Dwyer insert_iterator& operator++(); // constexpr in C++20 34906e2b737SArthur O'Dwyer insert_iterator& operator++(int); // constexpr in C++20 3503e519524SHoward Hinnant}; 3513e519524SHoward Hinnant 3522151b3d0SKonstantin Varlamovtemplate <class Container> 3532151b3d0SKonstantin Varlamovinsert_iterator<Container> inserter(Container& x, typename Container::iterator i); // until C++20 3542151b3d0SKonstantin Varlamovtemplate <class Container> 3552151b3d0SKonstantin Varlamovconstexpr insert_iterator<Container> inserter(Container& x, ranges::iterator_t<Container> i); // since C++20 3563e519524SHoward Hinnant 357947ce6b5SMarshall Clowtemplate <class Iterator> 358947ce6b5SMarshall Clowclass move_iterator { 359947ce6b5SMarshall Clowpublic: 360947ce6b5SMarshall Clow typedef Iterator iterator_type; 361947ce6b5SMarshall Clow typedef typename iterator_traits<Iterator>::difference_type difference_type; 362947ce6b5SMarshall Clow typedef Iterator pointer; 363947ce6b5SMarshall Clow typedef typename iterator_traits<Iterator>::value_type value_type; 364947ce6b5SMarshall Clow typedef typename iterator_traits<Iterator>::iterator_category iterator_category; 365947ce6b5SMarshall Clow typedef value_type&& reference; 366947ce6b5SMarshall Clow 367720ef472SMarshall Clow constexpr move_iterator(); // all the constexprs are in C++17 368720ef472SMarshall Clow constexpr explicit move_iterator(Iterator i); 369720ef472SMarshall Clow template <class U> 370720ef472SMarshall Clow constexpr move_iterator(const move_iterator<U>& u); 371720ef472SMarshall Clow template <class U> 372720ef472SMarshall Clow constexpr move_iterator& operator=(const move_iterator<U>& u); 373720ef472SMarshall Clow constexpr iterator_type base() const; 374720ef472SMarshall Clow constexpr reference operator*() const; 375720ef472SMarshall Clow constexpr pointer operator->() const; 376720ef472SMarshall Clow constexpr move_iterator& operator++(); 377720ef472SMarshall Clow constexpr move_iterator operator++(int); 378720ef472SMarshall Clow constexpr move_iterator& operator--(); 379720ef472SMarshall Clow constexpr move_iterator operator--(int); 380720ef472SMarshall Clow constexpr move_iterator operator+(difference_type n) const; 381720ef472SMarshall Clow constexpr move_iterator& operator+=(difference_type n); 382720ef472SMarshall Clow constexpr move_iterator operator-(difference_type n) const; 383720ef472SMarshall Clow constexpr move_iterator& operator-=(difference_type n); 384720ef472SMarshall Clow constexpr unspecified operator[](difference_type n) const; 385947ce6b5SMarshall Clowprivate: 386947ce6b5SMarshall Clow Iterator current; // exposition only 387947ce6b5SMarshall Clow}; 388947ce6b5SMarshall Clow 389947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 390720ef472SMarshall Clowconstexpr bool // constexpr in C++17 391947ce6b5SMarshall Clowoperator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); 392947ce6b5SMarshall Clow 393947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 394720ef472SMarshall Clowconstexpr bool // constexpr in C++17 395947ce6b5SMarshall Clowoperator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); 396947ce6b5SMarshall Clow 397947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 398720ef472SMarshall Clowconstexpr bool // constexpr in C++17 399947ce6b5SMarshall Clowoperator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); 400947ce6b5SMarshall Clow 401947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 402720ef472SMarshall Clowconstexpr bool // constexpr in C++17 403947ce6b5SMarshall Clowoperator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); 404947ce6b5SMarshall Clow 405947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 406720ef472SMarshall Clowconstexpr bool // constexpr in C++17 407947ce6b5SMarshall Clowoperator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); 408947ce6b5SMarshall Clow 409947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 410720ef472SMarshall Clowconstexpr bool // constexpr in C++17 411947ce6b5SMarshall Clowoperator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); 412947ce6b5SMarshall Clow 413947ce6b5SMarshall Clowtemplate <class Iterator1, class Iterator2> 414720ef472SMarshall Clowconstexpr auto // constexpr in C++17 415947ce6b5SMarshall Clowoperator-(const move_iterator<Iterator1>& x, 416947ce6b5SMarshall Clow const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base()); 417947ce6b5SMarshall Clow 418947ce6b5SMarshall Clowtemplate <class Iterator> 419720ef472SMarshall Clowconstexpr move_iterator<Iterator> operator+( // constexpr in C++17 420720ef472SMarshall Clow typename move_iterator<Iterator>::difference_type n, 421947ce6b5SMarshall Clow const move_iterator<Iterator>& x); 422947ce6b5SMarshall Clow 423720ef472SMarshall Clowtemplate <class Iterator> // constexpr in C++17 424720ef472SMarshall Clowconstexpr move_iterator<Iterator> make_move_iterator(const Iterator& i); 425947ce6b5SMarshall Clow 426065cf3f9Szoecarver// [default.sentinel], default sentinel 427065cf3f9Szoecarverstruct default_sentinel_t; 428065cf3f9Szoecarverinline constexpr default_sentinel_t default_sentinel{}; 429947ce6b5SMarshall Clow 4308a48e6ddSzoecarver// [iterators.counted], counted iterators 4318a48e6ddSzoecarvertemplate<input_or_output_iterator I> class counted_iterator; 4328a48e6ddSzoecarver 4338a48e6ddSzoecarvertemplate<input_iterator I> 4348a48e6ddSzoecarver requires see below 4358a48e6ddSzoecarver struct iterator_traits<counted_iterator<I>>; 4368a48e6ddSzoecarver 4374ac87e33Szoecarver// [unreachable.sentinel], unreachable sentinel 4384ac87e33Szoecarverstruct unreachable_sentinel_t; 4394ac87e33Szoecarverinline constexpr unreachable_sentinel_t unreachable_sentinel{}; 4404ac87e33Szoecarver 4413e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> 4423e519524SHoward Hinnantclass istream_iterator 4431055cb91SLouis Dionne : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17 4443e519524SHoward Hinnant{ 4453e519524SHoward Hinnantpublic: 44641bdf64dSLouis Dionne typedef input_iterator_tag iterator_category; 44741bdf64dSLouis Dionne typedef T value_type; 44841bdf64dSLouis Dionne typedef Distance difference_type; 44941bdf64dSLouis Dionne typedef const T* pointer; 45041bdf64dSLouis Dionne typedef const T& reference; 45141bdf64dSLouis Dionne 4523e519524SHoward Hinnant typedef charT char_type; 4533e519524SHoward Hinnant typedef traits traits_type; 4543e519524SHoward Hinnant typedef basic_istream<charT, traits> istream_type; 4553e519524SHoward Hinnant 45643bc1e56SKonstantin Varlamov istream_iterator(); // constexpr since C++11 45743bc1e56SKonstantin Varlamov constexpr istream_iterator(default_sentinel_t); // since C++20 4583e519524SHoward Hinnant istream_iterator(istream_type& s); 4593e519524SHoward Hinnant istream_iterator(const istream_iterator& x); 4603e519524SHoward Hinnant ~istream_iterator(); 4613e519524SHoward Hinnant 4623e519524SHoward Hinnant const T& operator*() const; 4633e519524SHoward Hinnant const T* operator->() const; 4643e519524SHoward Hinnant istream_iterator& operator++(); 4653e519524SHoward Hinnant istream_iterator operator++(int); 46643bc1e56SKonstantin Varlamov friend bool operator==(const istream_iterator& i, default_sentinel_t); // since C++20 4673e519524SHoward Hinnant}; 4683e519524SHoward Hinnant 4693e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance> 4703e519524SHoward Hinnantbool operator==(const istream_iterator<T,charT,traits,Distance>& x, 4713e519524SHoward Hinnant const istream_iterator<T,charT,traits,Distance>& y); 4723e519524SHoward Hinnanttemplate <class T, class charT, class traits, class Distance> 4733e519524SHoward Hinnantbool operator!=(const istream_iterator<T,charT,traits,Distance>& x, 47443bc1e56SKonstantin Varlamov const istream_iterator<T,charT,traits,Distance>& y); // until C++20 4753e519524SHoward Hinnant 4763e519524SHoward Hinnanttemplate <class T, class charT = char, class traits = char_traits<charT> > 4773e519524SHoward Hinnantclass ostream_iterator 4781055cb91SLouis Dionne : public iterator<output_iterator_tag, void, void, void, void> // until C++17 4793e519524SHoward Hinnant{ 4803e519524SHoward Hinnantpublic: 48141bdf64dSLouis Dionne typedef output_iterator_tag iterator_category; 48241bdf64dSLouis Dionne typedef void value_type; 48341bdf64dSLouis Dionne typedef void difference_type; // until C++20 48441bdf64dSLouis Dionne typedef ptrdiff_t difference_type; // since C++20 48541bdf64dSLouis Dionne typedef void pointer; 48641bdf64dSLouis Dionne typedef void reference; 48741bdf64dSLouis Dionne 4883e519524SHoward Hinnant typedef charT char_type; 4893e519524SHoward Hinnant typedef traits traits_type; 4903e519524SHoward Hinnant typedef basic_ostream<charT,traits> ostream_type; 4913e519524SHoward Hinnant 4923e519524SHoward Hinnant ostream_iterator(ostream_type& s); 4933e519524SHoward Hinnant ostream_iterator(ostream_type& s, const charT* delimiter); 4943e519524SHoward Hinnant ostream_iterator(const ostream_iterator& x); 4953e519524SHoward Hinnant ~ostream_iterator(); 4963e519524SHoward Hinnant ostream_iterator& operator=(const T& value); 4973e519524SHoward Hinnant 4983e519524SHoward Hinnant ostream_iterator& operator*(); 4993e519524SHoward Hinnant ostream_iterator& operator++(); 5003e519524SHoward Hinnant ostream_iterator& operator++(int); 5013e519524SHoward Hinnant}; 5023e519524SHoward Hinnant 5033e519524SHoward Hinnanttemplate<class charT, class traits = char_traits<charT> > 5043e519524SHoward Hinnantclass istreambuf_iterator 50541bdf64dSLouis Dionne : public iterator<input_iterator_tag, charT, traits::off_type, unspecified, charT> // until C++17 5063e519524SHoward Hinnant{ 5073e519524SHoward Hinnantpublic: 50841bdf64dSLouis Dionne typedef input_iterator_tag iterator_category; 50941bdf64dSLouis Dionne typedef charT value_type; 51041bdf64dSLouis Dionne typedef traits::off_type difference_type; 51141bdf64dSLouis Dionne typedef unspecified pointer; 51241bdf64dSLouis Dionne typedef charT reference; 51341bdf64dSLouis Dionne 5143e519524SHoward Hinnant typedef charT char_type; 5153e519524SHoward Hinnant typedef traits traits_type; 51641bdf64dSLouis Dionne typedef traits::int_type int_type; 5173e519524SHoward Hinnant typedef basic_streambuf<charT, traits> streambuf_type; 5183e519524SHoward Hinnant typedef basic_istream<charT, traits> istream_type; 5193e519524SHoward Hinnant 52043bc1e56SKonstantin Varlamov istreambuf_iterator() noexcept; // constexpr since C++11 52143bc1e56SKonstantin Varlamov constexpr istreambuf_iterator(default_sentinel_t) noexcept; // since C++20 5228e882dcbSHoward Hinnant istreambuf_iterator(istream_type& s) noexcept; 5238e882dcbSHoward Hinnant istreambuf_iterator(streambuf_type* s) noexcept; 5248e882dcbSHoward Hinnant istreambuf_iterator(a-private-type) noexcept; 5253e519524SHoward Hinnant 5263e519524SHoward Hinnant charT operator*() const; 5273e519524SHoward Hinnant pointer operator->() const; 5283e519524SHoward Hinnant istreambuf_iterator& operator++(); 5293e519524SHoward Hinnant a-private-type operator++(int); 5303e519524SHoward Hinnant 5313e519524SHoward Hinnant bool equal(const istreambuf_iterator& b) const; 53243bc1e56SKonstantin Varlamov friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); // since C++20 5333e519524SHoward Hinnant}; 5343e519524SHoward Hinnant 5353e519524SHoward Hinnanttemplate <class charT, class traits> 5363e519524SHoward Hinnantbool operator==(const istreambuf_iterator<charT,traits>& a, 5373e519524SHoward Hinnant const istreambuf_iterator<charT,traits>& b); 5383e519524SHoward Hinnanttemplate <class charT, class traits> 5393e519524SHoward Hinnantbool operator!=(const istreambuf_iterator<charT,traits>& a, 54043bc1e56SKonstantin Varlamov const istreambuf_iterator<charT,traits>& b); // until C++20 5413e519524SHoward Hinnant 5423e519524SHoward Hinnanttemplate <class charT, class traits = char_traits<charT> > 5433e519524SHoward Hinnantclass ostreambuf_iterator 5441055cb91SLouis Dionne : public iterator<output_iterator_tag, void, void, void, void> // until C++17 5453e519524SHoward Hinnant{ 5463e519524SHoward Hinnantpublic: 54741bdf64dSLouis Dionne typedef output_iterator_tag iterator_category; 54841bdf64dSLouis Dionne typedef void value_type; 54941bdf64dSLouis Dionne typedef void difference_type; // until C++20 55041bdf64dSLouis Dionne typedef ptrdiff_t difference_type; // since C++20 55141bdf64dSLouis Dionne typedef void pointer; 55241bdf64dSLouis Dionne typedef void reference; 55341bdf64dSLouis Dionne 5543e519524SHoward Hinnant typedef charT char_type; 5553e519524SHoward Hinnant typedef traits traits_type; 5563e519524SHoward Hinnant typedef basic_streambuf<charT, traits> streambuf_type; 5573e519524SHoward Hinnant typedef basic_ostream<charT, traits> ostream_type; 5583e519524SHoward Hinnant 5598e882dcbSHoward Hinnant ostreambuf_iterator(ostream_type& s) noexcept; 5608e882dcbSHoward Hinnant ostreambuf_iterator(streambuf_type* s) noexcept; 5613e519524SHoward Hinnant ostreambuf_iterator& operator=(charT c); 5623e519524SHoward Hinnant ostreambuf_iterator& operator*(); 5633e519524SHoward Hinnant ostreambuf_iterator& operator++(); 5643e519524SHoward Hinnant ostreambuf_iterator& operator++(int); 5658e882dcbSHoward Hinnant bool failed() const noexcept; 5663e519524SHoward Hinnant}; 5673e519524SHoward Hinnant 568020b623aSMarshall Clowtemplate <class C> constexpr auto begin(C& c) -> decltype(c.begin()); 569020b623aSMarshall Clowtemplate <class C> constexpr auto begin(const C& c) -> decltype(c.begin()); 570020b623aSMarshall Clowtemplate <class C> constexpr auto end(C& c) -> decltype(c.end()); 571020b623aSMarshall Clowtemplate <class C> constexpr auto end(const C& c) -> decltype(c.end()); 572020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* begin(T (&array)[N]); 573020b623aSMarshall Clowtemplate <class T, size_t N> constexpr T* end(T (&array)[N]); 5743e519524SHoward Hinnant 575020b623aSMarshall Clowtemplate <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c)); // C++14 576020b623aSMarshall Clowtemplate <class C> auto constexpr cend(const C& c) -> decltype(std::end(c)); // C++14 577020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin()); // C++14 578020b623aSMarshall Clowtemplate <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin()); // C++14 579020b623aSMarshall Clowtemplate <class C> auto constexpr rend(C& c) -> decltype(c.rend()); // C++14 580020b623aSMarshall Clowtemplate <class C> constexpr auto rend(const C& c) -> decltype(c.rend()); // C++14 581020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14 582020b623aSMarshall Clowtemplate <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il); // C++14 583020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]); // C++14 584020b623aSMarshall Clowtemplate <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]); // C++14 585020b623aSMarshall Clowtemplate <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14 586020b623aSMarshall Clowtemplate <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c)); // C++14 5871e548c72SMarshall Clow 588ad755104SMarshall Clow// 24.8, container access: 589ad755104SMarshall Clowtemplate <class C> constexpr auto size(const C& c) -> decltype(c.size()); // C++17 590ad755104SMarshall Clowtemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17 5917d3986eaSMarshall Clow 5927d3986eaSMarshall Clowtemplate <class C> constexpr auto ssize(const C& c) 5937d3986eaSMarshall Clow -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>; // C++20 5947d3986eaSMarshall Clowtemplate <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20 5957d3986eaSMarshall Clow 596ad755104SMarshall Clowtemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty()); // C++17 597ad755104SMarshall Clowtemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept; // C++17 598ad755104SMarshall Clowtemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept; // C++17 599ad755104SMarshall Clowtemplate <class C> constexpr auto data(C& c) -> decltype(c.data()); // C++17 600ad755104SMarshall Clowtemplate <class C> constexpr auto data(const C& c) -> decltype(c.data()); // C++17 601ad755104SMarshall Clowtemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept; // C++17 602ad755104SMarshall Clowtemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept; // C++17 603ad755104SMarshall Clow 6043e519524SHoward Hinnant} // std 6053e519524SHoward Hinnant 6063e519524SHoward Hinnant*/ 6073e519524SHoward Hinnant 6083e519524SHoward Hinnant#include <__config> 6095f51fb34SArthur O'Dwyer#include <__debug> 6108517a26dSChristopher Di Bella#include <__iterator/access.h> 61136d0fdf9SChristopher Di Bella#include <__iterator/advance.h> 612f32f3db9SLouis Dionne#include <__iterator/back_insert_iterator.h> 6131a29403dSzoecarver#include <__iterator/common_iterator.h> 61457ebf3d0SLouis Dionne#include <__iterator/concepts.h> 6158a48e6ddSzoecarver#include <__iterator/counted_iterator.h> 6168517a26dSChristopher Di Bella#include <__iterator/data.h> 617065cf3f9Szoecarver#include <__iterator/default_sentinel.h> 6188517a26dSChristopher Di Bella#include <__iterator/distance.h> 6198517a26dSChristopher Di Bella#include <__iterator/empty.h> 6208517a26dSChristopher Di Bella#include <__iterator/erase_if_container.h> 621f32f3db9SLouis Dionne#include <__iterator/front_insert_iterator.h> 622e0adf7e0Szoecarver#include <__iterator/incrementable_traits.h> 6236d722801SNikolas Klauser#include <__iterator/indirectly_comparable.h> 624f32f3db9SLouis Dionne#include <__iterator/insert_iterator.h> 6258517a26dSChristopher Di Bella#include <__iterator/istream_iterator.h> 6264d81a46fSArthur O'Dwyer#include <__iterator/istreambuf_iterator.h> 62797e383aaSLouis Dionne#include <__iterator/iter_move.h> 62840d6d2c4Szoecarver#include <__iterator/iter_swap.h> 6294d81a46fSArthur O'Dwyer#include <__iterator/iterator.h> 6304d81a46fSArthur O'Dwyer#include <__iterator/iterator_traits.h> 631*eea3d90aSKonstantin Varlamov#include <__iterator/mergeable.h> 632f32f3db9SLouis Dionne#include <__iterator/move_iterator.h> 633857fa7b7SChristopher Di Bella#include <__iterator/next.h> 6348517a26dSChristopher Di Bella#include <__iterator/ostream_iterator.h> 6354d81a46fSArthur O'Dwyer#include <__iterator/ostreambuf_iterator.h> 6368f1d8785SKonstantin Varlamov#include <__iterator/permutable.h> 6370dc7fd1bSChristopher Di Bella#include <__iterator/prev.h> 63858b29a4eSLouis Dionne#include <__iterator/projected.h> 639e0adf7e0Szoecarver#include <__iterator/readable_traits.h> 6408517a26dSChristopher Di Bella#include <__iterator/reverse_access.h> 641f32f3db9SLouis Dionne#include <__iterator/reverse_iterator.h> 6428517a26dSChristopher Di Bella#include <__iterator/size.h> 6434ac87e33Szoecarver#include <__iterator/unreachable_sentinel.h> 644f32f3db9SLouis Dionne#include <__iterator/wrap_iter.h> 645f992cfbaSLouis Dionne#include <__memory/addressof.h> 646d41c6d51SArthur O'Dwyer#include <__memory/pointer_traits.h> 6475f51fb34SArthur O'Dwyer#include <compare> 6485f51fb34SArthur O'Dwyer#include <concepts> // Mandated by the Standard. 6495f51fb34SArthur O'Dwyer#include <cstddef> 6505f51fb34SArthur O'Dwyer#include <initializer_list> 6515f51fb34SArthur O'Dwyer#include <type_traits> 652ea2206d7SArthur O'Dwyer#include <utility> 653f56972e2SMarshall Clow#include <version> 654b5c63a2eSHoward Hinnant 655169a66eaSNikolas Klauser// TODO: remove these headers 656169a66eaSNikolas Klauser#include <__functional/binary_function.h> 657169a66eaSNikolas Klauser#include <__functional/invoke.h> 658169a66eaSNikolas Klauser#include <__functional/operations.h> 659169a66eaSNikolas Klauser#include <__functional/reference_wrapper.h> 660169a66eaSNikolas Klauser#include <__functional/unary_function.h> 661169a66eaSNikolas Klauser#include <__functional/weak_result_type.h> 662169a66eaSNikolas Klauser#include <__memory/allocator_arg_t.h> 663169a66eaSNikolas Klauser#include <__memory/uses_allocator.h> 664169a66eaSNikolas Klauser#include <exception> 665169a66eaSNikolas Klauser#include <new> 666169a66eaSNikolas Klauser#include <typeinfo> 667169a66eaSNikolas Klauser 668073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 6693e519524SHoward Hinnant# pragma GCC system_header 670073458b1SHoward Hinnant#endif 6713e519524SHoward Hinnant 6723e519524SHoward Hinnant#endif // _LIBCPP_ITERATOR 673