xref: /freebsd/contrib/llvm-project/libcxx/include/iterator (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===-------------------------- iterator ----------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_ITERATOR
110b57cec5SDimitry Andric#define _LIBCPP_ITERATOR
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    iterator synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andrictemplate<class Iterator>
200b57cec5SDimitry Andricstruct iterator_traits
210b57cec5SDimitry Andric{
220b57cec5SDimitry Andric    typedef typename Iterator::difference_type difference_type;
230b57cec5SDimitry Andric    typedef typename Iterator::value_type value_type;
240b57cec5SDimitry Andric    typedef typename Iterator::pointer pointer;
250b57cec5SDimitry Andric    typedef typename Iterator::reference reference;
260b57cec5SDimitry Andric    typedef typename Iterator::iterator_category iterator_category;
270b57cec5SDimitry Andric};
280b57cec5SDimitry Andric
290b57cec5SDimitry Andrictemplate<class T>
300b57cec5SDimitry Andricstruct iterator_traits<T*>
310b57cec5SDimitry Andric{
320b57cec5SDimitry Andric    typedef ptrdiff_t difference_type;
330b57cec5SDimitry Andric    typedef T value_type;
340b57cec5SDimitry Andric    typedef T* pointer;
350b57cec5SDimitry Andric    typedef T& reference;
360b57cec5SDimitry Andric    typedef random_access_iterator_tag iterator_category;
370b57cec5SDimitry Andric};
380b57cec5SDimitry Andric
390b57cec5SDimitry Andrictemplate<class Category, class T, class Distance = ptrdiff_t,
400b57cec5SDimitry Andric         class Pointer = T*, class Reference = T&>
410b57cec5SDimitry Andricstruct iterator
420b57cec5SDimitry Andric{
430b57cec5SDimitry Andric    typedef T         value_type;
440b57cec5SDimitry Andric    typedef Distance  difference_type;
450b57cec5SDimitry Andric    typedef Pointer   pointer;
460b57cec5SDimitry Andric    typedef Reference reference;
470b57cec5SDimitry Andric    typedef Category  iterator_category;
480b57cec5SDimitry Andric};
490b57cec5SDimitry Andric
500b57cec5SDimitry Andricstruct input_iterator_tag  {};
510b57cec5SDimitry Andricstruct output_iterator_tag {};
520b57cec5SDimitry Andricstruct forward_iterator_tag       : public input_iterator_tag         {};
530b57cec5SDimitry Andricstruct bidirectional_iterator_tag : public forward_iterator_tag       {};
540b57cec5SDimitry Andricstruct random_access_iterator_tag : public bidirectional_iterator_tag {};
550b57cec5SDimitry Andric
560b57cec5SDimitry Andric// 27.4.3, iterator operations
570b57cec5SDimitry Andric// extension: second argument not conforming to C++03
580b57cec5SDimitry Andrictemplate <class InputIterator>  // constexpr in C++17
590b57cec5SDimitry Andric  constexpr void advance(InputIterator& i,
600b57cec5SDimitry Andric             typename iterator_traits<InputIterator>::difference_type n);
610b57cec5SDimitry Andric
620b57cec5SDimitry Andrictemplate <class InputIterator>  // constexpr in C++17
630b57cec5SDimitry Andric  constexpr typename iterator_traits<InputIterator>::difference_type
640b57cec5SDimitry Andric    distance(InputIterator first, InputIterator last);
650b57cec5SDimitry Andric
660b57cec5SDimitry Andrictemplate <class InputIterator>  // constexpr in C++17
670b57cec5SDimitry Andric  constexpr InputIterator next(InputIterator x,
680b57cec5SDimitry Andrictypename iterator_traits<InputIterator>::difference_type n = 1);
690b57cec5SDimitry Andric
700b57cec5SDimitry Andrictemplate <class BidirectionalIterator>  // constexpr in C++17
710b57cec5SDimitry Andric  constexpr BidirectionalIterator prev(BidirectionalIterator x,
720b57cec5SDimitry Andric    typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
730b57cec5SDimitry Andric
740b57cec5SDimitry Andrictemplate <class Iterator>
750b57cec5SDimitry Andricclass reverse_iterator
760b57cec5SDimitry Andric    : public iterator<typename iterator_traits<Iterator>::iterator_category,
770b57cec5SDimitry Andric                      typename iterator_traits<Iterator>::value_type,
780b57cec5SDimitry Andric                      typename iterator_traits<Iterator>::difference_type,
790b57cec5SDimitry Andric                      typename iterator_traits<Iterator>::pointer,
800b57cec5SDimitry Andric                      typename iterator_traits<Iterator>::reference>
810b57cec5SDimitry Andric{
820b57cec5SDimitry Andricprotected:
830b57cec5SDimitry Andric    Iterator current;
840b57cec5SDimitry Andricpublic:
850b57cec5SDimitry Andric    typedef Iterator                                            iterator_type;
860b57cec5SDimitry Andric    typedef typename iterator_traits<Iterator>::difference_type difference_type;
870b57cec5SDimitry Andric    typedef typename iterator_traits<Iterator>::reference       reference;
880b57cec5SDimitry Andric    typedef typename iterator_traits<Iterator>::pointer         pointer;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric    constexpr reverse_iterator();
910b57cec5SDimitry Andric    constexpr explicit reverse_iterator(Iterator x);
920b57cec5SDimitry Andric    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
930b57cec5SDimitry Andric    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
940b57cec5SDimitry Andric    constexpr Iterator base() const;
950b57cec5SDimitry Andric    constexpr reference operator*() const;
960b57cec5SDimitry Andric    constexpr pointer   operator->() const;
970b57cec5SDimitry Andric    constexpr reverse_iterator& operator++();
980b57cec5SDimitry Andric    constexpr reverse_iterator  operator++(int);
990b57cec5SDimitry Andric    constexpr reverse_iterator& operator--();
1000b57cec5SDimitry Andric    constexpr reverse_iterator  operator--(int);
1010b57cec5SDimitry Andric    constexpr reverse_iterator  operator+ (difference_type n) const;
1020b57cec5SDimitry Andric    constexpr reverse_iterator& operator+=(difference_type n);
1030b57cec5SDimitry Andric    constexpr reverse_iterator  operator- (difference_type n) const;
1040b57cec5SDimitry Andric    constexpr reverse_iterator& operator-=(difference_type n);
1050b57cec5SDimitry Andric    constexpr reference         operator[](difference_type n) const;
1060b57cec5SDimitry Andric};
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1090b57cec5SDimitry Andricconstexpr bool                          // constexpr in C++17
1100b57cec5SDimitry Andricoperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1130b57cec5SDimitry Andricconstexpr bool                          // constexpr in C++17
1140b57cec5SDimitry Andricoperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1170b57cec5SDimitry Andricconstexpr bool                          // constexpr in C++17
1180b57cec5SDimitry Andricoperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1210b57cec5SDimitry Andricconstexpr bool                          // constexpr in C++17
1220b57cec5SDimitry Andricoperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1250b57cec5SDimitry Andricconstexpr bool                          // constexpr in C++17
1260b57cec5SDimitry Andricoperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1290b57cec5SDimitry Andricconstexpr bool                          // constexpr in C++17
1300b57cec5SDimitry Andricoperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
1330b57cec5SDimitry Andricconstexpr auto
1340b57cec5SDimitry Andricoperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
1350b57cec5SDimitry Andric-> decltype(__y.base() - __x.base());   // constexpr in C++17
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andrictemplate <class Iterator>
1380b57cec5SDimitry Andricconstexpr reverse_iterator<Iterator>
1390b57cec5SDimitry Andricoperator+(typename reverse_iterator<Iterator>::difference_type n,
1400b57cec5SDimitry Andric          const reverse_iterator<Iterator>& x);   // constexpr in C++17
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andrictemplate <class Iterator>
1430b57cec5SDimitry Andricconstexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andrictemplate <class Container>
1460b57cec5SDimitry Andricclass back_insert_iterator
1470b57cec5SDimitry Andric{
1480b57cec5SDimitry Andricprotected:
1490b57cec5SDimitry Andric    Container* container;
1500b57cec5SDimitry Andricpublic:
1510b57cec5SDimitry Andric    typedef Container                   container_type;
1520b57cec5SDimitry Andric    typedef void                        value_type;
1530b57cec5SDimitry Andric    typedef void                        difference_type;
1540b57cec5SDimitry Andric    typedef void                        reference;
1550b57cec5SDimitry Andric    typedef void                        pointer;
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric    explicit back_insert_iterator(Container& x);
1580b57cec5SDimitry Andric    back_insert_iterator& operator=(const typename Container::value_type& value);
1590b57cec5SDimitry Andric    back_insert_iterator& operator*();
1600b57cec5SDimitry Andric    back_insert_iterator& operator++();
1610b57cec5SDimitry Andric    back_insert_iterator  operator++(int);
1620b57cec5SDimitry Andric};
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andrictemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x);
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andrictemplate <class Container>
1670b57cec5SDimitry Andricclass front_insert_iterator
1680b57cec5SDimitry Andric{
1690b57cec5SDimitry Andricprotected:
1700b57cec5SDimitry Andric    Container* container;
1710b57cec5SDimitry Andricpublic:
1720b57cec5SDimitry Andric    typedef Container                    container_type;
1730b57cec5SDimitry Andric    typedef void                         value_type;
1740b57cec5SDimitry Andric    typedef void                         difference_type;
1750b57cec5SDimitry Andric    typedef void                         reference;
1760b57cec5SDimitry Andric    typedef void                         pointer;
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric    explicit front_insert_iterator(Container& x);
1790b57cec5SDimitry Andric    front_insert_iterator& operator=(const typename Container::value_type& value);
1800b57cec5SDimitry Andric    front_insert_iterator& operator*();
1810b57cec5SDimitry Andric    front_insert_iterator& operator++();
1820b57cec5SDimitry Andric    front_insert_iterator  operator++(int);
1830b57cec5SDimitry Andric};
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andrictemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x);
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andrictemplate <class Container>
1880b57cec5SDimitry Andricclass insert_iterator
1890b57cec5SDimitry Andric{
1900b57cec5SDimitry Andricprotected:
1910b57cec5SDimitry Andric    Container* container;
1920b57cec5SDimitry Andric    typename Container::iterator iter;
1930b57cec5SDimitry Andricpublic:
1940b57cec5SDimitry Andric    typedef Container              container_type;
1950b57cec5SDimitry Andric    typedef void                   value_type;
1960b57cec5SDimitry Andric    typedef void                   difference_type;
1970b57cec5SDimitry Andric    typedef void                   reference;
1980b57cec5SDimitry Andric    typedef void                   pointer;
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric    insert_iterator(Container& x, typename Container::iterator i);
2010b57cec5SDimitry Andric    insert_iterator& operator=(const typename Container::value_type& value);
2020b57cec5SDimitry Andric    insert_iterator& operator*();
2030b57cec5SDimitry Andric    insert_iterator& operator++();
2040b57cec5SDimitry Andric    insert_iterator& operator++(int);
2050b57cec5SDimitry Andric};
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andrictemplate <class Container, class Iterator>
2080b57cec5SDimitry Andricinsert_iterator<Container> inserter(Container& x, Iterator i);
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andrictemplate <class Iterator>
2110b57cec5SDimitry Andricclass move_iterator {
2120b57cec5SDimitry Andricpublic:
2130b57cec5SDimitry Andric    typedef Iterator                                              iterator_type;
2140b57cec5SDimitry Andric    typedef typename iterator_traits<Iterator>::difference_type   difference_type;
2150b57cec5SDimitry Andric    typedef Iterator                                              pointer;
2160b57cec5SDimitry Andric    typedef typename iterator_traits<Iterator>::value_type        value_type;
2170b57cec5SDimitry Andric    typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
2180b57cec5SDimitry Andric    typedef value_type&&                                          reference;
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric    constexpr move_iterator();  // all the constexprs are in C++17
2210b57cec5SDimitry Andric    constexpr explicit move_iterator(Iterator i);
2220b57cec5SDimitry Andric    template <class U>
2230b57cec5SDimitry Andric      constexpr move_iterator(const move_iterator<U>& u);
2240b57cec5SDimitry Andric    template <class U>
2250b57cec5SDimitry Andric      constexpr move_iterator& operator=(const move_iterator<U>& u);
2260b57cec5SDimitry Andric    constexpr iterator_type base() const;
2270b57cec5SDimitry Andric    constexpr reference operator*() const;
2280b57cec5SDimitry Andric    constexpr pointer operator->() const;
2290b57cec5SDimitry Andric    constexpr move_iterator& operator++();
2300b57cec5SDimitry Andric    constexpr move_iterator operator++(int);
2310b57cec5SDimitry Andric    constexpr move_iterator& operator--();
2320b57cec5SDimitry Andric    constexpr move_iterator operator--(int);
2330b57cec5SDimitry Andric    constexpr move_iterator operator+(difference_type n) const;
2340b57cec5SDimitry Andric    constexpr move_iterator& operator+=(difference_type n);
2350b57cec5SDimitry Andric    constexpr move_iterator operator-(difference_type n) const;
2360b57cec5SDimitry Andric    constexpr move_iterator& operator-=(difference_type n);
2370b57cec5SDimitry Andric    constexpr unspecified operator[](difference_type n) const;
2380b57cec5SDimitry Andricprivate:
2390b57cec5SDimitry Andric    Iterator current; // exposition only
2400b57cec5SDimitry Andric};
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2430b57cec5SDimitry Andricconstexpr bool   // constexpr in C++17
2440b57cec5SDimitry Andricoperator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2470b57cec5SDimitry Andricconstexpr bool   // constexpr in C++17
2480b57cec5SDimitry Andricoperator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2510b57cec5SDimitry Andricconstexpr bool   // constexpr in C++17
2520b57cec5SDimitry Andricoperator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2530b57cec5SDimitry Andric
2540b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2550b57cec5SDimitry Andricconstexpr bool   // constexpr in C++17
2560b57cec5SDimitry Andricoperator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2590b57cec5SDimitry Andricconstexpr bool   // constexpr in C++17
2600b57cec5SDimitry Andricoperator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2630b57cec5SDimitry Andricconstexpr bool   // constexpr in C++17
2640b57cec5SDimitry Andricoperator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andrictemplate <class Iterator1, class Iterator2>
2670b57cec5SDimitry Andricconstexpr auto   // constexpr in C++17
2680b57cec5SDimitry Andricoperator-(const move_iterator<Iterator1>& x,
2690b57cec5SDimitry Andric          const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andrictemplate <class Iterator>
2720b57cec5SDimitry Andricconstexpr move_iterator<Iterator> operator+(   // constexpr in C++17
2730b57cec5SDimitry Andric            typename move_iterator<Iterator>::difference_type n,
2740b57cec5SDimitry Andric            const move_iterator<Iterator>& x);
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andrictemplate <class Iterator>   // constexpr in C++17
2770b57cec5SDimitry Andricconstexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andrictemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
2810b57cec5SDimitry Andricclass istream_iterator
2820b57cec5SDimitry Andric    : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
2830b57cec5SDimitry Andric{
2840b57cec5SDimitry Andricpublic:
2850b57cec5SDimitry Andric    typedef charT char_type;
2860b57cec5SDimitry Andric    typedef traits traits_type;
2870b57cec5SDimitry Andric    typedef basic_istream<charT,traits> istream_type;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andric    constexpr istream_iterator();
2900b57cec5SDimitry Andric    istream_iterator(istream_type& s);
2910b57cec5SDimitry Andric    istream_iterator(const istream_iterator& x);
2920b57cec5SDimitry Andric    ~istream_iterator();
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric    const T& operator*() const;
2950b57cec5SDimitry Andric    const T* operator->() const;
2960b57cec5SDimitry Andric    istream_iterator& operator++();
2970b57cec5SDimitry Andric    istream_iterator  operator++(int);
2980b57cec5SDimitry Andric};
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andrictemplate <class T, class charT, class traits, class Distance>
3010b57cec5SDimitry Andricbool operator==(const istream_iterator<T,charT,traits,Distance>& x,
3020b57cec5SDimitry Andric                const istream_iterator<T,charT,traits,Distance>& y);
3030b57cec5SDimitry Andrictemplate <class T, class charT, class traits, class Distance>
3040b57cec5SDimitry Andricbool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
3050b57cec5SDimitry Andric                const istream_iterator<T,charT,traits,Distance>& y);
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andrictemplate <class T, class charT = char, class traits = char_traits<charT> >
3080b57cec5SDimitry Andricclass ostream_iterator
3090b57cec5SDimitry Andric    : public iterator<output_iterator_tag, void, void, void ,void>
3100b57cec5SDimitry Andric{
3110b57cec5SDimitry Andricpublic:
3120b57cec5SDimitry Andric    typedef charT char_type;
3130b57cec5SDimitry Andric    typedef traits traits_type;
3140b57cec5SDimitry Andric    typedef basic_ostream<charT,traits> ostream_type;
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric    ostream_iterator(ostream_type& s);
3170b57cec5SDimitry Andric    ostream_iterator(ostream_type& s, const charT* delimiter);
3180b57cec5SDimitry Andric    ostream_iterator(const ostream_iterator& x);
3190b57cec5SDimitry Andric    ~ostream_iterator();
3200b57cec5SDimitry Andric    ostream_iterator& operator=(const T& value);
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric    ostream_iterator& operator*();
3230b57cec5SDimitry Andric    ostream_iterator& operator++();
3240b57cec5SDimitry Andric    ostream_iterator& operator++(int);
3250b57cec5SDimitry Andric};
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andrictemplate<class charT, class traits = char_traits<charT> >
3280b57cec5SDimitry Andricclass istreambuf_iterator
3290b57cec5SDimitry Andric    : public iterator<input_iterator_tag, charT,
3300b57cec5SDimitry Andric                      typename traits::off_type, unspecified,
3310b57cec5SDimitry Andric                      charT>
3320b57cec5SDimitry Andric{
3330b57cec5SDimitry Andricpublic:
3340b57cec5SDimitry Andric    typedef charT                         char_type;
3350b57cec5SDimitry Andric    typedef traits                        traits_type;
3360b57cec5SDimitry Andric    typedef typename traits::int_type     int_type;
3370b57cec5SDimitry Andric    typedef basic_streambuf<charT,traits> streambuf_type;
3380b57cec5SDimitry Andric    typedef basic_istream<charT,traits>   istream_type;
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andric    istreambuf_iterator() noexcept;
3410b57cec5SDimitry Andric    istreambuf_iterator(istream_type& s) noexcept;
3420b57cec5SDimitry Andric    istreambuf_iterator(streambuf_type* s) noexcept;
3430b57cec5SDimitry Andric    istreambuf_iterator(a-private-type) noexcept;
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric    charT                operator*() const;
3460b57cec5SDimitry Andric    pointer operator->() const;
3470b57cec5SDimitry Andric    istreambuf_iterator& operator++();
3480b57cec5SDimitry Andric    a-private-type       operator++(int);
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric    bool equal(const istreambuf_iterator& b) const;
3510b57cec5SDimitry Andric};
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andrictemplate <class charT, class traits>
3540b57cec5SDimitry Andricbool operator==(const istreambuf_iterator<charT,traits>& a,
3550b57cec5SDimitry Andric                const istreambuf_iterator<charT,traits>& b);
3560b57cec5SDimitry Andrictemplate <class charT, class traits>
3570b57cec5SDimitry Andricbool operator!=(const istreambuf_iterator<charT,traits>& a,
3580b57cec5SDimitry Andric                const istreambuf_iterator<charT,traits>& b);
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andrictemplate <class charT, class traits = char_traits<charT> >
3610b57cec5SDimitry Andricclass ostreambuf_iterator
3620b57cec5SDimitry Andric    : public iterator<output_iterator_tag, void, void, void, void>
3630b57cec5SDimitry Andric{
3640b57cec5SDimitry Andricpublic:
3650b57cec5SDimitry Andric    typedef charT                         char_type;
3660b57cec5SDimitry Andric    typedef traits                        traits_type;
3670b57cec5SDimitry Andric    typedef basic_streambuf<charT,traits> streambuf_type;
3680b57cec5SDimitry Andric    typedef basic_ostream<charT,traits>   ostream_type;
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andric    ostreambuf_iterator(ostream_type& s) noexcept;
3710b57cec5SDimitry Andric    ostreambuf_iterator(streambuf_type* s) noexcept;
3720b57cec5SDimitry Andric    ostreambuf_iterator& operator=(charT c);
3730b57cec5SDimitry Andric    ostreambuf_iterator& operator*();
3740b57cec5SDimitry Andric    ostreambuf_iterator& operator++();
3750b57cec5SDimitry Andric    ostreambuf_iterator& operator++(int);
3760b57cec5SDimitry Andric    bool failed() const noexcept;
3770b57cec5SDimitry Andric};
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andrictemplate <class C> constexpr auto begin(C& c) -> decltype(c.begin());
3800b57cec5SDimitry Andrictemplate <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
3810b57cec5SDimitry Andrictemplate <class C> constexpr auto end(C& c) -> decltype(c.end());
3820b57cec5SDimitry Andrictemplate <class C> constexpr auto end(const C& c) -> decltype(c.end());
3830b57cec5SDimitry Andrictemplate <class T, size_t N> constexpr T* begin(T (&array)[N]);
3840b57cec5SDimitry Andrictemplate <class T, size_t N> constexpr T* end(T (&array)[N]);
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andrictemplate <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c));        // C++14
3870b57cec5SDimitry Andrictemplate <class C> auto constexpr cend(const C& c) -> decltype(std::end(c));            // C++14
3880b57cec5SDimitry Andrictemplate <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
3890b57cec5SDimitry Andrictemplate <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
3900b57cec5SDimitry Andrictemplate <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
3910b57cec5SDimitry Andrictemplate <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
3920b57cec5SDimitry Andrictemplate <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
3930b57cec5SDimitry Andrictemplate <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il);   // C++14
3940b57cec5SDimitry Andrictemplate <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
3950b57cec5SDimitry Andrictemplate <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
3960b57cec5SDimitry Andrictemplate <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
3970b57cec5SDimitry Andrictemplate <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric// 24.8, container access:
4000b57cec5SDimitry Andrictemplate <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
4010b57cec5SDimitry Andrictemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andrictemplate <class C> constexpr auto ssize(const C& c)
4040b57cec5SDimitry Andric    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;				       // C++20
4050b57cec5SDimitry Andrictemplate <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
4060b57cec5SDimitry Andric
4070b57cec5SDimitry Andrictemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
4080b57cec5SDimitry Andrictemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
4090b57cec5SDimitry Andrictemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
4100b57cec5SDimitry Andrictemplate <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
4110b57cec5SDimitry Andrictemplate <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
4120b57cec5SDimitry Andrictemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
4130b57cec5SDimitry Andrictemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andric}  // std
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric*/
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andric#include <__config>
4200b57cec5SDimitry Andric#include <iosfwd> // for forward declarations of vector and string.
4210b57cec5SDimitry Andric#include <__functional_base>
4220b57cec5SDimitry Andric#include <type_traits>
4230b57cec5SDimitry Andric#include <cstddef>
4240b57cec5SDimitry Andric#include <initializer_list>
4250b57cec5SDimitry Andric#include <version>
4260b57cec5SDimitry Andric#ifdef __APPLE__
4270b57cec5SDimitry Andric#include <Availability.h>
4280b57cec5SDimitry Andric#endif
4290b57cec5SDimitry Andric
4300b57cec5SDimitry Andric#include <__debug>
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4330b57cec5SDimitry Andric#pragma GCC system_header
4340b57cec5SDimitry Andric#endif
4350b57cec5SDimitry Andric
4360b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
437*480093f4SDimitry Andrictemplate <class _Iter>
438*480093f4SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS iterator_traits;
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS input_iterator_tag {};
4410b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
4420b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS forward_iterator_tag       : public input_iterator_tag {};
4430b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
4440b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
445*480093f4SDimitry Andric#if _LIBCPP_STD_VER > 17
446*480093f4SDimitry Andric// TODO(EricWF)  contiguous_iterator_tag is provided as an extension prior to
447*480093f4SDimitry Andric//  C++20 to allow optimizations for users providing wrapped iterator types.
448*480093f4SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag: public random_access_iterator_tag { };
449*480093f4SDimitry Andric#endif
450*480093f4SDimitry Andric
451*480093f4SDimitry Andrictemplate <class _Iter>
452*480093f4SDimitry Andricstruct __iter_traits_cache {
453*480093f4SDimitry Andric  using type = _If<
454*480093f4SDimitry Andric    __is_primary_template<iterator_traits<_Iter> >::value,
455*480093f4SDimitry Andric    _Iter,
456*480093f4SDimitry Andric    iterator_traits<_Iter>
457*480093f4SDimitry Andric  >;
458*480093f4SDimitry Andric};
459*480093f4SDimitry Andrictemplate <class _Iter>
460*480093f4SDimitry Andricusing _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type;
461*480093f4SDimitry Andric
462*480093f4SDimitry Andricstruct __iter_concept_concept_test {
463*480093f4SDimitry Andric  template <class _Iter>
464*480093f4SDimitry Andric  using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept;
465*480093f4SDimitry Andric};
466*480093f4SDimitry Andricstruct __iter_concept_category_test {
467*480093f4SDimitry Andric  template <class _Iter>
468*480093f4SDimitry Andric  using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category;
469*480093f4SDimitry Andric};
470*480093f4SDimitry Andricstruct __iter_concept_random_fallback {
471*480093f4SDimitry Andric  template <class _Iter>
472*480093f4SDimitry Andric  using _Apply = _EnableIf<
473*480093f4SDimitry Andric                          __is_primary_template<iterator_traits<_Iter> >::value,
474*480093f4SDimitry Andric                          random_access_iterator_tag
475*480093f4SDimitry Andric                        >;
476*480093f4SDimitry Andric};
477*480093f4SDimitry Andric
478*480093f4SDimitry Andrictemplate <class _Iter, class _Tester> struct __test_iter_concept
479*480093f4SDimitry Andric    : _IsValidExpansion<_Tester::template _Apply, _Iter>,
480*480093f4SDimitry Andric      _Tester
481*480093f4SDimitry Andric{
482*480093f4SDimitry Andric};
483*480093f4SDimitry Andric
484*480093f4SDimitry Andrictemplate <class _Iter>
485*480093f4SDimitry Andricstruct __iter_concept_cache {
486*480093f4SDimitry Andric  using type = _Or<
487*480093f4SDimitry Andric    __test_iter_concept<_Iter, __iter_concept_concept_test>,
488*480093f4SDimitry Andric    __test_iter_concept<_Iter, __iter_concept_category_test>,
489*480093f4SDimitry Andric    __test_iter_concept<_Iter, __iter_concept_random_fallback>
490*480093f4SDimitry Andric  >;
491*480093f4SDimitry Andric};
492*480093f4SDimitry Andric
493*480093f4SDimitry Andrictemplate <class _Iter>
494*480093f4SDimitry Andricusing _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
495*480093f4SDimitry Andric
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andrictemplate <class _Tp>
4980b57cec5SDimitry Andricstruct __has_iterator_typedefs
4990b57cec5SDimitry Andric{
5000b57cec5SDimitry Andricprivate:
5010b57cec5SDimitry Andric    struct __two {char __lx; char __lxx;};
5020b57cec5SDimitry Andric    template <class _Up> static __two __test(...);
5030b57cec5SDimitry Andric    template <class _Up> static char __test(typename std::__void_t<typename _Up::iterator_category>::type* = 0,
5040b57cec5SDimitry Andric    										typename std::__void_t<typename _Up::difference_type>::type* = 0,
5050b57cec5SDimitry Andric    										typename std::__void_t<typename _Up::value_type>::type* = 0,
5060b57cec5SDimitry Andric    										typename std::__void_t<typename _Up::reference>::type* = 0,
5070b57cec5SDimitry Andric    										typename std::__void_t<typename _Up::pointer>::type* = 0
5080b57cec5SDimitry Andric    										);
5090b57cec5SDimitry Andricpublic:
5100b57cec5SDimitry Andric    static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
5110b57cec5SDimitry Andric};
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric
5140b57cec5SDimitry Andrictemplate <class _Tp>
5150b57cec5SDimitry Andricstruct __has_iterator_category
5160b57cec5SDimitry Andric{
5170b57cec5SDimitry Andricprivate:
5180b57cec5SDimitry Andric    struct __two {char __lx; char __lxx;};
5190b57cec5SDimitry Andric    template <class _Up> static __two __test(...);
5200b57cec5SDimitry Andric    template <class _Up> static char __test(typename _Up::iterator_category* = 0);
5210b57cec5SDimitry Andricpublic:
5220b57cec5SDimitry Andric    static const bool value = sizeof(__test<_Tp>(0)) == 1;
5230b57cec5SDimitry Andric};
5240b57cec5SDimitry Andric
5250b57cec5SDimitry Andrictemplate <class _Iter, bool> struct __iterator_traits_impl {};
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andrictemplate <class _Iter>
5280b57cec5SDimitry Andricstruct __iterator_traits_impl<_Iter, true>
5290b57cec5SDimitry Andric{
5300b57cec5SDimitry Andric    typedef typename _Iter::difference_type   difference_type;
5310b57cec5SDimitry Andric    typedef typename _Iter::value_type        value_type;
5320b57cec5SDimitry Andric    typedef typename _Iter::pointer           pointer;
5330b57cec5SDimitry Andric    typedef typename _Iter::reference         reference;
5340b57cec5SDimitry Andric    typedef typename _Iter::iterator_category iterator_category;
5350b57cec5SDimitry Andric};
5360b57cec5SDimitry Andric
5370b57cec5SDimitry Andrictemplate <class _Iter, bool> struct __iterator_traits {};
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andrictemplate <class _Iter>
5400b57cec5SDimitry Andricstruct __iterator_traits<_Iter, true>
5410b57cec5SDimitry Andric    :  __iterator_traits_impl
5420b57cec5SDimitry Andric      <
5430b57cec5SDimitry Andric        _Iter,
5440b57cec5SDimitry Andric        is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
5450b57cec5SDimitry Andric        is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
5460b57cec5SDimitry Andric      >
5470b57cec5SDimitry Andric{};
5480b57cec5SDimitry Andric
5490b57cec5SDimitry Andric// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
5500b57cec5SDimitry Andric//    exists.  Else iterator_traits<Iterator> will be an empty class.  This is a
5510b57cec5SDimitry Andric//    conforming extension which allows some programs to compile and behave as
5520b57cec5SDimitry Andric//    the client expects instead of failing at compile time.
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andrictemplate <class _Iter>
5550b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS iterator_traits
556*480093f4SDimitry Andric    : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {
557*480093f4SDimitry Andric
558*480093f4SDimitry Andric  using __primary_template = iterator_traits;
559*480093f4SDimitry Andric};
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andrictemplate<class _Tp>
5620b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
5630b57cec5SDimitry Andric{
5640b57cec5SDimitry Andric    typedef ptrdiff_t difference_type;
5650b57cec5SDimitry Andric    typedef typename remove_cv<_Tp>::type value_type;
5660b57cec5SDimitry Andric    typedef _Tp* pointer;
5670b57cec5SDimitry Andric    typedef _Tp& reference;
5680b57cec5SDimitry Andric    typedef random_access_iterator_tag iterator_category;
569*480093f4SDimitry Andric#if _LIBCPP_STD_VER > 17
570*480093f4SDimitry Andric    typedef contiguous_iterator_tag    iterator_concept;
571*480093f4SDimitry Andric#endif
5720b57cec5SDimitry Andric};
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andrictemplate <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
5750b57cec5SDimitry Andricstruct __has_iterator_category_convertible_to
5760b57cec5SDimitry Andric    : public integral_constant<bool, is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>::value>
5770b57cec5SDimitry Andric{};
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
5800b57cec5SDimitry Andricstruct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {};
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andrictemplate <class _Tp>
583*480093f4SDimitry Andricstruct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andrictemplate <class _Tp>
586*480093f4SDimitry Andricstruct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andrictemplate <class _Tp>
589*480093f4SDimitry Andricstruct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
5900b57cec5SDimitry Andric
5910b57cec5SDimitry Andrictemplate <class _Tp>
592*480093f4SDimitry Andricstruct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
593*480093f4SDimitry Andric
594*480093f4SDimitry Andric#if _LIBCPP_STD_VER > 17
595*480093f4SDimitry Andrictemplate <class _Tp>
596*480093f4SDimitry Andricstruct __is_cpp17_contiguous_iterator : public __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag> {};
597*480093f4SDimitry Andric#else
598*480093f4SDimitry Andrictemplate <class _Tp>
599*480093f4SDimitry Andricstruct __is_cpp17_contiguous_iterator : public false_type {};
600*480093f4SDimitry Andric#endif
601*480093f4SDimitry Andric
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andrictemplate <class _Tp>
604*480093f4SDimitry Andricstruct __is_exactly_cpp17_input_iterator
6050b57cec5SDimitry Andric    : public integral_constant<bool,
6060b57cec5SDimitry Andric         __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
6070b57cec5SDimitry Andric        !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
6100b57cec5SDimitry Andrictemplate<class _InputIterator>
6110b57cec5SDimitry Andricusing __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
6120b57cec5SDimitry Andric
6130b57cec5SDimitry Andrictemplate<class _InputIterator>
6140b57cec5SDimitry Andricusing __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
6150b57cec5SDimitry Andric
6160b57cec5SDimitry Andrictemplate<class _InputIterator>
6170b57cec5SDimitry Andricusing __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andrictemplate<class _InputIterator>
6200b57cec5SDimitry Andricusing __iter_to_alloc_type = pair<
6210b57cec5SDimitry Andric    add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>,
6220b57cec5SDimitry Andric    typename iterator_traits<_InputIterator>::value_type::second_type>;
6230b57cec5SDimitry Andric#endif
6240b57cec5SDimitry Andric
6250b57cec5SDimitry Andrictemplate<class _Category, class _Tp, class _Distance = ptrdiff_t,
6260b57cec5SDimitry Andric         class _Pointer = _Tp*, class _Reference = _Tp&>
6270b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS iterator
6280b57cec5SDimitry Andric{
6290b57cec5SDimitry Andric    typedef _Tp        value_type;
6300b57cec5SDimitry Andric    typedef _Distance  difference_type;
6310b57cec5SDimitry Andric    typedef _Pointer   pointer;
6320b57cec5SDimitry Andric    typedef _Reference reference;
6330b57cec5SDimitry Andric    typedef _Category  iterator_category;
6340b57cec5SDimitry Andric};
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andrictemplate <class _InputIter>
6370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6380b57cec5SDimitry Andricvoid __advance(_InputIter& __i,
6390b57cec5SDimitry Andric             typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)
6400b57cec5SDimitry Andric{
6410b57cec5SDimitry Andric    for (; __n > 0; --__n)
6420b57cec5SDimitry Andric        ++__i;
6430b57cec5SDimitry Andric}
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andrictemplate <class _BiDirIter>
6460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6470b57cec5SDimitry Andricvoid __advance(_BiDirIter& __i,
6480b57cec5SDimitry Andric             typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag)
6490b57cec5SDimitry Andric{
6500b57cec5SDimitry Andric    if (__n >= 0)
6510b57cec5SDimitry Andric        for (; __n > 0; --__n)
6520b57cec5SDimitry Andric            ++__i;
6530b57cec5SDimitry Andric    else
6540b57cec5SDimitry Andric        for (; __n < 0; ++__n)
6550b57cec5SDimitry Andric            --__i;
6560b57cec5SDimitry Andric}
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andrictemplate <class _RandIter>
6590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6600b57cec5SDimitry Andricvoid __advance(_RandIter& __i,
6610b57cec5SDimitry Andric             typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)
6620b57cec5SDimitry Andric{
6630b57cec5SDimitry Andric   __i += __n;
6640b57cec5SDimitry Andric}
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andrictemplate <class _InputIter>
6670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6680b57cec5SDimitry Andricvoid advance(_InputIter& __i,
6690b57cec5SDimitry Andric             typename iterator_traits<_InputIter>::difference_type __n)
6700b57cec5SDimitry Andric{
671*480093f4SDimitry Andric    _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
6720b57cec5SDimitry Andric                       "Attempt to advance(it, -n) on a non-bidi iterator");
6730b57cec5SDimitry Andric    __advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
6740b57cec5SDimitry Andric}
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andrictemplate <class _InputIter>
6770b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6780b57cec5SDimitry Andrictypename iterator_traits<_InputIter>::difference_type
6790b57cec5SDimitry Andric__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
6800b57cec5SDimitry Andric{
6810b57cec5SDimitry Andric    typename iterator_traits<_InputIter>::difference_type __r(0);
6820b57cec5SDimitry Andric    for (; __first != __last; ++__first)
6830b57cec5SDimitry Andric        ++__r;
6840b57cec5SDimitry Andric    return __r;
6850b57cec5SDimitry Andric}
6860b57cec5SDimitry Andric
6870b57cec5SDimitry Andrictemplate <class _RandIter>
6880b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6890b57cec5SDimitry Andrictypename iterator_traits<_RandIter>::difference_type
6900b57cec5SDimitry Andric__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
6910b57cec5SDimitry Andric{
6920b57cec5SDimitry Andric    return __last - __first;
6930b57cec5SDimitry Andric}
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andrictemplate <class _InputIter>
6960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
6970b57cec5SDimitry Andrictypename iterator_traits<_InputIter>::difference_type
6980b57cec5SDimitry Andricdistance(_InputIter __first, _InputIter __last)
6990b57cec5SDimitry Andric{
7000b57cec5SDimitry Andric    return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
7010b57cec5SDimitry Andric}
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andrictemplate <class _InputIter>
7040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7050b57cec5SDimitry Andrictypename enable_if
7060b57cec5SDimitry Andric<
707*480093f4SDimitry Andric    __is_cpp17_input_iterator<_InputIter>::value,
7080b57cec5SDimitry Andric    _InputIter
7090b57cec5SDimitry Andric>::type
7100b57cec5SDimitry Andricnext(_InputIter __x,
7110b57cec5SDimitry Andric     typename iterator_traits<_InputIter>::difference_type __n = 1)
7120b57cec5SDimitry Andric{
713*480093f4SDimitry Andric    _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
7140b57cec5SDimitry Andric                       "Attempt to next(it, -n) on a non-bidi iterator");
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andric    _VSTD::advance(__x, __n);
7170b57cec5SDimitry Andric    return __x;
7180b57cec5SDimitry Andric}
7190b57cec5SDimitry Andric
7200b57cec5SDimitry Andrictemplate <class _InputIter>
7210b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7220b57cec5SDimitry Andrictypename enable_if
7230b57cec5SDimitry Andric<
724*480093f4SDimitry Andric    __is_cpp17_input_iterator<_InputIter>::value,
7250b57cec5SDimitry Andric    _InputIter
7260b57cec5SDimitry Andric>::type
7270b57cec5SDimitry Andricprev(_InputIter __x,
7280b57cec5SDimitry Andric     typename iterator_traits<_InputIter>::difference_type __n = 1)
7290b57cec5SDimitry Andric{
730*480093f4SDimitry Andric    _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
7310b57cec5SDimitry Andric                       "Attempt to prev(it, +n) on a non-bidi iterator");
7320b57cec5SDimitry Andric    _VSTD::advance(__x, -__n);
7330b57cec5SDimitry Andric    return __x;
7340b57cec5SDimitry Andric}
7350b57cec5SDimitry Andric
7360b57cec5SDimitry Andric
7370b57cec5SDimitry Andrictemplate <class _Tp, class = void>
7380b57cec5SDimitry Andricstruct __is_stashing_iterator : false_type {};
7390b57cec5SDimitry Andric
7400b57cec5SDimitry Andrictemplate <class _Tp>
7410b57cec5SDimitry Andricstruct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
7420b57cec5SDimitry Andric  : true_type {};
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andrictemplate <class _Iter>
7450b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS reverse_iterator
7460b57cec5SDimitry Andric    : public iterator<typename iterator_traits<_Iter>::iterator_category,
7470b57cec5SDimitry Andric                      typename iterator_traits<_Iter>::value_type,
7480b57cec5SDimitry Andric                      typename iterator_traits<_Iter>::difference_type,
7490b57cec5SDimitry Andric                      typename iterator_traits<_Iter>::pointer,
7500b57cec5SDimitry Andric                      typename iterator_traits<_Iter>::reference>
7510b57cec5SDimitry Andric{
7520b57cec5SDimitry Andricprivate:
7530b57cec5SDimitry Andric    /*mutable*/ _Iter __t;  // no longer used as of LWG #2360, not removed due to ABI break
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andric    static_assert(!__is_stashing_iterator<_Iter>::value,
7560b57cec5SDimitry Andric      "The specified iterator type cannot be used with reverse_iterator; "
7570b57cec5SDimitry Andric      "Using stashing iterators with reverse_iterator causes undefined behavior");
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andricprotected:
7600b57cec5SDimitry Andric    _Iter current;
7610b57cec5SDimitry Andricpublic:
7620b57cec5SDimitry Andric    typedef _Iter                                            iterator_type;
7630b57cec5SDimitry Andric    typedef typename iterator_traits<_Iter>::difference_type difference_type;
7640b57cec5SDimitry Andric    typedef typename iterator_traits<_Iter>::reference       reference;
7650b57cec5SDimitry Andric    typedef typename iterator_traits<_Iter>::pointer         pointer;
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7680b57cec5SDimitry Andric    reverse_iterator() : __t(), current() {}
7690b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7700b57cec5SDimitry Andric    explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
7710b57cec5SDimitry Andric    template <class _Up>
7720b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7730b57cec5SDimitry Andric        reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {}
7740b57cec5SDimitry Andric    template <class _Up>
7750b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7760b57cec5SDimitry Andric        reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
7770b57cec5SDimitry Andric            { __t = current = __u.base(); return *this; }
7780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7790b57cec5SDimitry Andric    _Iter base() const {return current;}
7800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7810b57cec5SDimitry Andric    reference operator*() const {_Iter __tmp = current; return *--__tmp;}
7820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7830b57cec5SDimitry Andric    pointer  operator->() const {return _VSTD::addressof(operator*());}
7840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7850b57cec5SDimitry Andric    reverse_iterator& operator++() {--current; return *this;}
7860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7870b57cec5SDimitry Andric    reverse_iterator  operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
7880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7890b57cec5SDimitry Andric    reverse_iterator& operator--() {++current; return *this;}
7900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7910b57cec5SDimitry Andric    reverse_iterator  operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
7920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7930b57cec5SDimitry Andric    reverse_iterator  operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
7940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7950b57cec5SDimitry Andric    reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
7960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7970b57cec5SDimitry Andric    reverse_iterator  operator- (difference_type __n) const {return reverse_iterator(current + __n);}
7980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
7990b57cec5SDimitry Andric    reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
8000b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8010b57cec5SDimitry Andric    reference         operator[](difference_type __n) const {return *(*this + __n);}
8020b57cec5SDimitry Andric};
8030b57cec5SDimitry Andric
8040b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8050b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8060b57cec5SDimitry Andricbool
8070b57cec5SDimitry Andricoperator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8080b57cec5SDimitry Andric{
8090b57cec5SDimitry Andric    return __x.base() == __y.base();
8100b57cec5SDimitry Andric}
8110b57cec5SDimitry Andric
8120b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8140b57cec5SDimitry Andricbool
8150b57cec5SDimitry Andricoperator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8160b57cec5SDimitry Andric{
8170b57cec5SDimitry Andric    return __x.base() > __y.base();
8180b57cec5SDimitry Andric}
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8210b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8220b57cec5SDimitry Andricbool
8230b57cec5SDimitry Andricoperator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8240b57cec5SDimitry Andric{
8250b57cec5SDimitry Andric    return __x.base() != __y.base();
8260b57cec5SDimitry Andric}
8270b57cec5SDimitry Andric
8280b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8300b57cec5SDimitry Andricbool
8310b57cec5SDimitry Andricoperator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8320b57cec5SDimitry Andric{
8330b57cec5SDimitry Andric    return __x.base() < __y.base();
8340b57cec5SDimitry Andric}
8350b57cec5SDimitry Andric
8360b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8380b57cec5SDimitry Andricbool
8390b57cec5SDimitry Andricoperator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8400b57cec5SDimitry Andric{
8410b57cec5SDimitry Andric    return __x.base() <= __y.base();
8420b57cec5SDimitry Andric}
8430b57cec5SDimitry Andric
8440b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8450b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8460b57cec5SDimitry Andricbool
8470b57cec5SDimitry Andricoperator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8480b57cec5SDimitry Andric{
8490b57cec5SDimitry Andric    return __x.base() >= __y.base();
8500b57cec5SDimitry Andric}
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8530b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8540b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8550b57cec5SDimitry Andricauto
8560b57cec5SDimitry Andricoperator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8570b57cec5SDimitry Andric-> decltype(__y.base() - __x.base())
8580b57cec5SDimitry Andric{
8590b57cec5SDimitry Andric    return __y.base() - __x.base();
8600b57cec5SDimitry Andric}
8610b57cec5SDimitry Andric#else
8620b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
8630b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
8640b57cec5SDimitry Andrictypename reverse_iterator<_Iter1>::difference_type
8650b57cec5SDimitry Andricoperator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
8660b57cec5SDimitry Andric{
8670b57cec5SDimitry Andric    return __y.base() - __x.base();
8680b57cec5SDimitry Andric}
8690b57cec5SDimitry Andric#endif
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andrictemplate <class _Iter>
8720b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8730b57cec5SDimitry Andricreverse_iterator<_Iter>
8740b57cec5SDimitry Andricoperator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
8750b57cec5SDimitry Andric{
8760b57cec5SDimitry Andric    return reverse_iterator<_Iter>(__x.base() - __n);
8770b57cec5SDimitry Andric}
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
8800b57cec5SDimitry Andrictemplate <class _Iter>
8810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
8820b57cec5SDimitry Andricreverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
8830b57cec5SDimitry Andric{
8840b57cec5SDimitry Andric    return reverse_iterator<_Iter>(__i);
8850b57cec5SDimitry Andric}
8860b57cec5SDimitry Andric#endif
8870b57cec5SDimitry Andric
8880b57cec5SDimitry Andrictemplate <class _Container>
8890b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS back_insert_iterator
8900b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
8910b57cec5SDimitry Andric                      void,
8920b57cec5SDimitry Andric                      void,
8930b57cec5SDimitry Andric                      void,
8940b57cec5SDimitry Andric                      void>
8950b57cec5SDimitry Andric{
8960b57cec5SDimitry Andricprotected:
8970b57cec5SDimitry Andric    _Container* container;
8980b57cec5SDimitry Andricpublic:
8990b57cec5SDimitry Andric    typedef _Container container_type;
9000b57cec5SDimitry Andric
9010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
9020b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
9030b57cec5SDimitry Andric        {container->push_back(__value_); return *this;}
9040b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)
9060b57cec5SDimitry Andric        {container->push_back(_VSTD::move(__value_)); return *this;}
9070b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
9080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*()     {return *this;}
9090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++()    {return *this;}
9100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY back_insert_iterator  operator++(int) {return *this;}
9110b57cec5SDimitry Andric};
9120b57cec5SDimitry Andric
9130b57cec5SDimitry Andrictemplate <class _Container>
9140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9150b57cec5SDimitry Andricback_insert_iterator<_Container>
9160b57cec5SDimitry Andricback_inserter(_Container& __x)
9170b57cec5SDimitry Andric{
9180b57cec5SDimitry Andric    return back_insert_iterator<_Container>(__x);
9190b57cec5SDimitry Andric}
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andrictemplate <class _Container>
9220b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS front_insert_iterator
9230b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
9240b57cec5SDimitry Andric                      void,
9250b57cec5SDimitry Andric                      void,
9260b57cec5SDimitry Andric                      void,
9270b57cec5SDimitry Andric                      void>
9280b57cec5SDimitry Andric{
9290b57cec5SDimitry Andricprotected:
9300b57cec5SDimitry Andric    _Container* container;
9310b57cec5SDimitry Andricpublic:
9320b57cec5SDimitry Andric    typedef _Container container_type;
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
9350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)
9360b57cec5SDimitry Andric        {container->push_front(__value_); return *this;}
9370b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9380b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)
9390b57cec5SDimitry Andric        {container->push_front(_VSTD::move(__value_)); return *this;}
9400b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
9410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*()     {return *this;}
9420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++()    {return *this;}
9430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY front_insert_iterator  operator++(int) {return *this;}
9440b57cec5SDimitry Andric};
9450b57cec5SDimitry Andric
9460b57cec5SDimitry Andrictemplate <class _Container>
9470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9480b57cec5SDimitry Andricfront_insert_iterator<_Container>
9490b57cec5SDimitry Andricfront_inserter(_Container& __x)
9500b57cec5SDimitry Andric{
9510b57cec5SDimitry Andric    return front_insert_iterator<_Container>(__x);
9520b57cec5SDimitry Andric}
9530b57cec5SDimitry Andric
9540b57cec5SDimitry Andrictemplate <class _Container>
9550b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS insert_iterator
9560b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
9570b57cec5SDimitry Andric                      void,
9580b57cec5SDimitry Andric                      void,
9590b57cec5SDimitry Andric                      void,
9600b57cec5SDimitry Andric                      void>
9610b57cec5SDimitry Andric{
9620b57cec5SDimitry Andricprotected:
9630b57cec5SDimitry Andric    _Container* container;
9640b57cec5SDimitry Andric    typename _Container::iterator iter;
9650b57cec5SDimitry Andricpublic:
9660b57cec5SDimitry Andric    typedef _Container container_type;
9670b57cec5SDimitry Andric
9680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
9690b57cec5SDimitry Andric        : container(_VSTD::addressof(__x)), iter(__i) {}
9700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)
9710b57cec5SDimitry Andric        {iter = container->insert(iter, __value_); ++iter; return *this;}
9720b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)
9740b57cec5SDimitry Andric        {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
9750b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
9760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator*()        {return *this;}
9770b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++()       {return *this;}
9780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int)    {return *this;}
9790b57cec5SDimitry Andric};
9800b57cec5SDimitry Andric
9810b57cec5SDimitry Andrictemplate <class _Container>
9820b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9830b57cec5SDimitry Andricinsert_iterator<_Container>
9840b57cec5SDimitry Andricinserter(_Container& __x, typename _Container::iterator __i)
9850b57cec5SDimitry Andric{
9860b57cec5SDimitry Andric    return insert_iterator<_Container>(__x, __i);
9870b57cec5SDimitry Andric}
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andrictemplate <class _Tp, class _CharT = char,
9900b57cec5SDimitry Andric          class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
9910b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS istream_iterator
9920b57cec5SDimitry Andric    : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
9930b57cec5SDimitry Andric{
9940b57cec5SDimitry Andricpublic:
9950b57cec5SDimitry Andric    typedef _CharT char_type;
9960b57cec5SDimitry Andric    typedef _Traits traits_type;
9970b57cec5SDimitry Andric    typedef basic_istream<_CharT,_Traits> istream_type;
9980b57cec5SDimitry Andricprivate:
9990b57cec5SDimitry Andric    istream_type* __in_stream_;
10000b57cec5SDimitry Andric    _Tp __value_;
10010b57cec5SDimitry Andricpublic:
10020b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {}
10030b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
10040b57cec5SDimitry Andric        {
10050b57cec5SDimitry Andric            if (!(*__in_stream_ >> __value_))
10060b57cec5SDimitry Andric                __in_stream_ = 0;
10070b57cec5SDimitry Andric        }
10080b57cec5SDimitry Andric
10090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
10100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
10110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
10120b57cec5SDimitry Andric        {
10130b57cec5SDimitry Andric            if (!(*__in_stream_ >> __value_))
10140b57cec5SDimitry Andric                __in_stream_ = 0;
10150b57cec5SDimitry Andric            return *this;
10160b57cec5SDimitry Andric        }
10170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istream_iterator  operator++(int)
10180b57cec5SDimitry Andric        {istream_iterator __t(*this); ++(*this); return __t;}
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andric    template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
10210b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
10220b57cec5SDimitry Andric    bool
10230b57cec5SDimitry Andric    operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
10240b57cec5SDimitry Andric               const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
10250b57cec5SDimitry Andric
10260b57cec5SDimitry Andric    template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
10270b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
10280b57cec5SDimitry Andric    bool
10290b57cec5SDimitry Andric    operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
10300b57cec5SDimitry Andric               const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
10310b57cec5SDimitry Andric};
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits, class _Distance>
10340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10350b57cec5SDimitry Andricbool
10360b57cec5SDimitry Andricoperator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
10370b57cec5SDimitry Andric           const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
10380b57cec5SDimitry Andric{
10390b57cec5SDimitry Andric    return __x.__in_stream_ == __y.__in_stream_;
10400b57cec5SDimitry Andric}
10410b57cec5SDimitry Andric
10420b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits, class _Distance>
10430b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10440b57cec5SDimitry Andricbool
10450b57cec5SDimitry Andricoperator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
10460b57cec5SDimitry Andric           const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
10470b57cec5SDimitry Andric{
10480b57cec5SDimitry Andric    return !(__x == __y);
10490b57cec5SDimitry Andric}
10500b57cec5SDimitry Andric
10510b57cec5SDimitry Andrictemplate <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
10520b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS ostream_iterator
10530b57cec5SDimitry Andric    : public iterator<output_iterator_tag, void, void, void, void>
10540b57cec5SDimitry Andric{
10550b57cec5SDimitry Andricpublic:
10560b57cec5SDimitry Andric    typedef _CharT char_type;
10570b57cec5SDimitry Andric    typedef _Traits traits_type;
10580b57cec5SDimitry Andric    typedef basic_ostream<_CharT,_Traits> ostream_type;
10590b57cec5SDimitry Andricprivate:
10600b57cec5SDimitry Andric    ostream_type* __out_stream_;
10610b57cec5SDimitry Andric    const char_type* __delim_;
10620b57cec5SDimitry Andricpublic:
10630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
10640b57cec5SDimitry Andric        : __out_stream_(_VSTD::addressof(__s)), __delim_(0) {}
10650b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
10660b57cec5SDimitry Andric        : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
10670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
10680b57cec5SDimitry Andric        {
10690b57cec5SDimitry Andric            *__out_stream_ << __value_;
10700b57cec5SDimitry Andric            if (__delim_)
10710b57cec5SDimitry Andric                *__out_stream_ << __delim_;
10720b57cec5SDimitry Andric            return *this;
10730b57cec5SDimitry Andric        }
10740b57cec5SDimitry Andric
10750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*()     {return *this;}
10760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++()    {return *this;}
10770b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
10780b57cec5SDimitry Andric};
10790b57cec5SDimitry Andric
10800b57cec5SDimitry Andrictemplate<class _CharT, class _Traits>
10810b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS istreambuf_iterator
10820b57cec5SDimitry Andric    : public iterator<input_iterator_tag, _CharT,
10830b57cec5SDimitry Andric                      typename _Traits::off_type, _CharT*,
10840b57cec5SDimitry Andric                      _CharT>
10850b57cec5SDimitry Andric{
10860b57cec5SDimitry Andricpublic:
10870b57cec5SDimitry Andric    typedef _CharT                          char_type;
10880b57cec5SDimitry Andric    typedef _Traits                         traits_type;
10890b57cec5SDimitry Andric    typedef typename _Traits::int_type      int_type;
10900b57cec5SDimitry Andric    typedef basic_streambuf<_CharT,_Traits> streambuf_type;
10910b57cec5SDimitry Andric    typedef basic_istream<_CharT,_Traits>   istream_type;
10920b57cec5SDimitry Andricprivate:
10930b57cec5SDimitry Andric    mutable streambuf_type* __sbuf_;
10940b57cec5SDimitry Andric
10950b57cec5SDimitry Andric    class __proxy
10960b57cec5SDimitry Andric    {
10970b57cec5SDimitry Andric        char_type __keep_;
10980b57cec5SDimitry Andric        streambuf_type* __sbuf_;
10990b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
11000b57cec5SDimitry Andric            : __keep_(__c), __sbuf_(__s) {}
11010b57cec5SDimitry Andric        friend class istreambuf_iterator;
11020b57cec5SDimitry Andric    public:
11030b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
11040b57cec5SDimitry Andric    };
11050b57cec5SDimitry Andric
11060b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
11070b57cec5SDimitry Andric    bool __test_for_eof() const
11080b57cec5SDimitry Andric    {
11090b57cec5SDimitry Andric        if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
11100b57cec5SDimitry Andric            __sbuf_ = 0;
11110b57cec5SDimitry Andric        return __sbuf_ == 0;
11120b57cec5SDimitry Andric    }
11130b57cec5SDimitry Andricpublic:
11140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}
11150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
11160b57cec5SDimitry Andric        : __sbuf_(__s.rdbuf()) {}
11170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
11180b57cec5SDimitry Andric        : __sbuf_(__s) {}
11190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
11200b57cec5SDimitry Andric        : __sbuf_(__p.__sbuf_) {}
11210b57cec5SDimitry Andric
11220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY char_type  operator*() const
11230b57cec5SDimitry Andric        {return static_cast<char_type>(__sbuf_->sgetc());}
11240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
11250b57cec5SDimitry Andric        {
11260b57cec5SDimitry Andric            __sbuf_->sbumpc();
11270b57cec5SDimitry Andric            return *this;
11280b57cec5SDimitry Andric        }
11290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __proxy              operator++(int)
11300b57cec5SDimitry Andric        {
11310b57cec5SDimitry Andric            return __proxy(__sbuf_->sbumpc(), __sbuf_);
11320b57cec5SDimitry Andric        }
11330b57cec5SDimitry Andric
11340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
11350b57cec5SDimitry Andric        {return __test_for_eof() == __b.__test_for_eof();}
11360b57cec5SDimitry Andric};
11370b57cec5SDimitry Andric
11380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
11390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11400b57cec5SDimitry Andricbool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
11410b57cec5SDimitry Andric                const istreambuf_iterator<_CharT,_Traits>& __b)
11420b57cec5SDimitry Andric                {return __a.equal(__b);}
11430b57cec5SDimitry Andric
11440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
11450b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11460b57cec5SDimitry Andricbool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
11470b57cec5SDimitry Andric                const istreambuf_iterator<_CharT,_Traits>& __b)
11480b57cec5SDimitry Andric                {return !__a.equal(__b);}
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
11510b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
11520b57cec5SDimitry Andric    : public iterator<output_iterator_tag, void, void, void, void>
11530b57cec5SDimitry Andric{
11540b57cec5SDimitry Andricpublic:
11550b57cec5SDimitry Andric    typedef _CharT                          char_type;
11560b57cec5SDimitry Andric    typedef _Traits                         traits_type;
11570b57cec5SDimitry Andric    typedef basic_streambuf<_CharT,_Traits> streambuf_type;
11580b57cec5SDimitry Andric    typedef basic_ostream<_CharT,_Traits>   ostream_type;
11590b57cec5SDimitry Andricprivate:
11600b57cec5SDimitry Andric    streambuf_type* __sbuf_;
11610b57cec5SDimitry Andricpublic:
11620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
11630b57cec5SDimitry Andric        : __sbuf_(__s.rdbuf()) {}
11640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
11650b57cec5SDimitry Andric        : __sbuf_(__s) {}
11660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
11670b57cec5SDimitry Andric        {
11680b57cec5SDimitry Andric            if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
11690b57cec5SDimitry Andric                __sbuf_ = 0;
11700b57cec5SDimitry Andric            return *this;
11710b57cec5SDimitry Andric        }
11720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*()     {return *this;}
11730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++()    {return *this;}
11740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
11750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;}
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andric    template <class _Ch, class _Tr>
11780b57cec5SDimitry Andric    friend
11790b57cec5SDimitry Andric    _LIBCPP_HIDDEN
11800b57cec5SDimitry Andric    ostreambuf_iterator<_Ch, _Tr>
11810b57cec5SDimitry Andric    __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
11820b57cec5SDimitry Andric                     const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
11830b57cec5SDimitry Andric                     ios_base& __iob, _Ch __fl);
11840b57cec5SDimitry Andric};
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andrictemplate <class _Iter>
11870b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS move_iterator
11880b57cec5SDimitry Andric{
11890b57cec5SDimitry Andricprivate:
11900b57cec5SDimitry Andric    _Iter __i;
11910b57cec5SDimitry Andricpublic:
11920b57cec5SDimitry Andric    typedef _Iter                                            iterator_type;
11930b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
11940b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::value_type value_type;
11950b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::difference_type difference_type;
11960b57cec5SDimitry Andric    typedef iterator_type pointer;
11970b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
11980b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::reference __reference;
11990b57cec5SDimitry Andric    typedef typename conditional<
12000b57cec5SDimitry Andric            is_reference<__reference>::value,
12010b57cec5SDimitry Andric            typename remove_reference<__reference>::type&&,
12020b57cec5SDimitry Andric            __reference
12030b57cec5SDimitry Andric        >::type reference;
12040b57cec5SDimitry Andric#else
12050b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::reference reference;
12060b57cec5SDimitry Andric#endif
12070b57cec5SDimitry Andric
12080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12090b57cec5SDimitry Andric    move_iterator() : __i() {}
12100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12110b57cec5SDimitry Andric    explicit move_iterator(_Iter __x) : __i(__x) {}
12120b57cec5SDimitry Andric    template <class _Up>
12130b57cec5SDimitry Andric      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12140b57cec5SDimitry Andric      move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
12150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
12160b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12170b57cec5SDimitry Andric    reference operator*() const { return static_cast<reference>(*__i); }
12180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12190b57cec5SDimitry Andric    pointer  operator->() const { return __i;}
12200b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12210b57cec5SDimitry Andric    move_iterator& operator++() {++__i; return *this;}
12220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12230b57cec5SDimitry Andric    move_iterator  operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;}
12240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12250b57cec5SDimitry Andric    move_iterator& operator--() {--__i; return *this;}
12260b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12270b57cec5SDimitry Andric    move_iterator  operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;}
12280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12290b57cec5SDimitry Andric    move_iterator  operator+ (difference_type __n) const {return move_iterator(__i + __n);}
12300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12310b57cec5SDimitry Andric    move_iterator& operator+=(difference_type __n) {__i += __n; return *this;}
12320b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12330b57cec5SDimitry Andric    move_iterator  operator- (difference_type __n) const {return move_iterator(__i - __n);}
12340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12350b57cec5SDimitry Andric    move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;}
12360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12370b57cec5SDimitry Andric    reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); }
12380b57cec5SDimitry Andric};
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12420b57cec5SDimitry Andricbool
12430b57cec5SDimitry Andricoperator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12440b57cec5SDimitry Andric{
12450b57cec5SDimitry Andric    return __x.base() == __y.base();
12460b57cec5SDimitry Andric}
12470b57cec5SDimitry Andric
12480b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12490b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12500b57cec5SDimitry Andricbool
12510b57cec5SDimitry Andricoperator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12520b57cec5SDimitry Andric{
12530b57cec5SDimitry Andric    return __x.base() < __y.base();
12540b57cec5SDimitry Andric}
12550b57cec5SDimitry Andric
12560b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12580b57cec5SDimitry Andricbool
12590b57cec5SDimitry Andricoperator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12600b57cec5SDimitry Andric{
12610b57cec5SDimitry Andric    return __x.base() != __y.base();
12620b57cec5SDimitry Andric}
12630b57cec5SDimitry Andric
12640b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12660b57cec5SDimitry Andricbool
12670b57cec5SDimitry Andricoperator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12680b57cec5SDimitry Andric{
12690b57cec5SDimitry Andric    return __x.base() > __y.base();
12700b57cec5SDimitry Andric}
12710b57cec5SDimitry Andric
12720b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12730b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12740b57cec5SDimitry Andricbool
12750b57cec5SDimitry Andricoperator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12760b57cec5SDimitry Andric{
12770b57cec5SDimitry Andric    return __x.base() >= __y.base();
12780b57cec5SDimitry Andric}
12790b57cec5SDimitry Andric
12800b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12820b57cec5SDimitry Andricbool
12830b57cec5SDimitry Andricoperator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12840b57cec5SDimitry Andric{
12850b57cec5SDimitry Andric    return __x.base() <= __y.base();
12860b57cec5SDimitry Andric}
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
12890b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12900b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12910b57cec5SDimitry Andricauto
12920b57cec5SDimitry Andricoperator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
12930b57cec5SDimitry Andric-> decltype(__x.base() - __y.base())
12940b57cec5SDimitry Andric{
12950b57cec5SDimitry Andric    return __x.base() - __y.base();
12960b57cec5SDimitry Andric}
12970b57cec5SDimitry Andric#else
12980b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
12990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13000b57cec5SDimitry Andrictypename move_iterator<_Iter1>::difference_type
13010b57cec5SDimitry Andricoperator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
13020b57cec5SDimitry Andric{
13030b57cec5SDimitry Andric    return __x.base() - __y.base();
13040b57cec5SDimitry Andric}
13050b57cec5SDimitry Andric#endif
13060b57cec5SDimitry Andric
13070b57cec5SDimitry Andrictemplate <class _Iter>
13080b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
13090b57cec5SDimitry Andricmove_iterator<_Iter>
13100b57cec5SDimitry Andricoperator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
13110b57cec5SDimitry Andric{
13120b57cec5SDimitry Andric    return move_iterator<_Iter>(__x.base() + __n);
13130b57cec5SDimitry Andric}
13140b57cec5SDimitry Andric
13150b57cec5SDimitry Andrictemplate <class _Iter>
13160b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
13170b57cec5SDimitry Andricmove_iterator<_Iter>
13180b57cec5SDimitry Andricmake_move_iterator(_Iter __i)
13190b57cec5SDimitry Andric{
13200b57cec5SDimitry Andric    return move_iterator<_Iter>(__i);
13210b57cec5SDimitry Andric}
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andric// __wrap_iter
13240b57cec5SDimitry Andric
13250b57cec5SDimitry Andrictemplate <class _Iter> class __wrap_iter;
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13290b57cec5SDimitry Andricbool
13300b57cec5SDimitry Andricoperator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13310b57cec5SDimitry Andric
13320b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13330b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13340b57cec5SDimitry Andricbool
13350b57cec5SDimitry Andricoperator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13360b57cec5SDimitry Andric
13370b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13380b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13390b57cec5SDimitry Andricbool
13400b57cec5SDimitry Andricoperator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13410b57cec5SDimitry Andric
13420b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13430b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13440b57cec5SDimitry Andricbool
13450b57cec5SDimitry Andricoperator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13460b57cec5SDimitry Andric
13470b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13480b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13490b57cec5SDimitry Andricbool
13500b57cec5SDimitry Andricoperator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13510b57cec5SDimitry Andric
13520b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13530b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13540b57cec5SDimitry Andricbool
13550b57cec5SDimitry Andricoperator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
13580b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13600b57cec5SDimitry Andricauto
13610b57cec5SDimitry Andricoperator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
13620b57cec5SDimitry Andric-> decltype(__x.base() - __y.base());
13630b57cec5SDimitry Andric#else
13640b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
13650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13660b57cec5SDimitry Andrictypename __wrap_iter<_Iter1>::difference_type
13670b57cec5SDimitry Andricoperator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
13680b57cec5SDimitry Andric#endif
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andrictemplate <class _Iter>
13710b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13720b57cec5SDimitry Andric__wrap_iter<_Iter>
13730b57cec5SDimitry Andricoperator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
13740b57cec5SDimitry Andric
1375*480093f4SDimitry Andrictemplate <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op);
1376*480093f4SDimitry Andrictemplate <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2);
13770b57cec5SDimitry Andrictemplate <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op);
13780b57cec5SDimitry Andrictemplate <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2);
13790b57cec5SDimitry Andric
13800b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL < 2
13810b57cec5SDimitry Andric
13820b57cec5SDimitry Andrictemplate <class _Tp>
13830b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13840b57cec5SDimitry Andrictypename enable_if
13850b57cec5SDimitry Andric<
13860b57cec5SDimitry Andric    is_trivially_copy_assignable<_Tp>::value,
13870b57cec5SDimitry Andric    _Tp*
13880b57cec5SDimitry Andric>::type
13890b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<_Tp*>);
13900b57cec5SDimitry Andric
13910b57cec5SDimitry Andric#else
13920b57cec5SDimitry Andric
13930b57cec5SDimitry Andrictemplate <class _Tp>
13940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
13950b57cec5SDimitry Andrictypename enable_if
13960b57cec5SDimitry Andric<
13970b57cec5SDimitry Andric    is_trivially_copy_assignable<_Tp>::value,
13980b57cec5SDimitry Andric    __wrap_iter<_Tp*>
13990b57cec5SDimitry Andric>::type
14000b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<_Tp*> __i);
14010b57cec5SDimitry Andric
14020b57cec5SDimitry Andric#endif
14030b57cec5SDimitry Andric
14040b57cec5SDimitry Andrictemplate <class _Iter>
14050b57cec5SDimitry Andricclass __wrap_iter
14060b57cec5SDimitry Andric{
14070b57cec5SDimitry Andricpublic:
14080b57cec5SDimitry Andric    typedef _Iter                                                      iterator_type;
14090b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
14100b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::value_type        value_type;
14110b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::difference_type   difference_type;
14120b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::pointer           pointer;
14130b57cec5SDimitry Andric    typedef typename iterator_traits<iterator_type>::reference         reference;
14140b57cec5SDimitry Andricprivate:
14150b57cec5SDimitry Andric    iterator_type __i;
14160b57cec5SDimitry Andricpublic:
14170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
14180b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
14190b57cec5SDimitry Andric                : __i{}
14200b57cec5SDimitry Andric#endif
14210b57cec5SDimitry Andric    {
14220b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14230b57cec5SDimitry Andric        __get_db()->__insert_i(this);
14240b57cec5SDimitry Andric#endif
14250b57cec5SDimitry Andric    }
14260b57cec5SDimitry Andric    template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
14270b57cec5SDimitry Andric        __wrap_iter(const __wrap_iter<_Up>& __u,
14280b57cec5SDimitry Andric            typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT
14290b57cec5SDimitry Andric            : __i(__u.base())
14300b57cec5SDimitry Andric    {
14310b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14320b57cec5SDimitry Andric        __get_db()->__iterator_copy(this, &__u);
14330b57cec5SDimitry Andric#endif
14340b57cec5SDimitry Andric    }
14350b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
14370b57cec5SDimitry Andric    __wrap_iter(const __wrap_iter& __x)
14380b57cec5SDimitry Andric        : __i(__x.base())
14390b57cec5SDimitry Andric    {
14400b57cec5SDimitry Andric        __get_db()->__iterator_copy(this, &__x);
14410b57cec5SDimitry Andric    }
14420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
14430b57cec5SDimitry Andric    __wrap_iter& operator=(const __wrap_iter& __x)
14440b57cec5SDimitry Andric    {
14450b57cec5SDimitry Andric        if (this != &__x)
14460b57cec5SDimitry Andric        {
14470b57cec5SDimitry Andric            __get_db()->__iterator_copy(this, &__x);
14480b57cec5SDimitry Andric            __i = __x.__i;
14490b57cec5SDimitry Andric        }
14500b57cec5SDimitry Andric        return *this;
14510b57cec5SDimitry Andric    }
14520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
14530b57cec5SDimitry Andric    ~__wrap_iter()
14540b57cec5SDimitry Andric    {
14550b57cec5SDimitry Andric        __get_db()->__erase_i(this);
14560b57cec5SDimitry Andric    }
14570b57cec5SDimitry Andric#endif
14580b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
14590b57cec5SDimitry Andric    {
14600b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14610b57cec5SDimitry Andric        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
14620b57cec5SDimitry Andric                       "Attempted to dereference a non-dereferenceable iterator");
14630b57cec5SDimitry Andric#endif
14640b57cec5SDimitry Andric        return *__i;
14650b57cec5SDimitry Andric    }
14660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer  operator->() const _NOEXCEPT
14670b57cec5SDimitry Andric    {
14680b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14690b57cec5SDimitry Andric        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
14700b57cec5SDimitry Andric                       "Attempted to dereference a non-dereferenceable iterator");
14710b57cec5SDimitry Andric#endif
14720b57cec5SDimitry Andric        return (pointer)_VSTD::addressof(*__i);
14730b57cec5SDimitry Andric    }
14740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
14750b57cec5SDimitry Andric    {
14760b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14770b57cec5SDimitry Andric        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
14780b57cec5SDimitry Andric                       "Attempted to increment non-incrementable iterator");
14790b57cec5SDimitry Andric#endif
14800b57cec5SDimitry Andric        ++__i;
14810b57cec5SDimitry Andric        return *this;
14820b57cec5SDimitry Andric    }
14830b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator++(int) _NOEXCEPT
14840b57cec5SDimitry Andric        {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
14870b57cec5SDimitry Andric    {
14880b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
14890b57cec5SDimitry Andric        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
14900b57cec5SDimitry Andric                       "Attempted to decrement non-decrementable iterator");
14910b57cec5SDimitry Andric#endif
14920b57cec5SDimitry Andric        --__i;
14930b57cec5SDimitry Andric        return *this;
14940b57cec5SDimitry Andric    }
14950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator--(int) _NOEXCEPT
14960b57cec5SDimitry Andric        {__wrap_iter __tmp(*this); --(*this); return __tmp;}
14970b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT
14980b57cec5SDimitry Andric        {__wrap_iter __w(*this); __w += __n; return __w;}
14990b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
15000b57cec5SDimitry Andric    {
15010b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
15020b57cec5SDimitry Andric        _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
15030b57cec5SDimitry Andric                   "Attempted to add/subtract iterator outside of valid range");
15040b57cec5SDimitry Andric#endif
15050b57cec5SDimitry Andric        __i += __n;
15060b57cec5SDimitry Andric        return *this;
15070b57cec5SDimitry Andric    }
15080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator- (difference_type __n) const _NOEXCEPT
15090b57cec5SDimitry Andric        {return *this + (-__n);}
15100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
15110b57cec5SDimitry Andric        {*this += -__n; return *this;}
15120b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference    operator[](difference_type __n) const _NOEXCEPT
15130b57cec5SDimitry Andric    {
15140b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
15150b57cec5SDimitry Andric        _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
15160b57cec5SDimitry Andric                   "Attempted to subscript iterator outside of valid range");
15170b57cec5SDimitry Andric#endif
15180b57cec5SDimitry Andric        return __i[__n];
15190b57cec5SDimitry Andric    }
15200b57cec5SDimitry Andric
15210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
15220b57cec5SDimitry Andric
15230b57cec5SDimitry Andricprivate:
15240b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
15250b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
15260b57cec5SDimitry Andric    {
15270b57cec5SDimitry Andric        __get_db()->__insert_ic(this, __p);
15280b57cec5SDimitry Andric    }
15290b57cec5SDimitry Andric#else
15300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
15310b57cec5SDimitry Andric#endif
15320b57cec5SDimitry Andric
15330b57cec5SDimitry Andric    template <class _Up> friend class __wrap_iter;
15340b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
15350b57cec5SDimitry Andric    template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
15360b57cec5SDimitry Andric    template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
15370b57cec5SDimitry Andric
15380b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15390b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15400b57cec5SDimitry Andric    bool
15410b57cec5SDimitry Andric    operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15420b57cec5SDimitry Andric
15430b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15440b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15450b57cec5SDimitry Andric    bool
15460b57cec5SDimitry Andric    operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15470b57cec5SDimitry Andric
15480b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15490b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15500b57cec5SDimitry Andric    bool
15510b57cec5SDimitry Andric    operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15520b57cec5SDimitry Andric
15530b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15540b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15550b57cec5SDimitry Andric    bool
15560b57cec5SDimitry Andric    operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15570b57cec5SDimitry Andric
15580b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15590b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15600b57cec5SDimitry Andric    bool
15610b57cec5SDimitry Andric    operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15620b57cec5SDimitry Andric
15630b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15640b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15650b57cec5SDimitry Andric    bool
15660b57cec5SDimitry Andric    operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15670b57cec5SDimitry Andric
15680b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
15690b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15700b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15710b57cec5SDimitry Andric    auto
15720b57cec5SDimitry Andric    operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
15730b57cec5SDimitry Andric    -> decltype(__x.base() - __y.base());
15740b57cec5SDimitry Andric#else
15750b57cec5SDimitry Andric    template <class _Iter1, class _Iter2>
15760b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15770b57cec5SDimitry Andric    typename __wrap_iter<_Iter1>::difference_type
15780b57cec5SDimitry Andric    operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
15790b57cec5SDimitry Andric#endif
15800b57cec5SDimitry Andric
15810b57cec5SDimitry Andric    template <class _Iter1>
15820b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15830b57cec5SDimitry Andric    __wrap_iter<_Iter1>
15840b57cec5SDimitry Andric    operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
15850b57cec5SDimitry Andric
1586*480093f4SDimitry Andric    template <class _Ip, class _Op> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op copy(_Ip, _Ip, _Op);
1587*480093f4SDimitry Andric    template <class _B1, class _B2> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 copy_backward(_B1, _B1, _B2);
15880b57cec5SDimitry Andric    template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);
15890b57cec5SDimitry Andric    template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);
15900b57cec5SDimitry Andric
15910b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL < 2
15920b57cec5SDimitry Andric    template <class _Tp>
15930b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
15940b57cec5SDimitry Andric    typename enable_if
15950b57cec5SDimitry Andric    <
15960b57cec5SDimitry Andric        is_trivially_copy_assignable<_Tp>::value,
15970b57cec5SDimitry Andric        _Tp*
15980b57cec5SDimitry Andric    >::type
15990b57cec5SDimitry Andric    __unwrap_iter(__wrap_iter<_Tp*>);
16000b57cec5SDimitry Andric#else
16010b57cec5SDimitry Andric  template <class _Tp>
16020b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16030b57cec5SDimitry Andric  typename enable_if
16040b57cec5SDimitry Andric  <
16050b57cec5SDimitry Andric      is_trivially_copy_assignable<_Tp>::value,
16060b57cec5SDimitry Andric      __wrap_iter<_Tp*>
16070b57cec5SDimitry Andric  >::type
16080b57cec5SDimitry Andric  __unwrap_iter(__wrap_iter<_Tp*> __i);
16090b57cec5SDimitry Andric#endif
16100b57cec5SDimitry Andric};
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16140b57cec5SDimitry Andricbool
16150b57cec5SDimitry Andricoperator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
16160b57cec5SDimitry Andric{
16170b57cec5SDimitry Andric    return __x.base() == __y.base();
16180b57cec5SDimitry Andric}
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16210b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16220b57cec5SDimitry Andricbool
16230b57cec5SDimitry Andricoperator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
16240b57cec5SDimitry Andric{
16250b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
16260b57cec5SDimitry Andric    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
16270b57cec5SDimitry Andric                   "Attempted to compare incomparable iterators");
16280b57cec5SDimitry Andric#endif
16290b57cec5SDimitry Andric    return __x.base() < __y.base();
16300b57cec5SDimitry Andric}
16310b57cec5SDimitry Andric
16320b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16330b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16340b57cec5SDimitry Andricbool
16350b57cec5SDimitry Andricoperator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
16360b57cec5SDimitry Andric{
16370b57cec5SDimitry Andric    return !(__x == __y);
16380b57cec5SDimitry Andric}
16390b57cec5SDimitry Andric
16400b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16420b57cec5SDimitry Andricbool
16430b57cec5SDimitry Andricoperator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
16440b57cec5SDimitry Andric{
16450b57cec5SDimitry Andric    return __y < __x;
16460b57cec5SDimitry Andric}
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16490b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16500b57cec5SDimitry Andricbool
16510b57cec5SDimitry Andricoperator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
16520b57cec5SDimitry Andric{
16530b57cec5SDimitry Andric    return !(__x < __y);
16540b57cec5SDimitry Andric}
16550b57cec5SDimitry Andric
16560b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16580b57cec5SDimitry Andricbool
16590b57cec5SDimitry Andricoperator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
16600b57cec5SDimitry Andric{
16610b57cec5SDimitry Andric    return !(__y < __x);
16620b57cec5SDimitry Andric}
16630b57cec5SDimitry Andric
16640b57cec5SDimitry Andrictemplate <class _Iter1>
16650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16660b57cec5SDimitry Andricbool
16670b57cec5SDimitry Andricoperator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
16680b57cec5SDimitry Andric{
16690b57cec5SDimitry Andric    return !(__x == __y);
16700b57cec5SDimitry Andric}
16710b57cec5SDimitry Andric
16720b57cec5SDimitry Andrictemplate <class _Iter1>
16730b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16740b57cec5SDimitry Andricbool
16750b57cec5SDimitry Andricoperator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
16760b57cec5SDimitry Andric{
16770b57cec5SDimitry Andric    return __y < __x;
16780b57cec5SDimitry Andric}
16790b57cec5SDimitry Andric
16800b57cec5SDimitry Andrictemplate <class _Iter1>
16810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16820b57cec5SDimitry Andricbool
16830b57cec5SDimitry Andricoperator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
16840b57cec5SDimitry Andric{
16850b57cec5SDimitry Andric    return !(__x < __y);
16860b57cec5SDimitry Andric}
16870b57cec5SDimitry Andric
16880b57cec5SDimitry Andrictemplate <class _Iter1>
16890b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16900b57cec5SDimitry Andricbool
16910b57cec5SDimitry Andricoperator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
16920b57cec5SDimitry Andric{
16930b57cec5SDimitry Andric    return !(__y < __x);
16940b57cec5SDimitry Andric}
16950b57cec5SDimitry Andric
16960b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
16970b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
16980b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
16990b57cec5SDimitry Andricauto
17000b57cec5SDimitry Andricoperator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
17010b57cec5SDimitry Andric-> decltype(__x.base() - __y.base())
17020b57cec5SDimitry Andric{
17030b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
17040b57cec5SDimitry Andric    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
17050b57cec5SDimitry Andric                   "Attempted to subtract incompatible iterators");
17060b57cec5SDimitry Andric#endif
17070b57cec5SDimitry Andric    return __x.base() - __y.base();
17080b57cec5SDimitry Andric}
17090b57cec5SDimitry Andric#else
17100b57cec5SDimitry Andrictemplate <class _Iter1, class _Iter2>
17110b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
17120b57cec5SDimitry Andrictypename __wrap_iter<_Iter1>::difference_type
17130b57cec5SDimitry Andricoperator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
17140b57cec5SDimitry Andric{
17150b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2
17160b57cec5SDimitry Andric    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
17170b57cec5SDimitry Andric                   "Attempted to subtract incompatible iterators");
17180b57cec5SDimitry Andric#endif
17190b57cec5SDimitry Andric    return __x.base() - __y.base();
17200b57cec5SDimitry Andric}
17210b57cec5SDimitry Andric#endif
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andrictemplate <class _Iter>
17240b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
17250b57cec5SDimitry Andric__wrap_iter<_Iter>
17260b57cec5SDimitry Andricoperator+(typename __wrap_iter<_Iter>::difference_type __n,
17270b57cec5SDimitry Andric          __wrap_iter<_Iter> __x) _NOEXCEPT
17280b57cec5SDimitry Andric{
17290b57cec5SDimitry Andric    __x += __n;
17300b57cec5SDimitry Andric    return __x;
17310b57cec5SDimitry Andric}
17320b57cec5SDimitry Andric
17330b57cec5SDimitry Andrictemplate <class _Iter>
17340b57cec5SDimitry Andricstruct __libcpp_is_trivial_iterator
17350b57cec5SDimitry Andric    : public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {};
17360b57cec5SDimitry Andric
17370b57cec5SDimitry Andrictemplate <class _Iter>
17380b57cec5SDimitry Andricstruct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
17390b57cec5SDimitry Andric    : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
17400b57cec5SDimitry Andric
17410b57cec5SDimitry Andrictemplate <class _Iter>
17420b57cec5SDimitry Andricstruct __libcpp_is_trivial_iterator<reverse_iterator<_Iter> >
17430b57cec5SDimitry Andric    : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
17440b57cec5SDimitry Andric
17450b57cec5SDimitry Andrictemplate <class _Iter>
17460b57cec5SDimitry Andricstruct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
17470b57cec5SDimitry Andric    : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
17480b57cec5SDimitry Andric
17490b57cec5SDimitry Andric
17500b57cec5SDimitry Andrictemplate <class _Tp, size_t _Np>
17510b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
17520b57cec5SDimitry Andric_Tp*
17530b57cec5SDimitry Andricbegin(_Tp (&__array)[_Np])
17540b57cec5SDimitry Andric{
17550b57cec5SDimitry Andric    return __array;
17560b57cec5SDimitry Andric}
17570b57cec5SDimitry Andric
17580b57cec5SDimitry Andrictemplate <class _Tp, size_t _Np>
17590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
17600b57cec5SDimitry Andric_Tp*
17610b57cec5SDimitry Andricend(_Tp (&__array)[_Np])
17620b57cec5SDimitry Andric{
17630b57cec5SDimitry Andric    return __array + _Np;
17640b57cec5SDimitry Andric}
17650b57cec5SDimitry Andric
17660b57cec5SDimitry Andric#if !defined(_LIBCPP_CXX03_LANG)
17670b57cec5SDimitry Andric
17680b57cec5SDimitry Andrictemplate <class _Cp>
17690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
17700b57cec5SDimitry Andricauto
17710b57cec5SDimitry Andricbegin(_Cp& __c) -> decltype(__c.begin())
17720b57cec5SDimitry Andric{
17730b57cec5SDimitry Andric    return __c.begin();
17740b57cec5SDimitry Andric}
17750b57cec5SDimitry Andric
17760b57cec5SDimitry Andrictemplate <class _Cp>
17770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
17780b57cec5SDimitry Andricauto
17790b57cec5SDimitry Andricbegin(const _Cp& __c) -> decltype(__c.begin())
17800b57cec5SDimitry Andric{
17810b57cec5SDimitry Andric    return __c.begin();
17820b57cec5SDimitry Andric}
17830b57cec5SDimitry Andric
17840b57cec5SDimitry Andrictemplate <class _Cp>
17850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
17860b57cec5SDimitry Andricauto
17870b57cec5SDimitry Andricend(_Cp& __c) -> decltype(__c.end())
17880b57cec5SDimitry Andric{
17890b57cec5SDimitry Andric    return __c.end();
17900b57cec5SDimitry Andric}
17910b57cec5SDimitry Andric
17920b57cec5SDimitry Andrictemplate <class _Cp>
17930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
17940b57cec5SDimitry Andricauto
17950b57cec5SDimitry Andricend(const _Cp& __c) -> decltype(__c.end())
17960b57cec5SDimitry Andric{
17970b57cec5SDimitry Andric    return __c.end();
17980b57cec5SDimitry Andric}
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
18010b57cec5SDimitry Andric
18020b57cec5SDimitry Andrictemplate <class _Tp, size_t _Np>
18030b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18040b57cec5SDimitry Andricreverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
18050b57cec5SDimitry Andric{
18060b57cec5SDimitry Andric    return reverse_iterator<_Tp*>(__array + _Np);
18070b57cec5SDimitry Andric}
18080b57cec5SDimitry Andric
18090b57cec5SDimitry Andrictemplate <class _Tp, size_t _Np>
18100b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18110b57cec5SDimitry Andricreverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
18120b57cec5SDimitry Andric{
18130b57cec5SDimitry Andric    return reverse_iterator<_Tp*>(__array);
18140b57cec5SDimitry Andric}
18150b57cec5SDimitry Andric
18160b57cec5SDimitry Andrictemplate <class _Ep>
18170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18180b57cec5SDimitry Andricreverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
18190b57cec5SDimitry Andric{
18200b57cec5SDimitry Andric    return reverse_iterator<const _Ep*>(__il.end());
18210b57cec5SDimitry Andric}
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andrictemplate <class _Ep>
18240b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18250b57cec5SDimitry Andricreverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
18260b57cec5SDimitry Andric{
18270b57cec5SDimitry Andric    return reverse_iterator<const _Ep*>(__il.begin());
18280b57cec5SDimitry Andric}
18290b57cec5SDimitry Andric
18300b57cec5SDimitry Andrictemplate <class _Cp>
18310b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
18320b57cec5SDimitry Andricauto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
18330b57cec5SDimitry Andric{
18340b57cec5SDimitry Andric    return _VSTD::begin(__c);
18350b57cec5SDimitry Andric}
18360b57cec5SDimitry Andric
18370b57cec5SDimitry Andrictemplate <class _Cp>
18380b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
18390b57cec5SDimitry Andricauto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
18400b57cec5SDimitry Andric{
18410b57cec5SDimitry Andric    return _VSTD::end(__c);
18420b57cec5SDimitry Andric}
18430b57cec5SDimitry Andric
18440b57cec5SDimitry Andrictemplate <class _Cp>
18450b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18460b57cec5SDimitry Andricauto rbegin(_Cp& __c) -> decltype(__c.rbegin())
18470b57cec5SDimitry Andric{
18480b57cec5SDimitry Andric    return __c.rbegin();
18490b57cec5SDimitry Andric}
18500b57cec5SDimitry Andric
18510b57cec5SDimitry Andrictemplate <class _Cp>
18520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18530b57cec5SDimitry Andricauto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
18540b57cec5SDimitry Andric{
18550b57cec5SDimitry Andric    return __c.rbegin();
18560b57cec5SDimitry Andric}
18570b57cec5SDimitry Andric
18580b57cec5SDimitry Andrictemplate <class _Cp>
18590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18600b57cec5SDimitry Andricauto rend(_Cp& __c) -> decltype(__c.rend())
18610b57cec5SDimitry Andric{
18620b57cec5SDimitry Andric    return __c.rend();
18630b57cec5SDimitry Andric}
18640b57cec5SDimitry Andric
18650b57cec5SDimitry Andrictemplate <class _Cp>
18660b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18670b57cec5SDimitry Andricauto rend(const _Cp& __c) -> decltype(__c.rend())
18680b57cec5SDimitry Andric{
18690b57cec5SDimitry Andric    return __c.rend();
18700b57cec5SDimitry Andric}
18710b57cec5SDimitry Andric
18720b57cec5SDimitry Andrictemplate <class _Cp>
18730b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18740b57cec5SDimitry Andricauto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
18750b57cec5SDimitry Andric{
18760b57cec5SDimitry Andric    return _VSTD::rbegin(__c);
18770b57cec5SDimitry Andric}
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andrictemplate <class _Cp>
18800b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
18810b57cec5SDimitry Andricauto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
18820b57cec5SDimitry Andric{
18830b57cec5SDimitry Andric    return _VSTD::rend(__c);
18840b57cec5SDimitry Andric}
18850b57cec5SDimitry Andric
18860b57cec5SDimitry Andric#endif
18870b57cec5SDimitry Andric
18880b57cec5SDimitry Andric
18890b57cec5SDimitry Andric#else  // defined(_LIBCPP_CXX03_LANG)
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andrictemplate <class _Cp>
18920b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18930b57cec5SDimitry Andrictypename _Cp::iterator
18940b57cec5SDimitry Andricbegin(_Cp& __c)
18950b57cec5SDimitry Andric{
18960b57cec5SDimitry Andric    return __c.begin();
18970b57cec5SDimitry Andric}
18980b57cec5SDimitry Andric
18990b57cec5SDimitry Andrictemplate <class _Cp>
19000b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19010b57cec5SDimitry Andrictypename _Cp::const_iterator
19020b57cec5SDimitry Andricbegin(const _Cp& __c)
19030b57cec5SDimitry Andric{
19040b57cec5SDimitry Andric    return __c.begin();
19050b57cec5SDimitry Andric}
19060b57cec5SDimitry Andric
19070b57cec5SDimitry Andrictemplate <class _Cp>
19080b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19090b57cec5SDimitry Andrictypename _Cp::iterator
19100b57cec5SDimitry Andricend(_Cp& __c)
19110b57cec5SDimitry Andric{
19120b57cec5SDimitry Andric    return __c.end();
19130b57cec5SDimitry Andric}
19140b57cec5SDimitry Andric
19150b57cec5SDimitry Andrictemplate <class _Cp>
19160b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19170b57cec5SDimitry Andrictypename _Cp::const_iterator
19180b57cec5SDimitry Andricend(const _Cp& __c)
19190b57cec5SDimitry Andric{
19200b57cec5SDimitry Andric    return __c.end();
19210b57cec5SDimitry Andric}
19220b57cec5SDimitry Andric
19230b57cec5SDimitry Andric#endif  // !defined(_LIBCPP_CXX03_LANG)
19240b57cec5SDimitry Andric
19250b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
19260b57cec5SDimitry Andric
19270b57cec5SDimitry Andric// #if _LIBCPP_STD_VER > 11
19280b57cec5SDimitry Andric// template <>
19290b57cec5SDimitry Andric// struct _LIBCPP_TEMPLATE_VIS plus<void>
19300b57cec5SDimitry Andric// {
19310b57cec5SDimitry Andric//     template <class _T1, class _T2>
19320b57cec5SDimitry Andric//     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
19330b57cec5SDimitry Andric//     auto operator()(_T1&& __t, _T2&& __u) const
19340b57cec5SDimitry Andric//     _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
19350b57cec5SDimitry Andric//     -> decltype        (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
19360b57cec5SDimitry Andric//         { return        _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
19370b57cec5SDimitry Andric//     typedef void is_transparent;
19380b57cec5SDimitry Andric// };
19390b57cec5SDimitry Andric// #endif
19400b57cec5SDimitry Andric
19410b57cec5SDimitry Andrictemplate <class _Cont>
19420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19430b57cec5SDimitry Andricconstexpr auto size(const _Cont& __c)
19440b57cec5SDimitry Andric_NOEXCEPT_(noexcept(__c.size()))
19450b57cec5SDimitry Andric-> decltype        (__c.size())
19460b57cec5SDimitry Andric{ return            __c.size(); }
19470b57cec5SDimitry Andric
19480b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz>
19490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19500b57cec5SDimitry Andricconstexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
19530b57cec5SDimitry Andrictemplate <class _Cont>
19540b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19550b57cec5SDimitry Andricconstexpr auto ssize(const _Cont& __c)
19560b57cec5SDimitry Andric_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
19570b57cec5SDimitry Andric->                              common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
19580b57cec5SDimitry Andric{ return            static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andrictemplate <class _Tp, ptrdiff_t _Sz>
19610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19620b57cec5SDimitry Andricconstexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
19630b57cec5SDimitry Andric#endif
19640b57cec5SDimitry Andric
19650b57cec5SDimitry Andrictemplate <class _Cont>
19660b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
19670b57cec5SDimitry Andricconstexpr auto empty(const _Cont& __c)
19680b57cec5SDimitry Andric_NOEXCEPT_(noexcept(__c.empty()))
19690b57cec5SDimitry Andric-> decltype        (__c.empty())
19700b57cec5SDimitry Andric{ return            __c.empty(); }
19710b57cec5SDimitry Andric
19720b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz>
19730b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
19740b57cec5SDimitry Andricconstexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
19750b57cec5SDimitry Andric
19760b57cec5SDimitry Andrictemplate <class _Ep>
19770b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
19780b57cec5SDimitry Andricconstexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
19790b57cec5SDimitry Andric
19800b57cec5SDimitry Andrictemplate <class _Cont> constexpr
19810b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19820b57cec5SDimitry Andricauto data(_Cont& __c)
19830b57cec5SDimitry Andric_NOEXCEPT_(noexcept(__c.data()))
19840b57cec5SDimitry Andric-> decltype        (__c.data())
19850b57cec5SDimitry Andric{ return            __c.data(); }
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andrictemplate <class _Cont> constexpr
19880b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19890b57cec5SDimitry Andricauto data(const _Cont& __c)
19900b57cec5SDimitry Andric_NOEXCEPT_(noexcept(__c.data()))
19910b57cec5SDimitry Andric-> decltype        (__c.data())
19920b57cec5SDimitry Andric{ return            __c.data(); }
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz>
19950b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19960b57cec5SDimitry Andricconstexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
19970b57cec5SDimitry Andric
19980b57cec5SDimitry Andrictemplate <class _Ep>
19990b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20000b57cec5SDimitry Andricconstexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
20010b57cec5SDimitry Andric#endif
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andric
20040b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andric#endif  // _LIBCPP_ITERATOR
2007