204 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03___ITERATOR_REVERSE_ITERATOR_H11#define _LIBCPP___CXX03___ITERATOR_REVERSE_ITERATOR_H12 13#include <__cxx03/__algorithm/unwrap_iter.h>14#include <__cxx03/__config>15#include <__cxx03/__iterator/advance.h>16#include <__cxx03/__iterator/iterator.h>17#include <__cxx03/__iterator/iterator_traits.h>18#include <__cxx03/__iterator/next.h>19#include <__cxx03/__iterator/prev.h>20#include <__cxx03/__iterator/segmented_iterator.h>21#include <__cxx03/__memory/addressof.h>22#include <__cxx03/__type_traits/conditional.h>23#include <__cxx03/__type_traits/enable_if.h>24#include <__cxx03/__type_traits/is_assignable.h>25#include <__cxx03/__type_traits/is_convertible.h>26#include <__cxx03/__type_traits/is_nothrow_constructible.h>27#include <__cxx03/__type_traits/is_pointer.h>28#include <__cxx03/__type_traits/is_same.h>29#include <__cxx03/__utility/declval.h>30#include <__cxx03/__utility/move.h>31 32#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)33# pragma GCC system_header34#endif35 36_LIBCPP_BEGIN_NAMESPACE_STD37 38_LIBCPP_SUPPRESS_DEPRECATED_PUSH39template <class _Iter>40class _LIBCPP_TEMPLATE_VIS reverse_iterator41 : public iterator<typename iterator_traits<_Iter>::iterator_category,42 typename iterator_traits<_Iter>::value_type,43 typename iterator_traits<_Iter>::difference_type,44 typename iterator_traits<_Iter>::pointer,45 typename iterator_traits<_Iter>::reference> {46 _LIBCPP_SUPPRESS_DEPRECATED_POP47 48private:49#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES50 _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break51#endif52 53protected:54 _Iter current;55 56public:57 using iterator_type = _Iter;58 59 using iterator_category =60 _If<__has_random_access_iterator_category<_Iter>::value,61 random_access_iterator_tag,62 typename iterator_traits<_Iter>::iterator_category>;63 using pointer = typename iterator_traits<_Iter>::pointer;64 using value_type = typename iterator_traits<_Iter>::value_type;65 using difference_type = typename iterator_traits<_Iter>::difference_type;66 using reference = typename iterator_traits<_Iter>::reference;67 68#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES69 _LIBCPP_HIDE_FROM_ABI reverse_iterator() : __t_(), current() {}70 71 _LIBCPP_HIDE_FROM_ABI explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {}72 73 template <class _Up, __enable_if_t<!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value, int> = 0>74 _LIBCPP_HIDE_FROM_ABI reverse_iterator(const reverse_iterator<_Up>& __u) : __t_(__u.base()), current(__u.base()) {}75 76 template <class _Up,77 __enable_if_t<!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value &&78 is_assignable<_Iter&, _Up const&>::value,79 int> = 0>80 _LIBCPP_HIDE_FROM_ABI reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {81 __t_ = current = __u.base();82 return *this;83 }84#else85 _LIBCPP_HIDE_FROM_ABI reverse_iterator() : current() {}86 87 _LIBCPP_HIDE_FROM_ABI explicit reverse_iterator(_Iter __x) : current(__x) {}88 89 template <class _Up, __enable_if_t<!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value, int> = 0>90 _LIBCPP_HIDE_FROM_ABI reverse_iterator(const reverse_iterator<_Up>& __u) : current(__u.base()) {}91 92 template <class _Up,93 __enable_if_t<!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value &&94 is_assignable<_Iter&, _Up const&>::value,95 int> = 0>96 _LIBCPP_HIDE_FROM_ABI reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {97 current = __u.base();98 return *this;99 }100#endif101 _LIBCPP_HIDE_FROM_ABI _Iter base() const { return current; }102 _LIBCPP_HIDE_FROM_ABI reference operator*() const {103 _Iter __tmp = current;104 return *--__tmp;105 }106 107 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return std::addressof(operator*()); }108 109 _LIBCPP_HIDE_FROM_ABI reverse_iterator& operator++() {110 --current;111 return *this;112 }113 _LIBCPP_HIDE_FROM_ABI reverse_iterator operator++(int) {114 reverse_iterator __tmp(*this);115 --current;116 return __tmp;117 }118 _LIBCPP_HIDE_FROM_ABI reverse_iterator& operator--() {119 ++current;120 return *this;121 }122 _LIBCPP_HIDE_FROM_ABI reverse_iterator operator--(int) {123 reverse_iterator __tmp(*this);124 ++current;125 return __tmp;126 }127 _LIBCPP_HIDE_FROM_ABI reverse_iterator operator+(difference_type __n) const {128 return reverse_iterator(current - __n);129 }130 _LIBCPP_HIDE_FROM_ABI reverse_iterator& operator+=(difference_type __n) {131 current -= __n;132 return *this;133 }134 _LIBCPP_HIDE_FROM_ABI reverse_iterator operator-(difference_type __n) const {135 return reverse_iterator(current + __n);136 }137 _LIBCPP_HIDE_FROM_ABI reverse_iterator& operator-=(difference_type __n) {138 current += __n;139 return *this;140 }141 _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); }142};143 144template <class _Iter1, class _Iter2>145inline _LIBCPP_HIDE_FROM_ABI bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {146 return __x.base() == __y.base();147}148 149template <class _Iter1, class _Iter2>150inline _LIBCPP_HIDE_FROM_ABI bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {151 return __x.base() > __y.base();152}153 154template <class _Iter1, class _Iter2>155inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {156 return __x.base() != __y.base();157}158 159template <class _Iter1, class _Iter2>160inline _LIBCPP_HIDE_FROM_ABI bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {161 return __x.base() < __y.base();162}163 164template <class _Iter1, class _Iter2>165inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {166 return __x.base() <= __y.base();167}168 169template <class _Iter1, class _Iter2>170inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {171 return __x.base() >= __y.base();172}173 174template <class _Iter1, class _Iter2>175inline _LIBCPP_HIDE_FROM_ABI typename reverse_iterator<_Iter1>::difference_type176operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) {177 return __y.base() - __x.base();178}179 180template <class _Iter>181inline _LIBCPP_HIDE_FROM_ABI reverse_iterator<_Iter>182operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) {183 return reverse_iterator<_Iter>(__x.base() - __n);184}185 186template <class _Iter, bool __b>187struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b> {188 using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>()));189 using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >;190 191 static _LIBCPP_HIDE_FROM_ABI _ReverseWrapper __rewrap(_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) {192 return _ReverseWrapper(193 reverse_iterator<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap(__orig_iter.base().base(), __unwrapped_iter)));194 }195 196 static _LIBCPP_HIDE_FROM_ABI _UnwrappedIter __unwrap(_ReverseWrapper __i) _NOEXCEPT {197 return __unwrap_iter_impl<_Iter>::__unwrap(__i.base().base());198 }199};200 201_LIBCPP_END_NAMESPACE_STD202 203#endif // _LIBCPP___CXX03___ITERATOR_REVERSE_ITERATOR_H204