Bug 1216041 - Add ranged iterator support to mozilla::{Array,RangedArray,EnumerationArray}. r=froydnj
authorCameron McCormack <cam@mcc.id.au>
Tue, 20 Oct 2015 10:16:20 +1100
changeset 303600 c3e202bf0f25772c0eb34078db586449e51ccd00
parent 303599 c24e66d011eca8cf40bd5e48bacc804e429652c3
child 303601 240c0cff264b63cd246e63d0c266f0328b1c18e3
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1216041
milestone44.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 1216041 - Add ranged iterator support to mozilla::{Array,RangedArray,EnumerationArray}. r=froydnj
mfbt/Array.h
mfbt/EnumeratedArray.h
mfbt/EnumeratedRange.h
mfbt/RangedArray.h
--- a/mfbt/Array.h
+++ b/mfbt/Array.h
@@ -6,16 +6,17 @@
 
 /* A compile-time constant-length array with bounds-checking assertions. */
 
 #ifndef mozilla_Array_h
 #define mozilla_Array_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/ReverseIterator.h"
 
 #include <stddef.h>
 
 namespace mozilla {
 
 template<typename T, size_t Length>
 class Array
 {
@@ -28,16 +29,37 @@ public:
     return mArr[aIndex];
   }
 
   const T& operator[](size_t aIndex) const
   {
     MOZ_ASSERT(aIndex < Length);
     return mArr[aIndex];
   }
+
+  typedef T*                        iterator;
+  typedef const T*                  const_iterator;
+  typedef ReverseIterator<T*>       reverse_iterator;
+  typedef ReverseIterator<const T*> const_reverse_iterator;
+
+  // Methods for range-based for loops.
+  iterator begin() { return mArr; }
+  const_iterator begin() const { return mArr; }
+  const_iterator cbegin() const { return begin(); }
+  iterator end() { return mArr + Length; }
+  const_iterator end() const { return mArr + Length; }
+  const_iterator cend() const { return end(); }
+
+  // Methods for reverse iterating.
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+  const_reverse_iterator crbegin() const { return rbegin(); }
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+  const_reverse_iterator crend() const { return rend(); }
 };
 
 template<typename T>
 class Array<T, 0>
 {
 public:
   T& operator[](size_t aIndex)
   {
--- a/mfbt/EnumeratedArray.h
+++ b/mfbt/EnumeratedArray.h
@@ -41,17 +41,19 @@ template<typename IndexType,
          IndexType SizeAsEnumValue,
          typename ValueType>
 class EnumeratedArray
 {
 public:
   static const size_t kSize = size_t(SizeAsEnumValue);
 
 private:
-  Array<ValueType, kSize> mArray;
+  typedef Array<ValueType, kSize> ArrayType;
+
+  ArrayType mArray;
 
 public:
   EnumeratedArray() {}
 
   explicit EnumeratedArray(const EnumeratedArray& aOther)
   {
     for (size_t i = 0; i < kSize; i++) {
       mArray[i] = aOther.mArray[i];
@@ -62,13 +64,34 @@ public:
   {
     return mArray[size_t(aIndex)];
   }
 
   const ValueType& operator[](IndexType aIndex) const
   {
     return mArray[size_t(aIndex)];
   }
+
+  typedef typename ArrayType::iterator               iterator;
+  typedef typename ArrayType::const_iterator         const_iterator;
+  typedef typename ArrayType::reverse_iterator       reverse_iterator;
+  typedef typename ArrayType::const_reverse_iterator const_reverse_iterator;
+
+  // Methods for range-based for loops.
+  iterator begin() { return mArray.begin(); }
+  const_iterator begin() const { return mArray.begin(); }
+  const_iterator cbegin() const { return mArray.cbegin(); }
+  iterator end() { return mArray.end(); }
+  const_iterator end() const { return mArray.end(); }
+  const_iterator cend() const { return mArray.cend(); }
+
+  // Methods for reverse iterating.
+  reverse_iterator rbegin() { return mArray.rbegin(); }
+  const_reverse_iterator rbegin() const { return mArray.rbegin(); }
+  const_reverse_iterator crbegin() const { return mArray.crbegin(); }
+  reverse_iterator rend() { return mArray.rend(); }
+  const_reverse_iterator rend() const { return mArray.rend(); }
+  const_reverse_iterator crend() const { return mArray.crend(); }
 };
 
 } // namespace mozilla
 
 #endif // mozilla_EnumeratedArray_h
--- a/mfbt/EnumeratedRange.h
+++ b/mfbt/EnumeratedRange.h
@@ -190,22 +190,24 @@ MakeEnumeratedRange(EnumType aBegin, Enu
   return detail::EnumeratedRange<IntType, EnumType>(aBegin, aEnd);
 }
 
 // Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0)
 // should exist, but note that there is no way for us to ensure that it does!
 // Since the enumeration starts at EnumType(0), we know for sure that the values
 // will be in range of our deduced IntType.
 template<typename EnumType>
-inline detail::EnumeratedRange<UnsignedStdintTypeForSize<sizeof(EnumType)>::Type,
-                               EnumType>
+inline detail::EnumeratedRange<
+  typename UnsignedStdintTypeForSize<sizeof(EnumType)>::Type,
+  EnumType>
 MakeEnumeratedRange(EnumType aEnd)
 {
-  return MakeEnumeratedRange<UnsignedStdintTypeForSize<sizeof(EnumType)>::Type>(
-      EnumType(0), aEnd);
+  return MakeEnumeratedRange<
+    typename UnsignedStdintTypeForSize<sizeof(EnumType)>::Type>(EnumType(0),
+                                                                aEnd);
 }
 
 #ifdef __GNUC__
 #  pragma GCC diagnostic pop
 #endif
 
 } // namespace mozilla
 
--- a/mfbt/RangedArray.h
+++ b/mfbt/RangedArray.h
@@ -17,28 +17,50 @@
 
 #include "mozilla/Array.h"
 
 namespace mozilla {
 
 template<typename T, size_t MinIndex, size_t Length>
 class RangedArray
 {
+private:
+  typedef Array<T, Length> ArrayType;
+  ArrayType mArr;
+
 public:
   T& operator[](size_t aIndex)
   {
     MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex);
     return mArr[aIndex - MinIndex];
   }
 
   const T& operator[](size_t aIndex) const
   {
     MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex);
     return mArr[aIndex - MinIndex];
   }
 
-private:
-  Array<T, Length> mArr;
+  typedef typename ArrayType::iterator               iterator;
+  typedef typename ArrayType::const_iterator         const_iterator;
+  typedef typename ArrayType::reverse_iterator       reverse_iterator;
+  typedef typename ArrayType::const_reverse_iterator const_reverse_iterator;
+
+  // Methods for range-based for loops.
+  iterator begin() { return mArr.begin(); }
+  const_iterator begin() const { return mArr.begin(); }
+  const_iterator cbegin() const { return mArr.cbegin(); }
+  iterator end() { return mArr.end(); }
+  const_iterator end() const { return mArr.end(); }
+  const_iterator cend() const { return mArr.cend(); }
+
+  // Methods for reverse iterating.
+  reverse_iterator rbegin() { return mArr.rbegin(); }
+  const_reverse_iterator rbegin() const { return mArr.rbegin(); }
+  const_reverse_iterator crbegin() const { return mArr.crbegin(); }
+  reverse_iterator rend() { return mArr.rend(); }
+  const_reverse_iterator rend() const { return mArr.rend(); }
+  const_reverse_iterator crend() const { return mArr.crend(); }
 };
 
 } // namespace mozilla
 
 #endif // mozilla_RangedArray_h