From df4a22dec7d05ea8e5dc4d9f389be311cd92c49d Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 8 Jul 2016 16:54:47 +0000 Subject: [PATCH] Implement LWG685 (which is from C++11!). Fixes PR#28421. Note: this (subtly) changes the return type of operator-(Iter1, Iter2) where Iter1 is a reverse iterator or a move_iterator, and Iter2 is some other move/reverse iterator type. In practice, I believe that almost every time the second param will be const_XXX and this will mean that the return type will be the same as it was before. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@274880 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/iterator | 125 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/include/iterator b/include/iterator index c83320053..2e30a9229 100644 --- a/include/iterator +++ b/include/iterator @@ -131,8 +131,9 @@ bool operator<=(const reverse_iterator& x, const reverse_iterator& y); template -typename reverse_iterator::difference_type -operator-(const reverse_iterator& x, const reverse_iterator& y); +auto +operator-(const reverse_iterator& x, const reverse_iterator& y) +-> decltype(__y.base() - __x.base()); template reverse_iterator @@ -205,6 +206,73 @@ public: template insert_iterator inserter(Container& x, Iterator i); +template +class move_iterator { +public: + typedef Iterator iterator_type; + typedef typename iterator_traits::difference_type difference_type; + typedef Iterator pointer; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::iterator_category iterator_category; + typedef value_type&& reference; + + move_iterator(); + explicit move_iterator(Iterator i); + template move_iterator(const move_iterator& u); + template move_iterator& operator=(const move_iterator& u); + iterator_type base() const; + reference operator*() const; + pointer operator->() const; + move_iterator& operator++(); + move_iterator operator++(int); + move_iterator& operator--(); + move_iterator operator--(int); + move_iterator operator+(difference_type n) const; + move_iterator& operator+=(difference_type n); + move_iterator operator-(difference_type n) const; + move_iterator& operator-=(difference_type n); + unspecified operator[](difference_type n) const; +private: + Iterator current; // exposition only +}; + +template +bool +operator==(const move_iterator& x, const move_iterator& y); + +template +bool +operator!=(const move_iterator& x, const move_iterator& y); + +template +bool +operator<(const move_iterator& x, const move_iterator& y); + +template +bool +operator<=(const move_iterator& x, const move_iterator& y); + +template +bool +operator>(const move_iterator& x, const move_iterator& y); + +template +bool +operator>=(const move_iterator& x, const move_iterator& y); + +template +auto +operator-(const move_iterator& x, + const move_iterator& y) -> decltype(x.base() - y.base()); + +template +move_iterator operator+(typename move_iterator::difference_type n, + const move_iterator& x); + +template +move_iterator make_move_iterator(const Iterator& i); + + template , class Distance = ptrdiff_t> class istream_iterator : public iterator @@ -632,6 +700,16 @@ operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& return __x.base() >= __y.base(); } +#if __cplusplus >= 201103L +template +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +-> decltype(__y.base() - __x.base()) +{ + return __y.base() - __x.base(); +} +#else template inline _LIBCPP_INLINE_VISIBILITY typename reverse_iterator<_Iter1>::difference_type @@ -639,6 +717,7 @@ operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ { return __y.base() - __x.base(); } +#endif template inline _LIBCPP_INLINE_VISIBILITY @@ -1038,6 +1117,16 @@ operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) return __x.base() <= __y.base(); } +#if __cplusplus >= 201103L +template +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +-> decltype(__x.base() - __y.base()) +{ + return __x.base() - __y.base(); +} +#else template inline _LIBCPP_INLINE_VISIBILITY typename move_iterator<_Iter1>::difference_type @@ -1045,6 +1134,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() - __y.base(); } +#endif template inline _LIBCPP_INLINE_VISIBILITY @@ -1096,10 +1186,18 @@ _LIBCPP_INLINE_VISIBILITY bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#if __cplusplus >= 201103L +template +_LIBCPP_INLINE_VISIBILITY +auto +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +-> decltype(__x.base() - __y.base()); +#else template _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#endif template _LIBCPP_INLINE_VISIBILITY @@ -1281,10 +1379,18 @@ private: bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#if __cplusplus >= 201103L + template + friend + auto + operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT + -> decltype(__x.base() - __y.base()); +#else template friend typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#endif template friend @@ -1390,6 +1496,20 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX return !(__y < __x); } +#if __cplusplus >= 201103L +template +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +-> 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 template inline _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type @@ -1401,6 +1521,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC #endif return __x.base() - __y.base(); } +#endif template inline _LIBCPP_INLINE_VISIBILITY