3678f64ad3
almost all recent changes to libc++ and libcxxrt. MFC r256642: Since C++ typeinfo objects are currently not guaranteed to be merged at runtime by the dynamic linker, check for their equality in libcxxrt by not only comparing the typeinfo's name pointers, but also comparing the full names, if necessary. (This is similar to what GNU libstdc++ does in its default configuration.) The 'deep' check can be turned off again by defining LIBCXXRT_MERGED_TYPEINFO, and recompiling libcxxrt. Reviewed by: theraven MFC r270522 (by rdivacky): The standard we compile libc++ with is called c++11 not c++0x. MFC r273066 (by bapt): Import patch from libc++ r197313 which allows using libc++ headers with gcc Differential Revision: https://reviews.freebsd.org/D942 Reviewed by: imp MFC r273381 (by bapt): Add support for __cxa_throw_bad_array_new_length in libcxxrt It is required for use with newer g++49 Differential Revision: https://reviews.freebsd.org/D982 Reviewed by: theraven Approved by: theraven MFC r273382 (by bapt): Fix build by marking the new functions as weak This is a temporary fix MFC r273407 (by bapt): When using an external gcc 4.8+ and not building libstdc++ then create in the objectdir a fake libstdc++.so and libstdc++.a which is a symlink on libc++ that allow g++ to satisfy its links dependencies in the least hackish way. Please note that this hacky libstds++ never get installed on the final system Reviewed by: imp MFC r273434 (by bapt): Do not define bad_array_new_length::bad_array_new_length in libc++ anymore when used in combinaison with libcxxrt since it is now defined there already. This fixes building world MFC r276417: Import libcxxrt master 00bc29eb6513624824a6d7db2ebc768a4216a604. Interesting fixes: 76584a0 Reorganize code to use only 32bit atomic ops for 32bit platforms 30d2ae5 Implement __cxa_throw_bad_array_new_length Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D1390 MFC r277217: Import libc++ trunk r224926. This fixes a number of bugs, completes C++14 support[1], adds more C++1z features[2], and fixes the following LWG issues[3]: 1450: Contradiction in regex_constants 2003: String exception inconsistency in erase. 2075: Progress guarantees, lock-free property, and scheduling assumptions 2104: unique_lock move-assignment should not be noexcept 2112: User-defined classes that cannot be derived from 2132: std::function ambiguity 2135: Unclear requirement for exceptions thrown in condition_variable::wait() 2142: packaged_task::operator() synchronization too broad? 2182: Container::[const_]reference types are misleadingly specified 2186: Incomplete action on async/launch::deferred 2188: Reverse iterator does not fully support targets that overload operator& 2193: Default constructors for standard library containers are explicit 2205: Problematic postconditions of regex_match and regex_search 2213: Return value of std::regex_replace 2240: Probable misuse of term "function scope" in [thread.condition] 2252: Strong guarantee on vector::push_back() still broken with C++11? 2257: Simplify container requirements with the new algorithms 2258: a.erase(q1, q2) unable to directly return q2 2263: Comparing iterators and allocator pointers with different const-character 2268: Setting a default argument in the declaration of a member function assign of std::basic_string 2271: regex_traits::lookup_classname specification unclear 2272: quoted should use char_traits::eq for character comparison 2278: User-defined literals for Standard Library types 2280: begin / end for arrays should be constexpr and noexcept 2285: make_reverse_iterator 2288: Inconsistent requirements for shared mutexes 2291: std::hash is vulnerable to collision DoS attack 2293: Wrong facet used by num_put::do_put 2299: Effects of inaccessible key_compare::is_transparent type are not clear 2301: Why is std::tie not constexpr? 2304: Complexity of count in unordered associative containers 2306: match_results::reference should be value_type&, not const value_type& 2308: Clarify container destructor requirements w.r.t. std::array 2313: tuple_size should always derive from integral_constant<size_t, N> 2314: apply() should return decltype(auto) and use decay_t before tuple_size 2315: weak_ptr should be movable 2316: weak_ptr::lock() should be atomic 2317: The type property queries should be UnaryTypeTraits returning size_t 2320: select_on_container_copy_construction() takes allocators, not containers 2322: Associative(initializer_list, stuff) constructors are underspecified 2323: vector::resize(n, t)'s specification should be simplified 2324: Insert iterator constructors should use addressof() 2329: regex_match()/regex_search() with match_results should forbid temporary strings 2330: regex("meow", regex::icase) is technically forbidden but should be permitted 2332: regex_iterator/regex_token_iterator should forbid temporary regexes 2339: Wording issue in nth_element 2341: Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir) 2344: quoted()'s interaction with padding is unclear 2346: integral_constant's member functions should be marked noexcept 2350: min, max, and minmax should be constexpr 2356: Stability of erasure in unordered associative containers 2357: Remaining "Assignable" requirement 2359: How does regex_constants::nosubs affect basic_regex::mark_count()? 2360: reverse_iterator::operator*() is unimplementable [1] http://libcxx.llvm.org/cxx1y_status.html [2] http://libcxx.llvm.org/cxx1z_status.html [3] http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html Exp-run: antoine MFC r277944: Partially revert r273382, to reduce diffs against upstream. This was a temporary fix to solve a conflict with an older version of libc++, and it is no longer relevant. MFC r278010: Revert r256642, not only to reduce diffs against upstream libcxxrt, but also because it is the wrong approach: comparing typeinfo names deeply causes trouble if two loaded DSOs use independent types of the same name. In addition, this particular change was never merged to FreeBSD 10.x and 9.x, so let's get rid of it before it ends up in an 11.x release. Discussed with: theraven, joerg@netbsd MFC r278016: Import libcxxrt master 1cb607e89f6135bbc10f3d3b6fba1f983e258dcc. Interesting fixes: 1cb607e Correct gcc version check for __cxa_begin_catch() declaration with or without throw()
1615 lines
53 KiB
C++
1615 lines
53 KiB
C++
// -*- C++ -*-
|
|
//===-------------------------- iterator ----------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
|
// Source Licenses. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP_ITERATOR
|
|
#define _LIBCPP_ITERATOR
|
|
|
|
/*
|
|
iterator synopsis
|
|
|
|
namespace std
|
|
{
|
|
|
|
template<class Iterator>
|
|
struct iterator_traits
|
|
{
|
|
typedef typename Iterator::difference_type difference_type;
|
|
typedef typename Iterator::value_type value_type;
|
|
typedef typename Iterator::pointer pointer;
|
|
typedef typename Iterator::reference reference;
|
|
typedef typename Iterator::iterator_category iterator_category;
|
|
};
|
|
|
|
template<class T>
|
|
struct iterator_traits<T*>
|
|
{
|
|
typedef ptrdiff_t difference_type;
|
|
typedef T value_type;
|
|
typedef T* pointer;
|
|
typedef T& reference;
|
|
typedef random_access_iterator_tag iterator_category;
|
|
};
|
|
|
|
template<class T>
|
|
struct iterator_traits<const T*>
|
|
{
|
|
typedef ptrdiff_t difference_type;
|
|
typedef T value_type;
|
|
typedef const T* pointer;
|
|
typedef const T& reference;
|
|
typedef random_access_iterator_tag iterator_category;
|
|
};
|
|
|
|
template<class Category, class T, class Distance = ptrdiff_t,
|
|
class Pointer = T*, class Reference = T&>
|
|
struct iterator
|
|
{
|
|
typedef T value_type;
|
|
typedef Distance difference_type;
|
|
typedef Pointer pointer;
|
|
typedef Reference reference;
|
|
typedef Category iterator_category;
|
|
};
|
|
|
|
struct input_iterator_tag {};
|
|
struct output_iterator_tag {};
|
|
struct forward_iterator_tag : public input_iterator_tag {};
|
|
struct bidirectional_iterator_tag : public forward_iterator_tag {};
|
|
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
|
|
|
|
// extension: second argument not conforming to C++03
|
|
template <class InputIterator>
|
|
void advance(InputIterator& i,
|
|
typename iterator_traits<InputIterator>::difference_type n);
|
|
|
|
template <class InputIterator>
|
|
typename iterator_traits<InputIterator>::difference_type
|
|
distance(InputIterator first, InputIterator last);
|
|
|
|
template <class Iterator>
|
|
class reverse_iterator
|
|
: public iterator<typename iterator_traits<Iterator>::iterator_category,
|
|
typename iterator_traits<Iterator>::value_type,
|
|
typename iterator_traits<Iterator>::difference_type,
|
|
typename iterator_traits<Iterator>::pointer,
|
|
typename iterator_traits<Iterator>::reference>
|
|
{
|
|
protected:
|
|
Iterator current;
|
|
public:
|
|
typedef Iterator iterator_type;
|
|
typedef typename iterator_traits<Iterator>::difference_type difference_type;
|
|
typedef typename iterator_traits<Iterator>::reference reference;
|
|
typedef typename iterator_traits<Iterator>::pointer pointer;
|
|
|
|
reverse_iterator();
|
|
explicit reverse_iterator(Iterator x);
|
|
template <class U> reverse_iterator(const reverse_iterator<U>& u);
|
|
Iterator base() const;
|
|
reference operator*() const;
|
|
pointer operator->() const;
|
|
reverse_iterator& operator++();
|
|
reverse_iterator operator++(int);
|
|
reverse_iterator& operator--();
|
|
reverse_iterator operator--(int);
|
|
reverse_iterator operator+ (difference_type n) const;
|
|
reverse_iterator& operator+=(difference_type n);
|
|
reverse_iterator operator- (difference_type n) const;
|
|
reverse_iterator& operator-=(difference_type n);
|
|
reference operator[](difference_type n) const;
|
|
};
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
bool
|
|
operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
bool
|
|
operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
bool
|
|
operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
bool
|
|
operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
bool
|
|
operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
bool
|
|
operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator1, class Iterator2>
|
|
typename reverse_iterator<Iterator1>::difference_type
|
|
operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
template <class Iterator>
|
|
reverse_iterator<Iterator>
|
|
operator+(typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);
|
|
|
|
template <class Iterator> reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14
|
|
|
|
template <class Container>
|
|
class back_insert_iterator
|
|
{
|
|
protected:
|
|
Container* container;
|
|
public:
|
|
typedef Container container_type;
|
|
typedef void value_type;
|
|
typedef void difference_type;
|
|
typedef back_insert_iterator<Cont>& reference;
|
|
typedef void pointer;
|
|
|
|
explicit back_insert_iterator(Container& x);
|
|
back_insert_iterator& operator=(const typename Container::value_type& value);
|
|
back_insert_iterator& operator*();
|
|
back_insert_iterator& operator++();
|
|
back_insert_iterator operator++(int);
|
|
};
|
|
|
|
template <class Container> back_insert_iterator<Container> back_inserter(Container& x);
|
|
|
|
template <class Container>
|
|
class front_insert_iterator
|
|
{
|
|
protected:
|
|
Container* container;
|
|
public:
|
|
typedef Container container_type;
|
|
typedef void value_type;
|
|
typedef void difference_type;
|
|
typedef front_insert_iterator<Cont>& reference;
|
|
typedef void pointer;
|
|
|
|
explicit front_insert_iterator(Container& x);
|
|
front_insert_iterator& operator=(const typename Container::value_type& value);
|
|
front_insert_iterator& operator*();
|
|
front_insert_iterator& operator++();
|
|
front_insert_iterator operator++(int);
|
|
};
|
|
|
|
template <class Container> front_insert_iterator<Container> front_inserter(Container& x);
|
|
|
|
template <class Container>
|
|
class insert_iterator
|
|
{
|
|
protected:
|
|
Container* container;
|
|
typename Container::iterator iter;
|
|
public:
|
|
typedef Container container_type;
|
|
typedef void value_type;
|
|
typedef void difference_type;
|
|
typedef insert_iterator<Cont>& reference;
|
|
typedef void pointer;
|
|
|
|
insert_iterator(Container& x, typename Container::iterator i);
|
|
insert_iterator& operator=(const typename Container::value_type& value);
|
|
insert_iterator& operator*();
|
|
insert_iterator& operator++();
|
|
insert_iterator& operator++(int);
|
|
};
|
|
|
|
template <class Container, class Iterator>
|
|
insert_iterator<Container> inserter(Container& x, Iterator i);
|
|
|
|
template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
|
|
class istream_iterator
|
|
: public iterator<input_iterator_tag, T, Distance, const T*, const T&>
|
|
{
|
|
public:
|
|
typedef charT char_type;
|
|
typedef traits traits_type;
|
|
typedef basic_istream<charT,traits> istream_type;
|
|
|
|
istream_iterator();
|
|
istream_iterator(istream_type& s);
|
|
istream_iterator(const istream_iterator& x);
|
|
~istream_iterator();
|
|
|
|
const T& operator*() const;
|
|
const T* operator->() const;
|
|
istream_iterator& operator++();
|
|
istream_iterator operator++(int);
|
|
};
|
|
|
|
template <class T, class charT, class traits, class Distance>
|
|
bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
|
|
const istream_iterator<T,charT,traits,Distance>& y);
|
|
template <class T, class charT, class traits, class Distance>
|
|
bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
|
|
const istream_iterator<T,charT,traits,Distance>& y);
|
|
|
|
template <class T, class charT = char, class traits = char_traits<charT> >
|
|
class ostream_iterator
|
|
: public iterator<output_iterator_tag, void, void, void ,void>
|
|
{
|
|
public:
|
|
typedef charT char_type;
|
|
typedef traits traits_type;
|
|
typedef basic_ostream<charT,traits> ostream_type;
|
|
|
|
ostream_iterator(ostream_type& s);
|
|
ostream_iterator(ostream_type& s, const charT* delimiter);
|
|
ostream_iterator(const ostream_iterator& x);
|
|
~ostream_iterator();
|
|
ostream_iterator& operator=(const T& value);
|
|
|
|
ostream_iterator& operator*();
|
|
ostream_iterator& operator++();
|
|
ostream_iterator& operator++(int);
|
|
};
|
|
|
|
template<class charT, class traits = char_traits<charT> >
|
|
class istreambuf_iterator
|
|
: public iterator<input_iterator_tag, charT,
|
|
typename traits::off_type, unspecified,
|
|
charT>
|
|
{
|
|
public:
|
|
typedef charT char_type;
|
|
typedef traits traits_type;
|
|
typedef typename traits::int_type int_type;
|
|
typedef basic_streambuf<charT,traits> streambuf_type;
|
|
typedef basic_istream<charT,traits> istream_type;
|
|
|
|
istreambuf_iterator() noexcept;
|
|
istreambuf_iterator(istream_type& s) noexcept;
|
|
istreambuf_iterator(streambuf_type* s) noexcept;
|
|
istreambuf_iterator(a-private-type) noexcept;
|
|
|
|
charT operator*() const;
|
|
pointer operator->() const;
|
|
istreambuf_iterator& operator++();
|
|
a-private-type operator++(int);
|
|
|
|
bool equal(const istreambuf_iterator& b) const;
|
|
};
|
|
|
|
template <class charT, class traits>
|
|
bool operator==(const istreambuf_iterator<charT,traits>& a,
|
|
const istreambuf_iterator<charT,traits>& b);
|
|
template <class charT, class traits>
|
|
bool operator!=(const istreambuf_iterator<charT,traits>& a,
|
|
const istreambuf_iterator<charT,traits>& b);
|
|
|
|
template <class charT, class traits = char_traits<charT> >
|
|
class ostreambuf_iterator
|
|
: public iterator<output_iterator_tag, void, void, void, void>
|
|
{
|
|
public:
|
|
typedef charT char_type;
|
|
typedef traits traits_type;
|
|
typedef basic_streambuf<charT,traits> streambuf_type;
|
|
typedef basic_ostream<charT,traits> ostream_type;
|
|
|
|
ostreambuf_iterator(ostream_type& s) noexcept;
|
|
ostreambuf_iterator(streambuf_type* s) noexcept;
|
|
ostreambuf_iterator& operator=(charT c);
|
|
ostreambuf_iterator& operator*();
|
|
ostreambuf_iterator& operator++();
|
|
ostreambuf_iterator& operator++(int);
|
|
bool failed() const noexcept;
|
|
};
|
|
|
|
template <class C> auto begin(C& c) -> decltype(c.begin());
|
|
template <class C> auto begin(const C& c) -> decltype(c.begin());
|
|
template <class C> auto end(C& c) -> decltype(c.end());
|
|
template <class C> auto end(const C& c) -> decltype(c.end());
|
|
template <class T, size_t N> T* begin(T (&array)[N]);
|
|
template <class T, size_t N> T* end(T (&array)[N]);
|
|
|
|
template <class C> auto cbegin(const C& c) -> decltype(std::begin(c)); // C++14
|
|
template <class C> auto cend(const C& c) -> decltype(std::end(c)); // C++14
|
|
template <class C> auto rbegin(C& c) -> decltype(c.rbegin()); // C++14
|
|
template <class C> auto rbegin(const C& c) -> decltype(c.rbegin()); // C++14
|
|
template <class C> auto rend(C& c) -> decltype(c.rend()); // C++14
|
|
template <class C> auto rend(const C& c) -> decltype(c.rend()); // C++14
|
|
template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14
|
|
template <class E> reverse_iterator<const E*> rend(initializer_list<E> il); // C++14
|
|
template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]); // C++14
|
|
template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]); // C++14
|
|
template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14
|
|
template <class C> auto crend(const C& c) -> decltype(std::rend(c)); // C++14
|
|
|
|
// 24.8, container access:
|
|
template <class C> constexpr auto size(const C& c) -> decltype(c.size()); // C++17
|
|
template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
|
|
template <class C> constexpr auto empty(const C& c) -> decltype(c.empty()); // C++17
|
|
template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept; // C++17
|
|
template <class E> constexpr bool empty(initializer_list<E> il) noexcept; // C++17
|
|
template <class C> constexpr auto data(C& c) -> decltype(c.data()); // C++17
|
|
template <class C> constexpr auto data(const C& c) -> decltype(c.data()); // C++17
|
|
template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept; // C++17
|
|
template <class E> constexpr const E* data(initializer_list<E> il) noexcept; // C++17
|
|
|
|
} // std
|
|
|
|
*/
|
|
|
|
#include <__config>
|
|
#include <__functional_base>
|
|
#include <type_traits>
|
|
#include <cstddef>
|
|
#include <iosfwd>
|
|
#include <initializer_list>
|
|
#ifdef __APPLE__
|
|
#include <Availability.h>
|
|
#endif
|
|
|
|
#include <__debug>
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
#pragma GCC system_header
|
|
#endif
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
struct _LIBCPP_TYPE_VIS_ONLY input_iterator_tag {};
|
|
struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};
|
|
struct _LIBCPP_TYPE_VIS_ONLY forward_iterator_tag : public input_iterator_tag {};
|
|
struct _LIBCPP_TYPE_VIS_ONLY bidirectional_iterator_tag : public forward_iterator_tag {};
|
|
struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {};
|
|
|
|
template <class _Tp>
|
|
struct __has_iterator_category
|
|
{
|
|
private:
|
|
struct __two {char __lx; char __lxx;};
|
|
template <class _Up> static __two __test(...);
|
|
template <class _Up> static char __test(typename _Up::iterator_category* = 0);
|
|
public:
|
|
static const bool value = sizeof(__test<_Tp>(0)) == 1;
|
|
};
|
|
|
|
template <class _Iter, bool> struct __iterator_traits_impl {};
|
|
|
|
template <class _Iter>
|
|
struct __iterator_traits_impl<_Iter, true>
|
|
{
|
|
typedef typename _Iter::difference_type difference_type;
|
|
typedef typename _Iter::value_type value_type;
|
|
typedef typename _Iter::pointer pointer;
|
|
typedef typename _Iter::reference reference;
|
|
typedef typename _Iter::iterator_category iterator_category;
|
|
};
|
|
|
|
template <class _Iter, bool> struct __iterator_traits {};
|
|
|
|
template <class _Iter>
|
|
struct __iterator_traits<_Iter, true>
|
|
: __iterator_traits_impl
|
|
<
|
|
_Iter,
|
|
is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
|
|
is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
|
|
>
|
|
{};
|
|
|
|
// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
|
|
// exists. Else iterator_traits<Iterator> will be an empty class. This is a
|
|
// conforming extension which allows some programs to compile and behave as
|
|
// the client expects instead of failing at compile time.
|
|
|
|
template <class _Iter>
|
|
struct _LIBCPP_TYPE_VIS_ONLY iterator_traits
|
|
: __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};
|
|
|
|
template<class _Tp>
|
|
struct _LIBCPP_TYPE_VIS_ONLY iterator_traits<_Tp*>
|
|
{
|
|
typedef ptrdiff_t difference_type;
|
|
typedef typename remove_const<_Tp>::type value_type;
|
|
typedef _Tp* pointer;
|
|
typedef _Tp& reference;
|
|
typedef random_access_iterator_tag iterator_category;
|
|
};
|
|
|
|
template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
|
|
struct __has_iterator_category_convertible_to
|
|
: public integral_constant<bool, is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>::value>
|
|
{};
|
|
|
|
template <class _Tp, class _Up>
|
|
struct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {};
|
|
|
|
template <class _Tp>
|
|
struct __is_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
|
|
|
|
template <class _Tp>
|
|
struct __is_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
|
|
|
|
template <class _Tp>
|
|
struct __is_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
|
|
|
|
template <class _Tp>
|
|
struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
|
|
|
|
template<class _Category, class _Tp, class _Distance = ptrdiff_t,
|
|
class _Pointer = _Tp*, class _Reference = _Tp&>
|
|
struct _LIBCPP_TYPE_VIS_ONLY iterator
|
|
{
|
|
typedef _Tp value_type;
|
|
typedef _Distance difference_type;
|
|
typedef _Pointer pointer;
|
|
typedef _Reference reference;
|
|
typedef _Category iterator_category;
|
|
};
|
|
|
|
template <class _InputIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
void __advance(_InputIter& __i,
|
|
typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)
|
|
{
|
|
for (; __n > 0; --__n)
|
|
++__i;
|
|
}
|
|
|
|
template <class _BiDirIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
void __advance(_BiDirIter& __i,
|
|
typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag)
|
|
{
|
|
if (__n >= 0)
|
|
for (; __n > 0; --__n)
|
|
++__i;
|
|
else
|
|
for (; __n < 0; ++__n)
|
|
--__i;
|
|
}
|
|
|
|
template <class _RandIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
void __advance(_RandIter& __i,
|
|
typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)
|
|
{
|
|
__i += __n;
|
|
}
|
|
|
|
template <class _InputIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
void advance(_InputIter& __i,
|
|
typename iterator_traits<_InputIter>::difference_type __n)
|
|
{
|
|
__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
|
|
}
|
|
|
|
template <class _InputIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename iterator_traits<_InputIter>::difference_type
|
|
__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
|
|
{
|
|
typename iterator_traits<_InputIter>::difference_type __r(0);
|
|
for (; __first != __last; ++__first)
|
|
++__r;
|
|
return __r;
|
|
}
|
|
|
|
template <class _RandIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename iterator_traits<_RandIter>::difference_type
|
|
__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
|
|
{
|
|
return __last - __first;
|
|
}
|
|
|
|
template <class _InputIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename iterator_traits<_InputIter>::difference_type
|
|
distance(_InputIter __first, _InputIter __last)
|
|
{
|
|
return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
|
|
}
|
|
|
|
template <class _ForwardIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
_ForwardIter
|
|
next(_ForwardIter __x,
|
|
typename iterator_traits<_ForwardIter>::difference_type __n = 1,
|
|
typename enable_if<__is_forward_iterator<_ForwardIter>::value>::type* = 0)
|
|
{
|
|
_VSTD::advance(__x, __n);
|
|
return __x;
|
|
}
|
|
|
|
template <class _BidiretionalIter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
_BidiretionalIter
|
|
prev(_BidiretionalIter __x,
|
|
typename iterator_traits<_BidiretionalIter>::difference_type __n = 1,
|
|
typename enable_if<__is_bidirectional_iterator<_BidiretionalIter>::value>::type* = 0)
|
|
{
|
|
_VSTD::advance(__x, -__n);
|
|
return __x;
|
|
}
|
|
|
|
template <class _Iter>
|
|
class _LIBCPP_TYPE_VIS_ONLY reverse_iterator
|
|
: public iterator<typename iterator_traits<_Iter>::iterator_category,
|
|
typename iterator_traits<_Iter>::value_type,
|
|
typename iterator_traits<_Iter>::difference_type,
|
|
typename iterator_traits<_Iter>::pointer,
|
|
typename iterator_traits<_Iter>::reference>
|
|
{
|
|
private:
|
|
mutable _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
|
|
protected:
|
|
_Iter current;
|
|
public:
|
|
typedef _Iter iterator_type;
|
|
typedef typename iterator_traits<_Iter>::difference_type difference_type;
|
|
typedef typename iterator_traits<_Iter>::reference reference;
|
|
typedef typename iterator_traits<_Iter>::pointer pointer;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {}
|
|
_LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
|
|
template <class _Up> _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u)
|
|
: __t(__u.base()), current(__u.base()) {}
|
|
_LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;}
|
|
_LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY pointer operator->() const {return _VSTD::addressof(operator*());}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator++(int)
|
|
{reverse_iterator __tmp(*this); --current; return __tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator--(int)
|
|
{reverse_iterator __tmp(*this); ++current; return __tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator+ (difference_type __n) const
|
|
{return reverse_iterator(current - __n);}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n)
|
|
{current -= __n; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator operator- (difference_type __n) const
|
|
{return reverse_iterator(current + __n);}
|
|
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n)
|
|
{current += __n; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
|
|
{return current[-__n-1];}
|
|
};
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() == __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() > __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() != __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() < __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() <= __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() >= __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename reverse_iterator<_Iter1>::difference_type
|
|
operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
{
|
|
return __y.base() - __x.base();
|
|
}
|
|
|
|
template <class _Iter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator<_Iter>
|
|
operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
|
|
{
|
|
return reverse_iterator<_Iter>(__x.base() - __n);
|
|
}
|
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
template <class _Iter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
|
|
{
|
|
return reverse_iterator<_Iter>(__i);
|
|
}
|
|
#endif
|
|
|
|
template <class _Container>
|
|
class _LIBCPP_TYPE_VIS_ONLY back_insert_iterator
|
|
: public iterator<output_iterator_tag,
|
|
void,
|
|
void,
|
|
void,
|
|
back_insert_iterator<_Container>&>
|
|
{
|
|
protected:
|
|
_Container* container;
|
|
public:
|
|
typedef _Container container_type;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
|
|
{container->push_back(__value_); return *this;}
|
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)
|
|
{container->push_back(_VSTD::move(__value_)); return *this;}
|
|
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator operator++(int) {return *this;}
|
|
};
|
|
|
|
template <class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
back_insert_iterator<_Container>
|
|
back_inserter(_Container& __x)
|
|
{
|
|
return back_insert_iterator<_Container>(__x);
|
|
}
|
|
|
|
template <class _Container>
|
|
class _LIBCPP_TYPE_VIS_ONLY front_insert_iterator
|
|
: public iterator<output_iterator_tag,
|
|
void,
|
|
void,
|
|
void,
|
|
front_insert_iterator<_Container>&>
|
|
{
|
|
protected:
|
|
_Container* container;
|
|
public:
|
|
typedef _Container container_type;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)
|
|
{container->push_front(__value_); return *this;}
|
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)
|
|
{container->push_front(_VSTD::move(__value_)); return *this;}
|
|
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator operator++(int) {return *this;}
|
|
};
|
|
|
|
template <class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
front_insert_iterator<_Container>
|
|
front_inserter(_Container& __x)
|
|
{
|
|
return front_insert_iterator<_Container>(__x);
|
|
}
|
|
|
|
template <class _Container>
|
|
class _LIBCPP_TYPE_VIS_ONLY insert_iterator
|
|
: public iterator<output_iterator_tag,
|
|
void,
|
|
void,
|
|
void,
|
|
insert_iterator<_Container>&>
|
|
{
|
|
protected:
|
|
_Container* container;
|
|
typename _Container::iterator iter;
|
|
public:
|
|
typedef _Container container_type;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
|
|
: container(_VSTD::addressof(__x)), iter(__i) {}
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)
|
|
{iter = container->insert(iter, __value_); ++iter; return *this;}
|
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)
|
|
{iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
|
|
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator*() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator++() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int) {return *this;}
|
|
};
|
|
|
|
template <class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
insert_iterator<_Container>
|
|
inserter(_Container& __x, typename _Container::iterator __i)
|
|
{
|
|
return insert_iterator<_Container>(__x, __i);
|
|
}
|
|
|
|
template <class _Tp, class _CharT = char,
|
|
class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
|
|
class _LIBCPP_TYPE_VIS_ONLY istream_iterator
|
|
: public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
|
|
{
|
|
public:
|
|
typedef _CharT char_type;
|
|
typedef _Traits traits_type;
|
|
typedef basic_istream<_CharT,_Traits> istream_type;
|
|
private:
|
|
istream_type* __in_stream_;
|
|
_Tp __value_;
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY istream_iterator() : __in_stream_(0) {}
|
|
_LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s)
|
|
{
|
|
if (!(*__in_stream_ >> __value_))
|
|
__in_stream_ = 0;
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
|
|
_LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return &(operator*());}
|
|
_LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
|
|
{
|
|
if (!(*__in_stream_ >> __value_))
|
|
__in_stream_ = 0;
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int)
|
|
{istream_iterator __t(*this); ++(*this); return __t;}
|
|
|
|
friend _LIBCPP_INLINE_VISIBILITY
|
|
bool operator==(const istream_iterator& __x, const istream_iterator& __y)
|
|
{return __x.__in_stream_ == __y.__in_stream_;}
|
|
|
|
friend _LIBCPP_INLINE_VISIBILITY
|
|
bool operator!=(const istream_iterator& __x, const istream_iterator& __y)
|
|
{return !(__x == __y);}
|
|
};
|
|
|
|
template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
|
|
class _LIBCPP_TYPE_VIS_ONLY ostream_iterator
|
|
: public iterator<output_iterator_tag, void, void, void, void>
|
|
{
|
|
public:
|
|
typedef _CharT char_type;
|
|
typedef _Traits traits_type;
|
|
typedef basic_ostream<_CharT,_Traits> ostream_type;
|
|
private:
|
|
ostream_type* __out_stream_;
|
|
const char_type* __delim_;
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s)
|
|
: __out_stream_(&__s), __delim_(0) {}
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter)
|
|
: __out_stream_(&__s), __delim_(__delimiter) {}
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
|
|
{
|
|
*__out_stream_ << __value_;
|
|
if (__delim_)
|
|
*__out_stream_ << __delim_;
|
|
return *this;
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
|
|
};
|
|
|
|
template<class _CharT, class _Traits>
|
|
class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator
|
|
: public iterator<input_iterator_tag, _CharT,
|
|
typename _Traits::off_type, _CharT*,
|
|
_CharT>
|
|
{
|
|
public:
|
|
typedef _CharT char_type;
|
|
typedef _Traits traits_type;
|
|
typedef typename _Traits::int_type int_type;
|
|
typedef basic_streambuf<_CharT,_Traits> streambuf_type;
|
|
typedef basic_istream<_CharT,_Traits> istream_type;
|
|
private:
|
|
mutable streambuf_type* __sbuf_;
|
|
|
|
class __proxy
|
|
{
|
|
char_type __keep_;
|
|
streambuf_type* __sbuf_;
|
|
_LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
|
|
: __keep_(__c), __sbuf_(__s) {}
|
|
friend class istreambuf_iterator;
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
|
|
};
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool __test_for_eof() const
|
|
{
|
|
if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
|
|
__sbuf_ = 0;
|
|
return __sbuf_ == 0;
|
|
}
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
|
|
: __sbuf_(__s.rdbuf()) {}
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
|
|
: __sbuf_(__s) {}
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
|
|
: __sbuf_(__p.__sbuf_) {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY char_type operator*() const
|
|
{return static_cast<char_type>(__sbuf_->sgetc());}
|
|
_LIBCPP_INLINE_VISIBILITY char_type* operator->() const {return nullptr;}
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
|
|
{
|
|
__sbuf_->sbumpc();
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY __proxy operator++(int)
|
|
{
|
|
return __proxy(__sbuf_->sbumpc(), __sbuf_);
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
|
|
{return __test_for_eof() == __b.__test_for_eof();}
|
|
};
|
|
|
|
template <class _CharT, class _Traits>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
|
|
const istreambuf_iterator<_CharT,_Traits>& __b)
|
|
{return __a.equal(__b);}
|
|
|
|
template <class _CharT, class _Traits>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
|
|
const istreambuf_iterator<_CharT,_Traits>& __b)
|
|
{return !__a.equal(__b);}
|
|
|
|
template <class _CharT, class _Traits>
|
|
class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator
|
|
: public iterator<output_iterator_tag, void, void, void, void>
|
|
{
|
|
public:
|
|
typedef _CharT char_type;
|
|
typedef _Traits traits_type;
|
|
typedef basic_streambuf<_CharT,_Traits> streambuf_type;
|
|
typedef basic_ostream<_CharT,_Traits> ostream_type;
|
|
private:
|
|
streambuf_type* __sbuf_;
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
|
|
: __sbuf_(__s.rdbuf()) {}
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
|
|
: __sbuf_(__s) {}
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
|
|
{
|
|
if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
|
|
__sbuf_ = 0;
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;}
|
|
|
|
#if !defined(__APPLE__) || \
|
|
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
|
|
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
|
|
|
|
template <class _Ch, class _Tr>
|
|
friend
|
|
_LIBCPP_HIDDEN
|
|
ostreambuf_iterator<_Ch, _Tr>
|
|
__pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
|
|
const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
|
|
ios_base& __iob, _Ch __fl);
|
|
#endif
|
|
};
|
|
|
|
template <class _Iter>
|
|
class _LIBCPP_TYPE_VIS_ONLY move_iterator
|
|
{
|
|
private:
|
|
_Iter __i;
|
|
public:
|
|
typedef _Iter iterator_type;
|
|
typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
|
|
typedef typename iterator_traits<iterator_type>::value_type value_type;
|
|
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
|
|
typedef typename iterator_traits<iterator_type>::pointer pointer;
|
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
typedef value_type&& reference;
|
|
#else
|
|
typedef typename iterator_traits<iterator_type>::reference reference;
|
|
#endif
|
|
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator() : __i() {}
|
|
_LIBCPP_INLINE_VISIBILITY explicit move_iterator(_Iter __x) : __i(__x) {}
|
|
template <class _Up> _LIBCPP_INLINE_VISIBILITY move_iterator(const move_iterator<_Up>& __u)
|
|
: __i(__u.base()) {}
|
|
_LIBCPP_INLINE_VISIBILITY _Iter base() const {return __i;}
|
|
_LIBCPP_INLINE_VISIBILITY reference operator*() const {
|
|
return static_cast<reference>(*__i);
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY pointer operator->() const {
|
|
typename iterator_traits<iterator_type>::reference __ref = *__i;
|
|
return &__ref;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator& operator++() {++__i; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator operator++(int)
|
|
{move_iterator __tmp(*this); ++__i; return __tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator& operator--() {--__i; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator operator--(int)
|
|
{move_iterator __tmp(*this); --__i; return __tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator operator+ (difference_type __n) const
|
|
{return move_iterator(__i + __n);}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator& operator+=(difference_type __n)
|
|
{__i += __n; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator operator- (difference_type __n) const
|
|
{return move_iterator(__i - __n);}
|
|
_LIBCPP_INLINE_VISIBILITY move_iterator& operator-=(difference_type __n)
|
|
{__i -= __n; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
|
|
{
|
|
return static_cast<reference>(__i[__n]);
|
|
}
|
|
};
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() == __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() < __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() != __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() > __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() >= __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() <= __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename move_iterator<_Iter1>::difference_type
|
|
operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
{
|
|
return __x.base() - __y.base();
|
|
}
|
|
|
|
template <class _Iter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
move_iterator<_Iter>
|
|
operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
|
|
{
|
|
return move_iterator<_Iter>(__x.base() + __n);
|
|
}
|
|
|
|
template <class _Iter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
move_iterator<_Iter>
|
|
make_move_iterator(_Iter __i)
|
|
{
|
|
return move_iterator<_Iter>(__i);
|
|
}
|
|
|
|
// __wrap_iter
|
|
|
|
template <class _Iter> class __wrap_iter;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
typename __wrap_iter<_Iter1>::difference_type
|
|
operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
__wrap_iter<_Iter>
|
|
operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
|
|
|
|
template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op);
|
|
template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2);
|
|
template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op);
|
|
template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2);
|
|
|
|
template <class _Tp>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
typename enable_if
|
|
<
|
|
is_trivially_copy_assignable<_Tp>::value,
|
|
_Tp*
|
|
>::type
|
|
__unwrap_iter(__wrap_iter<_Tp*>);
|
|
|
|
template <class _Iter>
|
|
class __wrap_iter
|
|
{
|
|
public:
|
|
typedef _Iter iterator_type;
|
|
typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
|
|
typedef typename iterator_traits<iterator_type>::value_type value_type;
|
|
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
|
|
typedef typename iterator_traits<iterator_type>::pointer pointer;
|
|
typedef typename iterator_traits<iterator_type>::reference reference;
|
|
private:
|
|
iterator_type __i;
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT
|
|
#if _LIBCPP_STD_VER > 11
|
|
: __i{}
|
|
#endif
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
__get_db()->__insert_i(this);
|
|
#endif
|
|
}
|
|
template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u,
|
|
typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT
|
|
: __i(__u.base())
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
__get_db()->__iterator_copy(this, &__u);
|
|
#endif
|
|
}
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
__wrap_iter(const __wrap_iter& __x)
|
|
: __i(__x.base())
|
|
{
|
|
__get_db()->__iterator_copy(this, &__x);
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
__wrap_iter& operator=(const __wrap_iter& __x)
|
|
{
|
|
if (this != &__x)
|
|
{
|
|
__get_db()->__iterator_copy(this, &__x);
|
|
__i = __x.__i;
|
|
}
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
~__wrap_iter()
|
|
{
|
|
__get_db()->__erase_i(this);
|
|
}
|
|
#endif
|
|
_LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
|
"Attempted to dereference a non-dereferenceable iterator");
|
|
#endif
|
|
return *__i;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
|
"Attempted to dereference a non-dereferenceable iterator");
|
|
#endif
|
|
return (pointer)&reinterpret_cast<const volatile char&>(*__i);
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
|
"Attempted to increment non-incrementable iterator");
|
|
#endif
|
|
++__i;
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT
|
|
{__wrap_iter __tmp(*this); ++(*this); return __tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
|
|
"Attempted to decrement non-decrementable iterator");
|
|
#endif
|
|
--__i;
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT
|
|
{__wrap_iter __tmp(*this); --(*this); return __tmp;}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT
|
|
{__wrap_iter __w(*this); __w += __n; return __w;}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
|
|
"Attempted to add/subtract iterator outside of valid range");
|
|
#endif
|
|
__i += __n;
|
|
return *this;
|
|
}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT
|
|
{return *this + (-__n);}
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
|
|
{*this += -__n; return *this;}
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
|
|
"Attempted to subscript iterator outside of valid range");
|
|
#endif
|
|
return __i[__n];
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;}
|
|
|
|
private:
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
|
|
{
|
|
__get_db()->__insert_ic(this, __p);
|
|
}
|
|
#else
|
|
_LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
|
|
#endif
|
|
|
|
template <class _Up> friend class __wrap_iter;
|
|
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
|
|
template <class _Tp, class _Alloc> friend class vector;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
bool
|
|
operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
bool
|
|
operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
bool
|
|
operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
bool
|
|
operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
bool
|
|
operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
bool
|
|
operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
friend
|
|
typename __wrap_iter<_Iter1>::difference_type
|
|
operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
|
|
|
template <class _Iter1>
|
|
friend
|
|
__wrap_iter<_Iter1>
|
|
operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
|
|
|
|
template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);
|
|
template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2);
|
|
template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);
|
|
template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);
|
|
|
|
template <class _Tp>
|
|
friend
|
|
typename enable_if
|
|
<
|
|
is_trivially_copy_assignable<_Tp>::value,
|
|
_Tp*
|
|
>::type
|
|
__unwrap_iter(__wrap_iter<_Tp*>);
|
|
};
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
return __x.base() == __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
|
|
"Attempted to compare incomparable iterators");
|
|
#endif
|
|
return __x.base() < __y.base();
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
return !(__x == __y);
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
return __y < __x;
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
return !(__x < __y);
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
return !(__y < __x);
|
|
}
|
|
|
|
template <class _Iter1>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
|
{
|
|
return !(__x == __y);
|
|
}
|
|
|
|
template <class _Iter1>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
|
{
|
|
return __y < __x;
|
|
}
|
|
|
|
template <class _Iter1>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
|
{
|
|
return !(__x < __y);
|
|
}
|
|
|
|
template <class _Iter1>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
|
{
|
|
return !(__y < __x);
|
|
}
|
|
|
|
template <class _Iter1, class _Iter2>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename __wrap_iter<_Iter1>::difference_type
|
|
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
|
{
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
_LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
|
|
"Attempted to subtract incompatible iterators");
|
|
#endif
|
|
return __x.base() - __y.base();
|
|
}
|
|
|
|
template <class _Iter>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
__wrap_iter<_Iter>
|
|
operator+(typename __wrap_iter<_Iter>::difference_type __n,
|
|
__wrap_iter<_Iter> __x) _NOEXCEPT
|
|
{
|
|
__x += __n;
|
|
return __x;
|
|
}
|
|
|
|
template <class _Tp, size_t _Np>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
_Tp*
|
|
begin(_Tp (&__array)[_Np])
|
|
{
|
|
return __array;
|
|
}
|
|
|
|
template <class _Tp, size_t _Np>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
_Tp*
|
|
end(_Tp (&__array)[_Np])
|
|
{
|
|
return __array + _Np;
|
|
}
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto
|
|
begin(_Cp& __c) -> decltype(__c.begin())
|
|
{
|
|
return __c.begin();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto
|
|
begin(const _Cp& __c) -> decltype(__c.begin())
|
|
{
|
|
return __c.begin();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto
|
|
end(_Cp& __c) -> decltype(__c.end())
|
|
{
|
|
return __c.end();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto
|
|
end(const _Cp& __c) -> decltype(__c.end())
|
|
{
|
|
return __c.end();
|
|
}
|
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class _Tp, size_t _Np>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
|
|
{
|
|
return reverse_iterator<_Tp*>(__array + _Np);
|
|
}
|
|
|
|
template <class _Tp, size_t _Np>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
|
|
{
|
|
return reverse_iterator<_Tp*>(__array);
|
|
}
|
|
|
|
template <class _Ep>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
|
|
{
|
|
return reverse_iterator<const _Ep*>(__il.end());
|
|
}
|
|
|
|
template <class _Ep>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
|
|
{
|
|
return reverse_iterator<const _Ep*>(__il.begin());
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
auto cbegin(const _Cp& __c) -> decltype(begin(__c))
|
|
{
|
|
return begin(__c);
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
auto cend(const _Cp& __c) -> decltype(end(__c))
|
|
{
|
|
return end(__c);
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
|
|
{
|
|
return __c.rbegin();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
|
|
{
|
|
return __c.rbegin();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto rend(_Cp& __c) -> decltype(__c.rend())
|
|
{
|
|
return __c.rend();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto rend(const _Cp& __c) -> decltype(__c.rend())
|
|
{
|
|
return __c.rend();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto crbegin(const _Cp& __c) -> decltype(rbegin(__c))
|
|
{
|
|
return rbegin(__c);
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
auto crend(const _Cp& __c) -> decltype(rend(__c))
|
|
{
|
|
return rend(__c);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename _Cp::iterator
|
|
begin(_Cp& __c)
|
|
{
|
|
return __c.begin();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename _Cp::const_iterator
|
|
begin(const _Cp& __c)
|
|
{
|
|
return __c.begin();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename _Cp::iterator
|
|
end(_Cp& __c)
|
|
{
|
|
return __c.end();
|
|
}
|
|
|
|
template <class _Cp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename _Cp::const_iterator
|
|
end(const _Cp& __c)
|
|
{
|
|
return __c.end();
|
|
}
|
|
|
|
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
|
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
template <class _C>
|
|
constexpr auto size(const _C& __c) -> decltype(__c.size()) { return __c.size(); }
|
|
|
|
template <class _Tp, size_t _N>
|
|
constexpr size_t size(const _Tp (&__array)[_N]) noexcept { return _N; }
|
|
|
|
template <class _C>
|
|
constexpr auto empty(const _C& __c) -> decltype(__c.empty()) { return __c.empty(); }
|
|
|
|
template <class _Tp, size_t _N>
|
|
constexpr bool empty(const _Tp (&__array)[_N]) noexcept { return false; }
|
|
|
|
template <class _Ep>
|
|
constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
|
|
|
|
template <class _C> constexpr
|
|
auto data(_C& __c) -> decltype(__c.data()) { return __c.data(); }
|
|
|
|
template <class _C> constexpr
|
|
auto data(const _C& __c) -> decltype(__c.data()) { return __c.data(); }
|
|
|
|
template <class _Tp, size_t _N>
|
|
constexpr _Tp* data(_Tp (&__array)[_N]) noexcept { return __array; }
|
|
|
|
template <class _Ep>
|
|
constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
|
|
#endif
|
|
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
#endif // _LIBCPP_ITERATOR
|