2010-05-12 03:42:16 +08:00
|
|
|
// -*- C++ -*-
|
|
|
|
//===-------------------------- iterator ----------------------------------===//
|
|
|
|
//
|
2019-01-19 18:56:40 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#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 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 {};
|
|
|
|
|
2017-05-18 02:51:36 +08:00
|
|
|
// 27.4.3, iterator operations
|
2010-05-12 03:42:16 +08:00
|
|
|
// extension: second argument not conforming to C++03
|
2017-05-18 02:51:36 +08:00
|
|
|
template <class InputIterator> // constexpr in C++17
|
|
|
|
constexpr void advance(InputIterator& i,
|
2010-05-12 03:42:16 +08:00
|
|
|
typename iterator_traits<InputIterator>::difference_type n);
|
|
|
|
|
2017-05-18 02:51:36 +08:00
|
|
|
template <class InputIterator> // constexpr in C++17
|
|
|
|
constexpr typename iterator_traits<InputIterator>::difference_type
|
|
|
|
distance(InputIterator first, InputIterator last);
|
|
|
|
|
|
|
|
template <class InputIterator> // constexpr in C++17
|
|
|
|
constexpr InputIterator next(InputIterator x,
|
|
|
|
typename iterator_traits<InputIterator>::difference_type n = 1);
|
|
|
|
|
|
|
|
template <class BidirectionalIterator> // constexpr in C++17
|
|
|
|
constexpr BidirectionalIterator prev(BidirectionalIterator x,
|
2019-05-30 00:01:36 +08:00
|
|
|
typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
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;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr reverse_iterator();
|
|
|
|
constexpr explicit reverse_iterator(Iterator x);
|
|
|
|
template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
|
|
|
|
template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
|
|
|
|
constexpr Iterator base() const;
|
|
|
|
constexpr reference operator*() const;
|
|
|
|
constexpr pointer operator->() const;
|
|
|
|
constexpr reverse_iterator& operator++();
|
|
|
|
constexpr reverse_iterator operator++(int);
|
|
|
|
constexpr reverse_iterator& operator--();
|
|
|
|
constexpr reverse_iterator operator--(int);
|
|
|
|
constexpr reverse_iterator operator+ (difference_type n) const;
|
|
|
|
constexpr reverse_iterator& operator+=(difference_type n);
|
|
|
|
constexpr reverse_iterator operator- (difference_type n) const;
|
|
|
|
constexpr reverse_iterator& operator-=(difference_type n);
|
|
|
|
constexpr reference operator[](difference_type n) const;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr auto
|
2016-07-09 00:54:47 +08:00
|
|
|
operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y)
|
2016-10-19 23:12:50 +08:00
|
|
|
-> decltype(__y.base() - __x.base()); // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class Iterator>
|
2016-10-19 23:12:50 +08:00
|
|
|
constexpr reverse_iterator<Iterator>
|
2019-05-30 00:01:36 +08:00
|
|
|
operator+(typename reverse_iterator<Iterator>::difference_type n,
|
2016-10-19 23:12:50 +08:00
|
|
|
const reverse_iterator<Iterator>& x); // constexpr in C++17
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-10-19 23:12:50 +08:00
|
|
|
template <class Iterator>
|
|
|
|
constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17
|
2014-03-03 09:24:04 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class Container>
|
|
|
|
class back_insert_iterator
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
Container* container;
|
|
|
|
public:
|
|
|
|
typedef Container container_type;
|
|
|
|
typedef void value_type;
|
|
|
|
typedef void difference_type;
|
2016-06-30 12:40:50 +08:00
|
|
|
typedef void reference;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef void pointer;
|
|
|
|
|
|
|
|
explicit back_insert_iterator(Container& x);
|
2010-09-15 04:26:27 +08:00
|
|
|
back_insert_iterator& operator=(const typename Container::value_type& value);
|
2010-05-12 03:42:16 +08:00
|
|
|
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;
|
2016-06-30 12:40:50 +08:00
|
|
|
typedef void reference;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef void pointer;
|
|
|
|
|
|
|
|
explicit front_insert_iterator(Container& x);
|
2010-09-15 04:26:27 +08:00
|
|
|
front_insert_iterator& operator=(const typename Container::value_type& value);
|
2010-05-12 03:42:16 +08:00
|
|
|
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;
|
2016-06-30 12:40:50 +08:00
|
|
|
typedef void reference;
|
2010-05-12 03:42:16 +08:00
|
|
|
typedef void pointer;
|
|
|
|
|
|
|
|
insert_iterator(Container& x, typename Container::iterator i);
|
2010-09-15 04:26:27 +08:00
|
|
|
insert_iterator& operator=(const typename Container::value_type& value);
|
2010-05-12 03:42:16 +08:00
|
|
|
insert_iterator& operator*();
|
|
|
|
insert_iterator& operator++();
|
|
|
|
insert_iterator& operator++(int);
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class Container, class Iterator>
|
|
|
|
insert_iterator<Container> inserter(Container& x, Iterator i);
|
|
|
|
|
2016-07-09 00:54:47 +08:00
|
|
|
template <class Iterator>
|
|
|
|
class move_iterator {
|
|
|
|
public:
|
|
|
|
typedef Iterator iterator_type;
|
|
|
|
typedef typename iterator_traits<Iterator>::difference_type difference_type;
|
|
|
|
typedef Iterator pointer;
|
|
|
|
typedef typename iterator_traits<Iterator>::value_type value_type;
|
|
|
|
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
|
|
|
|
typedef value_type&& reference;
|
2019-05-30 00:01:36 +08:00
|
|
|
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr move_iterator(); // all the constexprs are in C++17
|
|
|
|
constexpr explicit move_iterator(Iterator i);
|
|
|
|
template <class U>
|
|
|
|
constexpr move_iterator(const move_iterator<U>& u);
|
|
|
|
template <class U>
|
|
|
|
constexpr move_iterator& operator=(const move_iterator<U>& u);
|
|
|
|
constexpr iterator_type base() const;
|
|
|
|
constexpr reference operator*() const;
|
|
|
|
constexpr pointer operator->() const;
|
|
|
|
constexpr move_iterator& operator++();
|
|
|
|
constexpr move_iterator operator++(int);
|
|
|
|
constexpr move_iterator& operator--();
|
|
|
|
constexpr move_iterator operator--(int);
|
2019-05-30 00:01:36 +08:00
|
|
|
constexpr move_iterator operator+(difference_type n) const;
|
|
|
|
constexpr move_iterator& operator+=(difference_type n);
|
|
|
|
constexpr move_iterator operator-(difference_type n) const;
|
|
|
|
constexpr move_iterator& operator-=(difference_type n);
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr unspecified operator[](difference_type n) const;
|
2016-07-09 00:54:47 +08:00
|
|
|
private:
|
|
|
|
Iterator current; // exposition only
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr bool // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
|
|
|
|
|
|
|
|
template <class Iterator1, class Iterator2>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr auto // constexpr in C++17
|
2016-07-09 00:54:47 +08:00
|
|
|
operator-(const move_iterator<Iterator1>& x,
|
|
|
|
const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
|
|
|
|
|
|
|
|
template <class Iterator>
|
2016-11-02 23:30:26 +08:00
|
|
|
constexpr move_iterator<Iterator> operator+( // constexpr in C++17
|
2019-05-30 00:01:36 +08:00
|
|
|
typename move_iterator<Iterator>::difference_type n,
|
2016-11-02 23:30:26 +08:00
|
|
|
const move_iterator<Iterator>& x);
|
2016-07-09 00:54:47 +08:00
|
|
|
|
2016-11-02 23:30:26 +08:00
|
|
|
template <class Iterator> // constexpr in C++17
|
|
|
|
constexpr move_iterator<Iterator> make_move_iterator(const Iterator& i);
|
2016-07-09 00:54:47 +08:00
|
|
|
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
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;
|
|
|
|
|
2015-04-17 05:36:54 +08:00
|
|
|
constexpr istream_iterator();
|
2010-05-12 03:42:16 +08:00
|
|
|
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;
|
|
|
|
|
2012-07-21 03:36:34 +08:00
|
|
|
istreambuf_iterator() noexcept;
|
|
|
|
istreambuf_iterator(istream_type& s) noexcept;
|
|
|
|
istreambuf_iterator(streambuf_type* s) noexcept;
|
|
|
|
istreambuf_iterator(a-private-type) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2012-07-21 03:36:34 +08:00
|
|
|
ostreambuf_iterator(ostream_type& s) noexcept;
|
|
|
|
ostreambuf_iterator(streambuf_type* s) noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
ostreambuf_iterator& operator=(charT c);
|
|
|
|
ostreambuf_iterator& operator*();
|
|
|
|
ostreambuf_iterator& operator++();
|
|
|
|
ostreambuf_iterator& operator++(int);
|
2012-07-21 03:36:34 +08:00
|
|
|
bool failed() const noexcept;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
2017-01-05 01:58:17 +08:00
|
|
|
template <class C> constexpr auto begin(C& c) -> decltype(c.begin());
|
|
|
|
template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
|
|
|
|
template <class C> constexpr auto end(C& c) -> decltype(c.end());
|
|
|
|
template <class C> constexpr auto end(const C& c) -> decltype(c.end());
|
|
|
|
template <class T, size_t N> constexpr T* begin(T (&array)[N]);
|
|
|
|
template <class T, size_t N> constexpr T* end(T (&array)[N]);
|
|
|
|
|
|
|
|
template <class C> auto constexpr cbegin(const C& c) -> decltype(std::begin(c)); // C++14
|
|
|
|
template <class C> auto constexpr cend(const C& c) -> decltype(std::end(c)); // C++14
|
|
|
|
template <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin()); // C++14
|
|
|
|
template <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin()); // C++14
|
|
|
|
template <class C> auto constexpr rend(C& c) -> decltype(c.rend()); // C++14
|
|
|
|
template <class C> constexpr auto rend(const C& c) -> decltype(c.rend()); // C++14
|
|
|
|
template <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14
|
|
|
|
template <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il); // C++14
|
|
|
|
template <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]); // C++14
|
|
|
|
template <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]); // C++14
|
|
|
|
template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14
|
|
|
|
template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c)); // C++14
|
2013-08-30 09:17:07 +08:00
|
|
|
|
2014-11-20 03:43:23 +08:00
|
|
|
// 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
|
2019-02-27 10:58:56 +08:00
|
|
|
|
|
|
|
template <class C> constexpr auto ssize(const C& c)
|
|
|
|
-> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>; // C++20
|
|
|
|
template <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
|
|
|
|
|
2014-11-20 03:43:23 +08:00
|
|
|
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
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <__config>
|
2016-02-20 08:19:45 +08:00
|
|
|
#include <iosfwd> // for forward declarations of vector and string.
|
2014-02-27 10:11:50 +08:00
|
|
|
#include <__functional_base>
|
2010-05-12 03:42:16 +08:00
|
|
|
#include <type_traits>
|
|
|
|
#include <cstddef>
|
2013-08-30 09:17:07 +08:00
|
|
|
#include <initializer_list>
|
2018-09-13 03:41:40 +08:00
|
|
|
#include <version>
|
2013-03-19 01:45:34 +08:00
|
|
|
#ifdef __APPLE__
|
2012-11-15 05:17:15 +08:00
|
|
|
#include <Availability.h>
|
|
|
|
#endif
|
|
|
|
|
2014-08-11 07:53:08 +08:00
|
|
|
#include <__debug>
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-10-18 04:05:10 +08:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2010-05-12 03:42:16 +08:00
|
|
|
#pragma GCC system_header
|
2011-10-18 04:05:10 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {};
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {};
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-11-13 13:33:31 +08:00
|
|
|
template <class _Tp>
|
|
|
|
struct __has_iterator_typedefs
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
struct __two {char __lx; char __lxx;};
|
|
|
|
template <class _Up> static __two __test(...);
|
|
|
|
template <class _Up> static char __test(typename std::__void_t<typename _Up::iterator_category>::type* = 0,
|
|
|
|
typename std::__void_t<typename _Up::difference_type>::type* = 0,
|
|
|
|
typename std::__void_t<typename _Up::value_type>::type* = 0,
|
|
|
|
typename std::__void_t<typename _Up::reference>::type* = 0,
|
|
|
|
typename std::__void_t<typename _Up::pointer>::type* = 0
|
|
|
|
);
|
|
|
|
public:
|
|
|
|
static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp>
|
|
|
|
struct __has_iterator_category
|
|
|
|
{
|
|
|
|
private:
|
2012-10-31 03:06:59 +08:00
|
|
|
struct __two {char __lx; char __lxx;};
|
2010-05-12 03:42:16 +08:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2014-01-04 06:55:49 +08:00
|
|
|
template <class _Iter, bool> struct __iterator_traits_impl {};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
2014-01-04 06:55:49 +08:00
|
|
|
struct __iterator_traits_impl<_Iter, true>
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
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>
|
2014-01-04 06:55:49 +08:00
|
|
|
: __iterator_traits_impl
|
2010-05-12 03:42:16 +08:00
|
|
|
<
|
|
|
|
_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>
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS iterator_traits
|
2018-11-13 13:33:31 +08:00
|
|
|
: __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<class _Tp>
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
typedef ptrdiff_t difference_type;
|
2017-11-14 08:03:10 +08:00
|
|
|
typedef typename remove_cv<_Tp>::type value_type;
|
2010-05-12 03:42:16 +08:00
|
|
|
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> {};
|
|
|
|
|
2016-01-14 05:54:34 +08:00
|
|
|
template <class _Tp>
|
|
|
|
struct __is_exactly_input_iterator
|
2019-05-30 00:01:36 +08:00
|
|
|
: public integral_constant<bool,
|
|
|
|
__has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
|
2016-11-02 23:30:26 +08:00
|
|
|
!__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
|
2016-01-14 05:54:34 +08:00
|
|
|
|
2019-06-21 03:32:00 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
|
|
|
template<class _InputIterator>
|
|
|
|
using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
|
|
|
|
|
|
|
|
template<class _InputIterator>
|
|
|
|
using __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
|
|
|
|
|
|
|
|
template<class _InputIterator>
|
|
|
|
using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
|
|
|
|
|
|
|
|
template<class _InputIterator>
|
|
|
|
using __iter_to_alloc_type = pair<
|
|
|
|
add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>,
|
|
|
|
typename iterator_traits<_InputIterator>::value_type::second_type>;
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template<class _Category, class _Tp, class _Distance = ptrdiff_t,
|
|
|
|
class _Pointer = _Tp*, class _Reference = _Tp&>
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
typedef _Tp value_type;
|
|
|
|
typedef _Distance difference_type;
|
|
|
|
typedef _Pointer pointer;
|
|
|
|
typedef _Reference reference;
|
|
|
|
typedef _Category iterator_category;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _InputIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
void __advance(_InputIter& __i,
|
|
|
|
typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)
|
|
|
|
{
|
|
|
|
for (; __n > 0; --__n)
|
|
|
|
++__i;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _BiDirIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
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>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
void __advance(_RandIter& __i,
|
|
|
|
typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)
|
|
|
|
{
|
|
|
|
__i += __n;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _InputIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
void advance(_InputIter& __i,
|
|
|
|
typename iterator_traits<_InputIter>::difference_type __n)
|
|
|
|
{
|
2019-03-23 06:32:20 +08:00
|
|
|
_LIBCPP_ASSERT(__n >= 0 || __is_bidirectional_iterator<_InputIter>::value,
|
|
|
|
"Attempt to advance(it, -n) on a non-bidi iterator");
|
2010-05-12 03:42:16 +08:00
|
|
|
__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _InputIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
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>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
typename iterator_traits<_RandIter>::difference_type
|
|
|
|
__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
|
|
|
|
{
|
|
|
|
return __last - __first;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _InputIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
typename iterator_traits<_InputIter>::difference_type
|
|
|
|
distance(_InputIter __first, _InputIter __last)
|
|
|
|
{
|
|
|
|
return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
|
|
|
|
}
|
|
|
|
|
2015-11-08 01:48:49 +08:00
|
|
|
template <class _InputIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2017-07-25 06:17:05 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
2019-05-30 00:01:36 +08:00
|
|
|
__is_input_iterator<_InputIter>::value,
|
2017-07-25 06:17:05 +08:00
|
|
|
_InputIter
|
|
|
|
>::type
|
2015-11-08 01:48:49 +08:00
|
|
|
next(_InputIter __x,
|
2017-07-25 06:17:05 +08:00
|
|
|
typename iterator_traits<_InputIter>::difference_type __n = 1)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2019-03-23 06:32:20 +08:00
|
|
|
_LIBCPP_ASSERT(__n >= 0 || __is_bidirectional_iterator<_InputIter>::value,
|
|
|
|
"Attempt to next(it, -n) on a non-bidi iterator");
|
|
|
|
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::advance(__x, __n);
|
2010-05-12 03:42:16 +08:00
|
|
|
return __x;
|
|
|
|
}
|
|
|
|
|
2019-03-23 06:32:20 +08:00
|
|
|
template <class _InputIter>
|
2017-05-18 02:51:36 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2017-07-25 06:17:05 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
2019-05-30 00:01:36 +08:00
|
|
|
__is_input_iterator<_InputIter>::value,
|
2019-03-23 06:32:20 +08:00
|
|
|
_InputIter
|
2017-07-25 06:17:05 +08:00
|
|
|
>::type
|
2019-03-23 06:32:20 +08:00
|
|
|
prev(_InputIter __x,
|
|
|
|
typename iterator_traits<_InputIter>::difference_type __n = 1)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2019-03-23 06:32:20 +08:00
|
|
|
_LIBCPP_ASSERT(__n <= 0 || __is_bidirectional_iterator<_InputIter>::value,
|
|
|
|
"Attempt to prev(it, +n) on a non-bidi iterator");
|
2011-07-01 05:18:19 +08:00
|
|
|
_VSTD::advance(__x, -__n);
|
2010-05-12 03:42:16 +08:00
|
|
|
return __x;
|
|
|
|
}
|
|
|
|
|
2017-04-13 10:54:13 +08:00
|
|
|
|
|
|
|
template <class _Tp, class = void>
|
|
|
|
struct __is_stashing_iterator : false_type {};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
|
|
|
|
: true_type {};
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS reverse_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: 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>
|
|
|
|
{
|
2014-03-12 06:05:31 +08:00
|
|
|
private:
|
2016-10-19 23:12:50 +08:00
|
|
|
/*mutable*/ _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
|
2017-04-13 10:54:13 +08:00
|
|
|
|
|
|
|
static_assert(!__is_stashing_iterator<_Iter>::value,
|
|
|
|
"The specified iterator type cannot be used with reverse_iterator; "
|
|
|
|
"Using stashing iterators with reverse_iterator causes undefined behavior");
|
|
|
|
|
2014-03-12 09:19:36 +08:00
|
|
|
protected:
|
|
|
|
_Iter current;
|
2010-05-12 03:42:16 +08:00
|
|
|
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;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2016-10-19 23:12:50 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator() : __t(), current() {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
|
|
|
|
template <class _Up>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {}
|
|
|
|
template <class _Up>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
|
|
|
|
{ __t = current = __u.base(); return *this; }
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
_Iter base() const {return current;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reference operator*() const {_Iter __tmp = current; return *--__tmp;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
pointer operator->() const {return _VSTD::addressof(operator*());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator& operator++() {--current; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator& operator--() {++current; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reference operator[](difference_type __n) const {return *(*this + __n);}
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() == __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() > __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() != __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() < __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() <= __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() >= __y.base();
|
|
|
|
}
|
|
|
|
|
2016-07-18 21:19:00 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-07-09 00:54:47 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2016-07-09 00:54:47 +08:00
|
|
|
auto
|
|
|
|
operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
|
|
|
|
-> decltype(__y.base() - __x.base())
|
|
|
|
{
|
|
|
|
return __y.base() - __x.base();
|
|
|
|
}
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
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();
|
|
|
|
}
|
2016-07-09 00:54:47 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
reverse_iterator<_Iter>
|
|
|
|
operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
|
|
|
|
{
|
|
|
|
return reverse_iterator<_Iter>(__x.base() - __n);
|
|
|
|
}
|
|
|
|
|
2014-03-03 09:24:04 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class _Iter>
|
2016-10-19 23:12:50 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2014-03-03 09:24:04 +08:00
|
|
|
reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
|
|
|
|
{
|
|
|
|
return reverse_iterator<_Iter>(__i);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Container>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS back_insert_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: public iterator<output_iterator_tag,
|
|
|
|
void,
|
|
|
|
void,
|
|
|
|
void,
|
2016-06-30 12:40:50 +08:00
|
|
|
void>
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
_Container* container;
|
|
|
|
public:
|
|
|
|
typedef _Container container_type;
|
|
|
|
|
2014-03-04 03:20:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
|
|
|
|
{container->push_back(__value_); return *this;}
|
2017-04-19 09:34:08 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)
|
|
|
|
{container->push_back(_VSTD::move(__value_)); return *this;}
|
2017-04-19 09:34:08 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
_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>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS front_insert_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: public iterator<output_iterator_tag,
|
|
|
|
void,
|
|
|
|
void,
|
|
|
|
void,
|
2016-06-30 12:40:50 +08:00
|
|
|
void>
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
_Container* container;
|
|
|
|
public:
|
|
|
|
typedef _Container container_type;
|
|
|
|
|
2014-03-04 03:20:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)
|
|
|
|
{container->push_front(__value_); return *this;}
|
2017-04-19 09:34:08 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)
|
|
|
|
{container->push_front(_VSTD::move(__value_)); return *this;}
|
2017-04-19 09:34:08 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
_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>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS insert_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: public iterator<output_iterator_tag,
|
|
|
|
void,
|
|
|
|
void,
|
|
|
|
void,
|
2016-06-30 12:40:50 +08:00
|
|
|
void>
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
_Container* container;
|
|
|
|
typename _Container::iterator iter;
|
|
|
|
public:
|
|
|
|
typedef _Container container_type;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
|
2014-03-04 03:20:40 +08:00
|
|
|
: container(_VSTD::addressof(__x)), iter(__i) {}
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)
|
|
|
|
{iter = container->insert(iter, __value_); ++iter; return *this;}
|
2017-04-19 09:34:08 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)
|
|
|
|
{iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
|
2017-04-19 09:34:08 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
_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>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS istream_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: 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:
|
2015-04-17 05:36:54 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {}
|
2016-05-18 01:44:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (!(*__in_stream_ >> __value_))
|
|
|
|
__in_stream_ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
|
2016-05-18 01:44:40 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
|
2010-05-12 03:42:16 +08:00
|
|
|
_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;}
|
|
|
|
|
2017-12-11 21:54:58 +08:00
|
|
|
template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
|
2010-05-12 03:42:16 +08:00
|
|
|
friend _LIBCPP_INLINE_VISIBILITY
|
2017-12-11 21:54:58 +08:00
|
|
|
bool
|
|
|
|
operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
|
|
|
|
const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-12-11 21:54:58 +08:00
|
|
|
template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
|
2010-05-12 03:42:16 +08:00
|
|
|
friend _LIBCPP_INLINE_VISIBILITY
|
2017-12-11 21:54:58 +08:00
|
|
|
bool
|
|
|
|
operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
|
|
|
|
const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
2017-12-11 21:54:58 +08:00
|
|
|
template <class _Tp, class _CharT, class _Traits, class _Distance>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool
|
|
|
|
operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
|
|
|
|
const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
|
|
|
|
{
|
|
|
|
return __x.__in_stream_ == __y.__in_stream_;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _CharT, class _Traits, class _Distance>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool
|
|
|
|
operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
|
|
|
|
const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
|
|
|
|
{
|
|
|
|
return !(__x == __y);
|
|
|
|
}
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS ostream_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: 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:
|
2016-10-13 00:13:48 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
|
2016-05-18 01:44:40 +08:00
|
|
|
: __out_stream_(_VSTD::addressof(__s)), __delim_(0) {}
|
2016-10-13 00:13:48 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
|
2016-05-18 01:44:40 +08:00
|
|
|
: __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
|
2011-10-23 04:59:45 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-10-23 04:59:45 +08:00
|
|
|
*__out_stream_ << __value_;
|
2010-05-12 03:42:16 +08:00
|
|
|
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>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: 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:
|
2012-11-17 06:17:23 +08:00
|
|
|
mutable streambuf_type* __sbuf_;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
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_;}
|
|
|
|
};
|
|
|
|
|
2010-09-23 00:48:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2012-11-17 06:17:23 +08:00
|
|
|
bool __test_for_eof() const
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
|
|
|
|
__sbuf_ = 0;
|
2012-11-17 06:17:23 +08:00
|
|
|
return __sbuf_ == 0;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
public:
|
2012-11-17 06:17:23 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}
|
2012-07-21 03:36:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
|
2012-12-30 01:45:42 +08:00
|
|
|
: __sbuf_(__s.rdbuf()) {}
|
2012-07-21 03:36:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
|
2012-12-30 01:45:42 +08:00
|
|
|
: __sbuf_(__s) {}
|
2012-07-21 03:36:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
: __sbuf_(__p.__sbuf_) {}
|
|
|
|
|
2011-12-02 04:21:04 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY char_type operator*() const
|
|
|
|
{return static_cast<char_type>(__sbuf_->sgetc());}
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
|
|
|
|
{
|
2012-11-17 06:17:23 +08:00
|
|
|
__sbuf_->sbumpc();
|
2010-05-12 03:42:16 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY __proxy operator++(int)
|
|
|
|
{
|
2012-11-17 06:17:23 +08:00
|
|
|
return __proxy(__sbuf_->sbumpc(), __sbuf_);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
|
2012-11-17 06:17:23 +08:00
|
|
|
{return __test_for_eof() == __b.__test_for_eof();}
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
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>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
: 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:
|
2012-07-21 03:36:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
: __sbuf_(__s.rdbuf()) {}
|
2012-07-21 03:36:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
: __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;}
|
2012-07-21 03:36:34 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;}
|
2012-09-20 03:14:15 +08:00
|
|
|
|
|
|
|
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);
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Iter>
|
2017-01-05 07:56:00 +08:00
|
|
|
class _LIBCPP_TEMPLATE_VIS move_iterator
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
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;
|
2016-04-11 11:54:53 +08:00
|
|
|
typedef iterator_type pointer;
|
2017-04-19 09:34:08 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-04-22 08:49:12 +08:00
|
|
|
typedef typename iterator_traits<iterator_type>::reference __reference;
|
|
|
|
typedef typename conditional<
|
|
|
|
is_reference<__reference>::value,
|
|
|
|
typename remove_reference<__reference>::type&&,
|
|
|
|
__reference
|
|
|
|
>::type reference;
|
2010-05-12 03:42:16 +08:00
|
|
|
#else
|
|
|
|
typedef typename iterator_traits<iterator_type>::reference reference;
|
|
|
|
#endif
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2016-11-02 23:30:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator() : __i() {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
explicit move_iterator(_Iter __x) : __i(__x) {}
|
|
|
|
template <class _Up>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
|
2019-05-30 00:01:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2016-11-02 23:30:26 +08:00
|
|
|
reference operator*() const { return static_cast<reference>(*__i); }
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
pointer operator->() const { return __i;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator& operator++() {++__i; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator& operator--() {--__i; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator& operator+=(difference_type __n) {__i += __n; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
|
|
|
reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); }
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() == __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() < __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() != __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() > __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() >= __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
{
|
|
|
|
return __x.base() <= __y.base();
|
|
|
|
}
|
|
|
|
|
2016-07-18 21:19:00 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-07-09 00:54:47 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2016-07-09 00:54:47 +08:00
|
|
|
auto
|
|
|
|
operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
|
|
|
|
-> decltype(__x.base() - __y.base())
|
|
|
|
{
|
|
|
|
return __x.base() - __y.base();
|
|
|
|
}
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
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();
|
|
|
|
}
|
2016-07-09 00:54:47 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
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>
|
2016-11-02 23:30:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
move_iterator<_Iter>
|
2013-08-27 21:03:03 +08:00
|
|
|
make_move_iterator(_Iter __i)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return move_iterator<_Iter>(__i);
|
|
|
|
}
|
|
|
|
|
|
|
|
// __wrap_iter
|
|
|
|
|
|
|
|
template <class _Iter> class __wrap_iter;
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-07-18 21:19:00 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-07-09 00:54:47 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2016-07-09 00:54:47 +08:00
|
|
|
auto
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2016-07-09 00:54:47 +08:00
|
|
|
-> decltype(__x.base() - __y.base());
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2012-09-14 08:39:16 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2010-05-12 03:42:16 +08:00
|
|
|
typename __wrap_iter<_Iter1>::difference_type
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2016-07-09 00:54:47 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
__wrap_iter<_Iter>
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2012-09-14 08:39:16 +08:00
|
|
|
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);
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-12-28 13:35:32 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL < 2
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
2010-11-20 06:17:28 +08:00
|
|
|
is_trivially_copy_assignable<_Tp>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
_Tp*
|
|
|
|
>::type
|
|
|
|
__unwrap_iter(__wrap_iter<_Tp*>);
|
|
|
|
|
2016-12-28 13:35:32 +08:00
|
|
|
#else
|
|
|
|
|
|
|
|
template <class _Tp>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2016-12-28 13:35:32 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
is_trivially_copy_assignable<_Tp>::value,
|
|
|
|
__wrap_iter<_Tp*>
|
|
|
|
>::type
|
|
|
|
__unwrap_iter(__wrap_iter<_Tp*> __i);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
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:
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
|
2013-08-08 04:48:48 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
: __i{}
|
|
|
|
#endif
|
2011-09-17 03:52:23 +08:00
|
|
|
{
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
__get_db()->__insert_i(this);
|
|
|
|
#endif
|
|
|
|
}
|
2018-07-14 00:35:26 +08:00
|
|
|
template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
|
|
|
__wrap_iter(const __wrap_iter<_Up>& __u,
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT
|
2018-07-14 00:35:26 +08:00
|
|
|
: __i(__u.base())
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
__get_db()->__iterator_copy(this, &__u);
|
|
|
|
#endif
|
|
|
|
}
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2011-09-15 02:33:51 +08:00
|
|
|
__wrap_iter(const __wrap_iter& __x)
|
|
|
|
: __i(__x.base())
|
|
|
|
{
|
|
|
|
__get_db()->__iterator_copy(this, &__x);
|
|
|
|
}
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2011-09-15 02:33:51 +08:00
|
|
|
__wrap_iter& operator=(const __wrap_iter& __x)
|
|
|
|
{
|
|
|
|
if (this != &__x)
|
|
|
|
{
|
|
|
|
__get_db()->__iterator_copy(this, &__x);
|
|
|
|
__i = __x.__i;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2011-09-15 02:33:51 +08:00
|
|
|
~__wrap_iter()
|
|
|
|
{
|
|
|
|
__get_db()->__erase_i(this);
|
|
|
|
}
|
|
|
|
#endif
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
|
|
|
"Attempted to dereference a non-dereferenceable iterator");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
return *__i;
|
|
|
|
}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT
|
2013-06-28 03:35:32 +08:00
|
|
|
{
|
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
|
|
|
"Attempted to dereference a non-dereferenceable iterator");
|
|
|
|
#endif
|
2016-04-11 11:54:53 +08:00
|
|
|
return (pointer)_VSTD::addressof(*__i);
|
2013-06-28 03:35:32 +08:00
|
|
|
}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
|
|
|
"Attempted to increment non-incrementable iterator");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
++__i;
|
|
|
|
return *this;
|
|
|
|
}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{__wrap_iter __tmp(*this); ++(*this); return __tmp;}
|
2018-07-14 11:06:11 +08:00
|
|
|
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
|
|
|
|
"Attempted to decrement non-decrementable iterator");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
--__i;
|
|
|
|
return *this;
|
|
|
|
}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{__wrap_iter __tmp(*this); --(*this); return __tmp;}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{__wrap_iter __w(*this); __w += __n; return __w;}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
|
|
|
|
"Attempted to add/subtract iterator outside of valid range");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
__i += __n;
|
|
|
|
return *this;
|
|
|
|
}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{return *this + (-__n);}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{*this += -__n; return *this;}
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2011-09-15 02:33:51 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
|
|
|
|
"Attempted to subscript iterator outside of valid range");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2011-09-15 02:33:51 +08:00
|
|
|
return __i[__n];
|
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
private:
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
|
2011-09-15 02:33:51 +08:00
|
|
|
{
|
|
|
|
__get_db()->__insert_ic(this, __p);
|
|
|
|
}
|
2013-08-24 01:37:05 +08:00
|
|
|
#else
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
|
2011-09-15 02:33:51 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Up> friend class __wrap_iter;
|
|
|
|
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
|
2017-01-05 07:56:00 +08:00
|
|
|
template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
|
2019-02-27 08:32:16 +08:00
|
|
|
template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2016-07-18 21:19:00 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-07-09 00:54:47 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2016-07-09 00:54:47 +08:00
|
|
|
auto
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2016-07-09 00:54:47 +08:00
|
|
|
-> decltype(__x.base() - __y.base());
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
typename __wrap_iter<_Iter1>::difference_type
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
|
2016-07-09 00:54:47 +08:00
|
|
|
#endif
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
__wrap_iter<_Iter1>
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2);
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);
|
|
|
|
|
2016-12-28 13:35:32 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL < 2
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp>
|
2018-07-14 00:35:26 +08:00
|
|
|
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
|
2010-05-12 03:42:16 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
2010-11-20 06:17:28 +08:00
|
|
|
is_trivially_copy_assignable<_Tp>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
_Tp*
|
|
|
|
>::type
|
|
|
|
__unwrap_iter(__wrap_iter<_Tp*>);
|
2016-12-28 13:35:32 +08:00
|
|
|
#else
|
|
|
|
template <class _Tp>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2016-12-28 13:35:32 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
is_trivially_copy_assignable<_Tp>::value,
|
|
|
|
__wrap_iter<_Tp*>
|
|
|
|
>::type
|
|
|
|
__unwrap_iter(__wrap_iter<_Tp*> __i);
|
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __x.base() == __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
Ok, 3 major changes for debug mode in one commit:
1. I had been detecting and trapping iterator == and \!= among iterators
in different containers as an error. But the trapping itself is actually
an error.
Consider:
#include <iostream>
#include <vector>
#include <algorithm>
template <class C>
void
display(const C& c)
{
std::cout << "{";
bool first = true;
for (const auto& x : c)
{
if (\!first)
std::cout << ", ";
first = false;
std::cout << x;
}
std::cout << "}\n";
}
int
main()
{
typedef std::vector<int> V;
V v1 = {1, 3, 5};
V v2 = {2, 4, 6};
display(v1);
display(v2);
V::iterator i = std::find(v1.begin(), v1.end(), 1);
V::iterator j = std::find(v2.begin(), v2.end(), 2);
if (*i == *j)
i = j; // perfectly legal
// ...
if (i \!= j) // the only way to check
v2.push_back(*i);
display(v1);
display(v2);
}
It is legal to assign an iterator from one container to another of the
same type. This is required to work. One might want to test whether or
not such an assignment had been made. The way one performs such a check
is using the iterator's ==, \!= operator. This is a logical and necessary
function and does not constitute an error.
2. I had a header circular dependence bug when _LIBCPP_DEBUG2 is defined.
This caused a problem in several of the libc++ tests.
Fixed.
3. There is a serious problem when _LIBCPP_DEBUG2=1 at the moment in that
std::basic_string is inoperable. std::basic_string uses __wrap_iterator
to implement its iterators. __wrap_iterator has been rigged up in debug
mode to support vector. But string hasn't been rigged up yet. This means
that one gets false positives when using std::string in debug mode. I've
upped std::string's priority in www/debug_mode.html.
llvm-svn: 187636
2013-08-02 08:26:35 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
|
2011-09-15 02:33:51 +08:00
|
|
|
"Attempted to compare incomparable iterators");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
return __x.base() < __y.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
return !(__x == __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
return __y < __x;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
return !(__x < __y);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
return !(__y < __x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2012-10-03 03:45:42 +08:00
|
|
|
template <class _Iter1>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2012-10-03 03:45:42 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
2012-10-03 03:45:42 +08:00
|
|
|
{
|
|
|
|
return !(__x == __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2012-10-03 03:45:42 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
2012-10-03 03:45:42 +08:00
|
|
|
{
|
|
|
|
return __y < __x;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2012-10-03 03:45:42 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
2012-10-03 03:45:42 +08:00
|
|
|
{
|
|
|
|
return !(__x < __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Iter1>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2012-10-03 03:45:42 +08:00
|
|
|
bool
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
|
2012-10-03 03:45:42 +08:00
|
|
|
{
|
|
|
|
return !(__y < __x);
|
|
|
|
}
|
|
|
|
|
2016-07-18 21:19:00 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2016-07-09 00:54:47 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2016-07-09 00:54:47 +08:00
|
|
|
auto
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2016-07-09 00:54:47 +08:00
|
|
|
-> decltype(__x.base() - __y.base())
|
|
|
|
{
|
|
|
|
#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();
|
|
|
|
}
|
|
|
|
#else
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Iter1, class _Iter2>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
typename __wrap_iter<_Iter1>::difference_type
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-17 01:29:17 +08:00
|
|
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
Ok, 3 major changes for debug mode in one commit:
1. I had been detecting and trapping iterator == and \!= among iterators
in different containers as an error. But the trapping itself is actually
an error.
Consider:
#include <iostream>
#include <vector>
#include <algorithm>
template <class C>
void
display(const C& c)
{
std::cout << "{";
bool first = true;
for (const auto& x : c)
{
if (\!first)
std::cout << ", ";
first = false;
std::cout << x;
}
std::cout << "}\n";
}
int
main()
{
typedef std::vector<int> V;
V v1 = {1, 3, 5};
V v2 = {2, 4, 6};
display(v1);
display(v2);
V::iterator i = std::find(v1.begin(), v1.end(), 1);
V::iterator j = std::find(v2.begin(), v2.end(), 2);
if (*i == *j)
i = j; // perfectly legal
// ...
if (i \!= j) // the only way to check
v2.push_back(*i);
display(v1);
display(v2);
}
It is legal to assign an iterator from one container to another of the
same type. This is required to work. One might want to test whether or
not such an assignment had been made. The way one performs such a check
is using the iterator's ==, \!= operator. This is a logical and necessary
function and does not constitute an error.
2. I had a header circular dependence bug when _LIBCPP_DEBUG2 is defined.
This caused a problem in several of the libc++ tests.
Fixed.
3. There is a serious problem when _LIBCPP_DEBUG2=1 at the moment in that
std::basic_string is inoperable. std::basic_string uses __wrap_iterator
to implement its iterators. __wrap_iterator has been rigged up in debug
mode to support vector. But string hasn't been rigged up yet. This means
that one gets false positives when using std::string in debug mode. I've
upped std::string's priority in www/debug_mode.html.
llvm-svn: 187636
2013-08-02 08:26:35 +08:00
|
|
|
_LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
|
2011-09-15 02:33:51 +08:00
|
|
|
"Attempted to subtract incompatible iterators");
|
2011-09-17 01:29:17 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
return __x.base() - __y.base();
|
|
|
|
}
|
2016-07-09 00:54:47 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
2018-07-14 00:35:26 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
|
2010-05-12 03:42:16 +08:00
|
|
|
__wrap_iter<_Iter>
|
|
|
|
operator+(typename __wrap_iter<_Iter>::difference_type __n,
|
Remove exception throwing debug mode handler support.
Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!
However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.
Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.
This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
death tests.
Reviewers: mclow.lists, ldionne, thomasanderson
Reviewed By: ldionne
Subscribers: christof, arphaman, libcxx-commits, #libc
Differential Revision: https://reviews.llvm.org/D59166
llvm-svn: 356417
2019-03-19 05:50:12 +08:00
|
|
|
__wrap_iter<_Iter> __x) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-09-15 02:33:51 +08:00
|
|
|
__x += __n;
|
|
|
|
return __x;
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2016-01-14 05:54:34 +08:00
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_is_trivial_iterator
|
2016-11-02 23:30:26 +08:00
|
|
|
: public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {};
|
2019-05-30 00:01:36 +08:00
|
|
|
|
2016-01-14 05:54:34 +08:00
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
|
2016-11-02 23:30:26 +08:00
|
|
|
: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
|
2016-01-14 05:54:34 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_is_trivial_iterator<reverse_iterator<_Iter> >
|
2016-11-02 23:30:26 +08:00
|
|
|
: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
|
2016-01-14 05:54:34 +08:00
|
|
|
|
|
|
|
template <class _Iter>
|
|
|
|
struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
|
2016-11-02 23:30:26 +08:00
|
|
|
: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
|
2016-01-14 05:54:34 +08:00
|
|
|
|
|
|
|
|
2013-12-02 11:24:33 +08:00
|
|
|
template <class _Tp, size_t _Np>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2013-12-02 11:24:33 +08:00
|
|
|
_Tp*
|
|
|
|
begin(_Tp (&__array)[_Np])
|
|
|
|
{
|
|
|
|
return __array;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, size_t _Np>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2013-12-02 11:24:33 +08:00
|
|
|
_Tp*
|
|
|
|
end(_Tp (&__array)[_Np])
|
|
|
|
{
|
|
|
|
return __array + _Np;
|
|
|
|
}
|
|
|
|
|
2016-09-25 11:34:28 +08:00
|
|
|
#if !defined(_LIBCPP_CXX03_LANG)
|
2013-12-12 03:32:32 +08:00
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
auto
|
2011-11-30 02:15:50 +08:00
|
|
|
begin(_Cp& __c) -> decltype(__c.begin())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.begin();
|
|
|
|
}
|
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
auto
|
2011-11-30 02:15:50 +08:00
|
|
|
begin(const _Cp& __c) -> decltype(__c.begin())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.begin();
|
|
|
|
}
|
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
auto
|
2011-11-30 02:15:50 +08:00
|
|
|
end(_Cp& __c) -> decltype(__c.end())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.end();
|
|
|
|
}
|
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2010-05-12 03:42:16 +08:00
|
|
|
auto
|
2011-11-30 02:15:50 +08:00
|
|
|
end(const _Cp& __c) -> decltype(__c.end())
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.end();
|
|
|
|
}
|
|
|
|
|
2013-08-30 09:17:07 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
|
2013-12-02 11:24:33 +08:00
|
|
|
template <class _Tp, size_t _Np>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-12-02 11:24:33 +08:00
|
|
|
reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
|
|
|
|
{
|
|
|
|
return reverse_iterator<_Tp*>(__array + _Np);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, size_t _Np>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-12-02 11:24:33 +08:00
|
|
|
reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
|
|
|
|
{
|
|
|
|
return reverse_iterator<_Tp*>(__array);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Ep>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-12-02 11:24:33 +08:00
|
|
|
reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
|
|
|
|
{
|
|
|
|
return reverse_iterator<const _Ep*>(__il.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Ep>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-12-02 11:24:33 +08:00
|
|
|
reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
|
|
|
|
{
|
|
|
|
return reverse_iterator<const _Ep*>(__il.begin());
|
|
|
|
}
|
|
|
|
|
2013-08-30 09:17:07 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2016-08-11 04:04:46 +08:00
|
|
|
auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
|
2013-08-30 09:17:07 +08:00
|
|
|
{
|
2016-08-11 04:04:46 +08:00
|
|
|
return _VSTD::begin(__c);
|
2013-08-30 09:17:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2016-08-11 04:04:46 +08:00
|
|
|
auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
|
2013-08-30 09:17:07 +08:00
|
|
|
{
|
2016-08-11 04:04:46 +08:00
|
|
|
return _VSTD::end(__c);
|
2013-08-30 09:17:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-08-30 09:17:07 +08:00
|
|
|
auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
|
|
|
|
{
|
|
|
|
return __c.rbegin();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-08-30 09:17:07 +08:00
|
|
|
auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
|
|
|
|
{
|
|
|
|
return __c.rbegin();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-08-30 09:17:07 +08:00
|
|
|
auto rend(_Cp& __c) -> decltype(__c.rend())
|
|
|
|
{
|
|
|
|
return __c.rend();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2013-08-30 09:17:07 +08:00
|
|
|
auto rend(const _Cp& __c) -> decltype(__c.rend())
|
|
|
|
{
|
|
|
|
return __c.rend();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2016-08-11 04:04:46 +08:00
|
|
|
auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
|
2013-08-30 09:17:07 +08:00
|
|
|
{
|
2016-08-11 04:04:46 +08:00
|
|
|
return _VSTD::rbegin(__c);
|
2013-08-30 09:17:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
2016-08-11 04:04:46 +08:00
|
|
|
auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
|
2013-08-30 09:17:07 +08:00
|
|
|
{
|
2016-08-11 04:04:46 +08:00
|
|
|
return _VSTD::rend(__c);
|
2013-08-30 09:17:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2016-09-25 11:34:28 +08:00
|
|
|
#else // defined(_LIBCPP_CXX03_LANG)
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-11-30 02:15:50 +08:00
|
|
|
typename _Cp::iterator
|
|
|
|
begin(_Cp& __c)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.begin();
|
|
|
|
}
|
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-11-30 02:15:50 +08:00
|
|
|
typename _Cp::const_iterator
|
|
|
|
begin(const _Cp& __c)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.begin();
|
|
|
|
}
|
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-11-30 02:15:50 +08:00
|
|
|
typename _Cp::iterator
|
|
|
|
end(_Cp& __c)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.end();
|
|
|
|
}
|
|
|
|
|
2011-11-30 02:15:50 +08:00
|
|
|
template <class _Cp>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2011-11-30 02:15:50 +08:00
|
|
|
typename _Cp::const_iterator
|
|
|
|
end(const _Cp& __c)
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __c.end();
|
|
|
|
}
|
|
|
|
|
2016-09-25 11:34:28 +08:00
|
|
|
#endif // !defined(_LIBCPP_CXX03_LANG)
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2014-11-20 03:43:23 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
2017-11-17 01:55:41 +08:00
|
|
|
|
|
|
|
// #if _LIBCPP_STD_VER > 11
|
|
|
|
// template <>
|
|
|
|
// struct _LIBCPP_TEMPLATE_VIS plus<void>
|
|
|
|
// {
|
|
|
|
// template <class _T1, class _T2>
|
|
|
|
// _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
// auto operator()(_T1&& __t, _T2&& __u) const
|
|
|
|
// _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
|
|
|
|
// -> decltype (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
|
|
|
|
// { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
|
|
|
|
// typedef void is_transparent;
|
|
|
|
// };
|
|
|
|
// #endif
|
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Cont>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-11-17 01:55:41 +08:00
|
|
|
constexpr auto size(const _Cont& __c)
|
|
|
|
_NOEXCEPT_(noexcept(__c.size()))
|
|
|
|
-> decltype (__c.size())
|
|
|
|
{ return __c.size(); }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Tp, size_t _Sz>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2016-12-24 07:37:52 +08:00
|
|
|
constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
2019-02-27 10:58:56 +08:00
|
|
|
#if _LIBCPP_STD_VER > 17
|
|
|
|
template <class _Cont>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-02-27 10:58:56 +08:00
|
|
|
constexpr auto ssize(const _Cont& __c)
|
|
|
|
_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
|
|
|
|
-> common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
|
|
|
|
{ return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
|
|
|
|
|
|
|
|
template <class _Tp, ptrdiff_t _Sz>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-02-27 10:58:56 +08:00
|
|
|
constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
|
|
|
|
#endif
|
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Cont>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
2017-11-17 01:55:41 +08:00
|
|
|
constexpr auto empty(const _Cont& __c)
|
|
|
|
_NOEXCEPT_(noexcept(__c.empty()))
|
|
|
|
-> decltype (__c.empty())
|
|
|
|
{ return __c.empty(); }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Tp, size_t _Sz>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
2016-12-24 07:37:52 +08:00
|
|
|
constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
|
|
|
template <class _Ep>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
2014-11-20 03:43:23 +08:00
|
|
|
constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
|
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Cont> constexpr
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-11-17 01:55:41 +08:00
|
|
|
auto data(_Cont& __c)
|
|
|
|
_NOEXCEPT_(noexcept(__c.data()))
|
|
|
|
-> decltype (__c.data())
|
|
|
|
{ return __c.data(); }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Cont> constexpr
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-11-17 01:55:41 +08:00
|
|
|
auto data(const _Cont& __c)
|
|
|
|
_NOEXCEPT_(noexcept(__c.data()))
|
2019-05-30 00:01:36 +08:00
|
|
|
-> decltype (__c.data())
|
2017-11-17 01:55:41 +08:00
|
|
|
{ return __c.data(); }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
2015-02-12 00:14:01 +08:00
|
|
|
template <class _Tp, size_t _Sz>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2015-02-12 00:14:01 +08:00
|
|
|
constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
|
2014-11-20 03:43:23 +08:00
|
|
|
|
|
|
|
template <class _Ep>
|
2019-02-27 11:25:43 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2014-11-20 03:43:23 +08:00
|
|
|
constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
|
|
|
#endif // _LIBCPP_ITERATOR
|