Author: marshall Date: Fri Jul 8 11:54:47 2016 New Revision: 274880 URL: http://llvm.org/viewvc/llvm-project?rev=274880&view=rev Log: 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.
Modified: libcxx/trunk/include/iterator Modified: libcxx/trunk/include/iterator URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/iterator?rev=274880&r1=274879&r2=274880&view=diff ============================================================================== --- libcxx/trunk/include/iterator (original) +++ libcxx/trunk/include/iterator Fri Jul 8 11:54:47 2016 @@ -131,8 +131,9 @@ bool operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -typename reverse_iterator<Iterator1>::difference_type -operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); +auto +operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) +-> decltype(__y.base() - __x.base()); template <class Iterator> reverse_iterator<Iterator> @@ -205,6 +206,73 @@ public: template <class Container, class Iterator> insert_iterator<Container> inserter(Container& x, Iterator i); +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; + + move_iterator(); + explicit move_iterator(Iterator i); + template <class U> move_iterator(const move_iterator<U>& u); + template <class U> move_iterator& operator=(const move_iterator<U>& 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 <class Iterator1, class Iterator2> +bool +operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +auto +operator-(const move_iterator<Iterator1>& x, + const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base()); + +template <class Iterator> +move_iterator<Iterator> operator+(typename move_iterator<Iterator>::difference_type n, + const move_iterator<Iterator>& x); + +template <class Iterator> +move_iterator<Iterator> make_move_iterator(const Iterator& i); + + template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> class istream_iterator : public iterator<input_iterator_tag, T, Distance, const T*, const T&> @@ -632,6 +700,16 @@ operator<=(const reverse_iterator<_Iter1 return __x.base() >= __y.base(); } +#if __cplusplus >= 201103L +template <class _Iter1, class _Iter2> +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 <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename reverse_iterator<_Iter1>::difference_type @@ -639,6 +717,7 @@ operator-(const reverse_iterator<_Iter1> { return __y.base() - __x.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY @@ -1038,6 +1117,16 @@ operator<=(const move_iterator<_Iter1>& return __x.base() <= __y.base(); } +#if __cplusplus >= 201103L +template <class _Iter1, class _Iter2> +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 <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename move_iterator<_Iter1>::difference_type @@ -1045,6 +1134,7 @@ operator-(const move_iterator<_Iter1>& _ { return __x.base() - __y.base(); } +#endif template <class _Iter> 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 <class _Iter1, class _Iter2> +_LIBCPP_INLINE_VISIBILITY +auto +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +-> decltype(__x.base() - __y.base()); +#else template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#endif template <class _Iter> _LIBCPP_INLINE_VISIBILITY @@ -1281,10 +1379,18 @@ private: bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#if __cplusplus >= 201103L + template <class _Iter1, class _Iter2> + friend + auto + operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT + -> decltype(__x.base() - __y.base()); +#else template <class _Iter1, class _Iter2> friend typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#endif template <class _Iter1> friend @@ -1390,6 +1496,20 @@ operator<=(const __wrap_iter<_Iter1>& __ return !(__y < __x); } +#if __cplusplus >= 201103L +template <class _Iter1, class _Iter2> +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 <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type @@ -1401,6 +1521,7 @@ operator-(const __wrap_iter<_Iter1>& __x #endif return __x.base() - __y.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits