123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /* An iterator that acts like another iterator, but iterating in
- * the negative direction. (Note that not all iterators can iterate
- * in the negative direction.) */
- #ifndef mozilla_ReverseIterator_h
- #define mozilla_ReverseIterator_h
- #include "mozilla/Attributes.h"
- #include "mozilla/TypeTraits.h"
- namespace mozilla {
- template<typename IteratorT>
- class ReverseIterator
- {
- public:
- template<typename Iterator>
- explicit ReverseIterator(Iterator aIter)
- : mCurrent(aIter) { }
- template<typename Iterator>
- MOZ_IMPLICIT ReverseIterator(const ReverseIterator<Iterator>& aOther)
- : mCurrent(aOther.mCurrent) { }
- decltype(*DeclVal<IteratorT>()) operator*() const
- {
- IteratorT tmp = mCurrent;
- return *--tmp;
- }
- /* Increments and decrements operators */
- ReverseIterator& operator++() { --mCurrent; return *this; }
- ReverseIterator& operator--() { ++mCurrent; return *this; }
- ReverseIterator operator++(int) { auto ret = *this; mCurrent--; return ret; }
- ReverseIterator operator--(int) { auto ret = *this; mCurrent++; return ret; }
- /* Comparison operators */
- template<typename Iterator1, typename Iterator2>
- friend bool operator==(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2);
- template<typename Iterator1, typename Iterator2>
- friend bool operator!=(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2);
- template<typename Iterator1, typename Iterator2>
- friend bool operator<(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2);
- template<typename Iterator1, typename Iterator2>
- friend bool operator<=(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2);
- template<typename Iterator1, typename Iterator2>
- friend bool operator>(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2);
- template<typename Iterator1, typename Iterator2>
- friend bool operator>=(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2);
- private:
- IteratorT mCurrent;
- };
- template<typename Iterator1, typename Iterator2>
- bool
- operator==(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2)
- {
- return aIter1.mCurrent == aIter2.mCurrent;
- }
- template<typename Iterator1, typename Iterator2>
- bool
- operator!=(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2)
- {
- return aIter1.mCurrent != aIter2.mCurrent;
- }
- template<typename Iterator1, typename Iterator2>
- bool
- operator<(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2)
- {
- return aIter1.mCurrent > aIter2.mCurrent;
- }
- template<typename Iterator1, typename Iterator2>
- bool
- operator<=(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2)
- {
- return aIter1.mCurrent >= aIter2.mCurrent;
- }
- template<typename Iterator1, typename Iterator2>
- bool
- operator>(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2)
- {
- return aIter1.mCurrent < aIter2.mCurrent;
- }
- template<typename Iterator1, typename Iterator2>
- bool
- operator>=(const ReverseIterator<Iterator1>& aIter1,
- const ReverseIterator<Iterator2>& aIter2)
- {
- return aIter1.mCurrent <= aIter2.mCurrent;
- }
- namespace detail {
- template<typename IteratorT>
- class IteratorRange
- {
- public:
- typedef IteratorT iterator;
- typedef IteratorT const_iterator;
- typedef ReverseIterator<IteratorT> reverse_iterator;
- typedef ReverseIterator<IteratorT> const_reverse_iterator;
- template<typename Iterator1, typename Iterator2>
- MOZ_IMPLICIT IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd)
- : mIterBegin(aIterBegin), mIterEnd(aIterEnd) { }
- template<typename Iterator>
- MOZ_IMPLICIT IteratorRange(const IteratorRange<Iterator>& aOther)
- : mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { }
- iterator begin() const { return mIterBegin; }
- const_iterator cbegin() const { return begin(); }
- iterator end() const { return mIterEnd; }
- const_iterator cend() const { return end(); }
- reverse_iterator rbegin() const { return reverse_iterator(mIterEnd); }
- const_reverse_iterator crbegin() const { return rbegin(); }
- reverse_iterator rend() const { return reverse_iterator(mIterBegin); }
- const_reverse_iterator crend() const { return rend(); }
- private:
- IteratorT mIterBegin;
- IteratorT mIterEnd;
- };
- } // namespace detail
- template<typename Range>
- detail::IteratorRange<typename Range::reverse_iterator>
- Reversed(Range& aRange)
- {
- return {aRange.rbegin(), aRange.rend()};
- }
- template<typename Range>
- detail::IteratorRange<typename Range::const_reverse_iterator>
- Reversed(const Range& aRange)
- {
- return {aRange.rbegin(), aRange.rend()};
- }
- } // namespace mozilla
- #endif // mozilla_ReverseIterator_h
|