#pragma once /** * A constexpr std::reverse_iterator for C++11. * Implementation taken from libstdc++, * https://raw.githubusercontent.com/gcc-mirror/gcc/gcc-9_2_0-release/libstdc%2B%2B-v3/include/bits/stl_iterator.h * adapted to our code base and constexpr'ified. */ // Copyright (C) 2001-2019 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ #include #include namespace c10 { template class reverse_iterator { protected: _Iterator current; using __traits_type = std::iterator_traits<_Iterator>; public: using iterator_type = _Iterator; using value_type = typename __traits_type::value_type; using difference_type = typename __traits_type::difference_type; using pointer = typename __traits_type::pointer; using reference = typename __traits_type::reference; using iterator_category = typename __traits_type::iterator_category; constexpr reverse_iterator() : current() {} explicit constexpr reverse_iterator(iterator_type __x) : current(__x) {} constexpr reverse_iterator(const reverse_iterator& __x) : current(__x.current) {} constexpr reverse_iterator& operator=(const reverse_iterator& rhs) noexcept { current = rhs.current; return current; } template constexpr reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) {} constexpr iterator_type base() const { return current; } constexpr reference operator*() const { #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 _Iterator iter = current; return *--iter; #else // Only works for random access iterators if we're not C++14 :( return *(current - 1); #endif } constexpr pointer operator->() const { #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 _Iterator iter = current; return _S_to_pointer(--iter); #else // Only works for random access iterators if we're not C++14 :( return _S_to_pointer(current - 1); #endif } constexpr reverse_iterator& operator++() { --current; return *this; } constexpr reverse_iterator operator++(int) { reverse_iterator __tmp = *this; --current; return __tmp; } constexpr reverse_iterator& operator--() { ++current; return *this; } constexpr reverse_iterator operator--(int) { reverse_iterator __tmp = *this; ++current; return __tmp; } constexpr reverse_iterator operator+(difference_type __n) const { return reverse_iterator(current - __n); } constexpr reverse_iterator& operator+=(difference_type __n) { current -= __n; return *this; } constexpr reverse_iterator operator-(difference_type __n) const { return reverse_iterator(current + __n); } constexpr reverse_iterator& operator-=(difference_type __n) { current += __n; return *this; } constexpr reference operator[](difference_type __n) const { return *(*this + __n); } private: template static constexpr _Tp* _S_to_pointer(_Tp* __p) { return __p; } template static constexpr pointer _S_to_pointer(_Tp __t) { return __t.operator->(); } }; template inline constexpr bool operator==( const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } template inline constexpr bool operator<( const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y.base() < __x.base(); } template inline constexpr bool operator!=( const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x == __y); } template inline constexpr bool operator>( const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y < __x; } template inline constexpr bool operator<=( const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__y < __x); } template inline constexpr bool operator>=( const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x < __y); } template inline constexpr bool operator==( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __x.base() == __y.base(); } template inline constexpr bool operator<( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y.base() < __x.base(); } template inline constexpr bool operator!=( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__x == __y); } template inline constexpr bool operator>( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y < __x; } template inline constexpr bool operator<=( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__y < __x); } template inline constexpr bool operator>=( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__x < __y); } template inline constexpr decltype(auto) operator-( const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y.base() - __x.base(); } template inline constexpr reverse_iterator<_Iterator> operator+( typename reverse_iterator<_Iterator>::difference_type __n, const reverse_iterator<_Iterator>& __x) { return reverse_iterator<_Iterator>(__x.base() - __n); } template inline constexpr reverse_iterator<_Iterator> __make_reverse_iterator( _Iterator __i) { return reverse_iterator<_Iterator>(__i); } template inline constexpr reverse_iterator<_Iterator> make_reverse_iterator( _Iterator __i) { return reverse_iterator<_Iterator>(__i); } template decltype(auto) __niter_base(reverse_iterator<_Iterator> __it) { return __make_reverse_iterator(__niter_base(__it.base())); } } // namespace c10