Bug 1127044 part 2 - Add ReverseIterator template class. r=waldo
authorXidorn Quan <quanxunzhen@gmail.com>
Wed, 04 Feb 2015 19:07:32 +1100
changeset 227414 8b2716be2d71f060e054e7f9dbf684b56c18e579
parent 227413 56219858c1e152b795d42b7ca8620eb2e1284d44
child 227415 e57cd9c7c07c23851583a350dfdf9a00bdd9ab90
push id28230
push userryanvm@gmail.com
push dateWed, 04 Feb 2015 19:42:59 +0000
treeherdermozilla-central@3cda3997f45d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1127044
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1127044 part 2 - Add ReverseIterator template class. r=waldo
mfbt/ReverseIterator.h
mfbt/moz.build
new file mode 100644
--- /dev/null
+++ b/mfbt/ReverseIterator.h
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/IteratorTraits.h"
+
+namespace mozilla {
+
+template<typename IteratorT>
+class ReverseIterator
+{
+public:
+  typedef typename IteratorTraits<IteratorT>::ValueType ValueType;
+  typedef typename IteratorTraits<IteratorT>::DifferenceType DifferenceType;
+
+  template<typename Iterator>
+  explicit ReverseIterator(Iterator aIter)
+    : mCurrent(aIter) { }
+
+  template<typename Iterator>
+  MOZ_IMPLICIT ReverseIterator(const ReverseIterator<Iterator>& aOther)
+    : mCurrent(aOther.mCurrent) { }
+
+  ValueType& 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; }
+
+  ReverseIterator operator+(DifferenceType aN) const
+  {
+    return ReverseIterator(mCurrent - aN);
+  }
+  ReverseIterator operator-(DifferenceType aN) const
+  {
+    return ReverseIterator(mCurrent + aN);
+  }
+  ReverseIterator& operator+=(DifferenceType aN)
+  {
+    mCurrent -= aN;
+    return *this;
+  }
+  ReverseIterator& operator-=(DifferenceType aN)
+  {
+    mCurrent += aN;
+    return *this;
+  }
+
+  /* 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>
+  IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd)
+    : mIterBegin(aIterBegin), mIterEnd(aIterEnd) { }
+
+  template<typename Iterator>
+  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
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -55,16 +55,17 @@ EXPORTS.mozilla = [
     'Pair.h',
     'PodOperations.h',
     'Poison.h',
     'Range.h',
     'RangedPtr.h',
     'RefCountType.h',
     'ReentrancyGuard.h',
     'RefPtr.h',
+    'ReverseIterator.h',
     'RollingMean.h',
     'Scoped.h',
     'SegmentedVector.h',
     'SHA1.h',
     'SizePrintfMacros.h',
     'SplayTree.h',
     'TaggedAnonymousMemory.h',
     'TemplateLib.h',