Bug 1290035 - Remove the explicit Type parameter to MakeEnumeratedRange. r?waldo draft
authorCameron McCormack <cam@mcc.id.au>
Thu, 28 Jul 2016 17:48:50 +0800
changeset 393715 ce80f6445e988bde55c4387dce14ff28d558ce10
parent 392248 93d4bd8a4ad33d4202c8705e1a4e4fe716843614
child 526653 0088e556a257201a562597b3af76235d7f0fe4aa
push id24395
push userbmo:cam@mcc.id.au
push dateThu, 28 Jul 2016 09:49:49 +0000
reviewerswaldo
bugs1290035
milestone50.0a1
Bug 1290035 - Remove the explicit Type parameter to MakeEnumeratedRange. r?waldo MozReview-Commit-ID: BtFVn9pTQpU
js/src/gc/Heap.h
mfbt/EnumeratedRange.h
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -178,38 +178,38 @@ IsObjectAllocKind(AllocKind kind)
 inline bool
 IsShapeAllocKind(AllocKind kind)
 {
     return kind == AllocKind::SHAPE || kind == AllocKind::ACCESSOR_SHAPE;
 }
 
 // Returns a sequence for use in a range-based for loop,
 // to iterate over all alloc kinds.
-inline decltype(mozilla::MakeEnumeratedRange<int>(AllocKind::FIRST, AllocKind::LIMIT))
+inline decltype(mozilla::MakeEnumeratedRange(AllocKind::FIRST, AllocKind::LIMIT))
 AllAllocKinds()
 {
-    return mozilla::MakeEnumeratedRange<int>(AllocKind::FIRST, AllocKind::LIMIT);
+    return mozilla::MakeEnumeratedRange(AllocKind::FIRST, AllocKind::LIMIT);
 }
 
 // Returns a sequence for use in a range-based for loop,
 // to iterate over all object alloc kinds.
-inline decltype(mozilla::MakeEnumeratedRange<int>(AllocKind::OBJECT_FIRST, AllocKind::OBJECT_LIMIT))
+inline decltype(mozilla::MakeEnumeratedRange(AllocKind::OBJECT_FIRST, AllocKind::OBJECT_LIMIT))
 ObjectAllocKinds()
 {
-    return mozilla::MakeEnumeratedRange<int>(AllocKind::OBJECT_FIRST, AllocKind::OBJECT_LIMIT);
+    return mozilla::MakeEnumeratedRange(AllocKind::OBJECT_FIRST, AllocKind::OBJECT_LIMIT);
 }
 
 // Returns a sequence for use in a range-based for loop,
 // to iterate over alloc kinds from |first| to |limit|, exclusive.
-inline decltype(mozilla::MakeEnumeratedRange<int>(AllocKind::FIRST, AllocKind::LIMIT))
+inline decltype(mozilla::MakeEnumeratedRange(AllocKind::FIRST, AllocKind::LIMIT))
 SomeAllocKinds(AllocKind first = AllocKind::FIRST, AllocKind limit = AllocKind::LIMIT)
 {
     MOZ_ASSERT(IsAllocKind(first), "|first| is not a valid AllocKind!");
     MOZ_ASSERT(IsAllocKind(limit), "|limit| is not a valid AllocKind!");
-    return mozilla::MakeEnumeratedRange<int>(first, limit);
+    return mozilla::MakeEnumeratedRange(first, limit);
 }
 
 // AllAllocKindArray<ValueType> gives an enumerated array of ValueTypes,
 // with each index corresponding to a particular alloc kind.
 template<typename ValueType> using AllAllocKindArray =
     mozilla::EnumeratedArray<AllocKind, AllocKind::LIMIT, ValueType>;
 
 // ObjectAllocKindArray<ValueType> gives an enumerated array of ValueTypes,
--- a/mfbt/EnumeratedRange.h
+++ b/mfbt/EnumeratedRange.h
@@ -15,33 +15,36 @@
  * Note that the enum values should be contiguous in the iterated range;
  * unfortunately there exists no way for EnumeratedRange to enforce this
  * either dynamically or at compile time.
  */
 
 #ifndef mozilla_EnumeratedRange_h
 #define mozilla_EnumeratedRange_h
 
-#include "mozilla/IntegerTypeTraits.h"
+#include <type_traits>
+
 #include "mozilla/ReverseIterator.h"
 
 namespace mozilla {
 
 namespace detail {
 
-template<typename IntTypeT, typename EnumTypeT>
+template<typename EnumTypeT>
 class EnumeratedIterator
 {
 public:
+  typedef typename std::underlying_type<EnumTypeT>::type IntTypeT;
+
   template<typename EnumType>
   explicit EnumeratedIterator(EnumType aCurrent)
     : mCurrent(aCurrent) { }
 
-  template<typename IntType, typename EnumType>
-  explicit EnumeratedIterator(const EnumeratedIterator<IntType, EnumType>& aOther)
+  template<typename EnumType>
+  explicit EnumeratedIterator(const EnumeratedIterator<EnumType>& aOther)
     : mCurrent(aOther.mCurrent) { }
 
   EnumTypeT operator*() const { return mCurrent; }
 
   /* Increment and decrement operators */
 
   EnumeratedIterator& operator++()
   {
@@ -63,87 +66,87 @@ public:
   {
     auto ret = *this;
     mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
     return ret;
   }
 
   /* Comparison operators */
 
-  template<typename IntType, typename EnumType>
-  friend bool operator==(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                         const EnumeratedIterator<IntType, EnumType>& aIter2);
-  template<typename IntType, typename EnumType>
-  friend bool operator!=(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                         const EnumeratedIterator<IntType, EnumType>& aIter2);
-  template<typename IntType, typename EnumType>
-  friend bool operator<(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                        const EnumeratedIterator<IntType, EnumType>& aIter2);
-  template<typename IntType, typename EnumType>
-  friend bool operator<=(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                         const EnumeratedIterator<IntType, EnumType>& aIter2);
-  template<typename IntType, typename EnumType>
-  friend bool operator>(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                        const EnumeratedIterator<IntType, EnumType>& aIter2);
-  template<typename IntType, typename EnumType>
-  friend bool operator>=(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                         const EnumeratedIterator<IntType, EnumType>& aIter2);
+  template<typename EnumType>
+  friend bool operator==(const EnumeratedIterator<EnumType>& aIter1,
+                         const EnumeratedIterator<EnumType>& aIter2);
+  template<typename EnumType>
+  friend bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
+                         const EnumeratedIterator<EnumType>& aIter2);
+  template<typename EnumType>
+  friend bool operator<(const EnumeratedIterator<EnumType>& aIter1,
+                        const EnumeratedIterator<EnumType>& aIter2);
+  template<typename EnumType>
+  friend bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
+                         const EnumeratedIterator<EnumType>& aIter2);
+  template<typename EnumType>
+  friend bool operator>(const EnumeratedIterator<EnumType>& aIter1,
+                        const EnumeratedIterator<EnumType>& aIter2);
+  template<typename EnumType>
+  friend bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
+                         const EnumeratedIterator<EnumType>& aIter2);
 
 private:
   EnumTypeT mCurrent;
 };
 
-template<typename IntType, typename EnumType>
-bool operator==(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                const EnumeratedIterator<IntType, EnumType>& aIter2)
+template<typename EnumType>
+bool operator==(const EnumeratedIterator<EnumType>& aIter1,
+                const EnumeratedIterator<EnumType>& aIter2)
 {
   return aIter1.mCurrent == aIter2.mCurrent;
 }
 
-template<typename IntType, typename EnumType>
-bool operator!=(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                const EnumeratedIterator<IntType, EnumType>& aIter2)
+template<typename EnumType>
+bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
+                const EnumeratedIterator<EnumType>& aIter2)
 {
   return aIter1.mCurrent != aIter2.mCurrent;
 }
 
-template<typename IntType, typename EnumType>
-bool operator<(const EnumeratedIterator<IntType, EnumType>& aIter1,
-               const EnumeratedIterator<IntType, EnumType>& aIter2)
+template<typename EnumType>
+bool operator<(const EnumeratedIterator<EnumType>& aIter1,
+               const EnumeratedIterator<EnumType>& aIter2)
 {
   return aIter1.mCurrent < aIter2.mCurrent;
 }
 
-template<typename IntType, typename EnumType>
-bool operator<=(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                const EnumeratedIterator<IntType, EnumType>& aIter2)
+template<typename EnumType>
+bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
+                const EnumeratedIterator<EnumType>& aIter2)
 {
   return aIter1.mCurrent <= aIter2.mCurrent;
 }
 
-template<typename IntType, typename EnumType>
-bool operator>(const EnumeratedIterator<IntType, EnumType>& aIter1,
-               const EnumeratedIterator<IntType, EnumType>& aIter2)
+template<typename EnumType>
+bool operator>(const EnumeratedIterator<EnumType>& aIter1,
+               const EnumeratedIterator<EnumType>& aIter2)
 {
   return aIter1.mCurrent > aIter2.mCurrent;
 }
 
-template<typename IntType, typename EnumType>
-bool operator>=(const EnumeratedIterator<IntType, EnumType>& aIter1,
-                const EnumeratedIterator<IntType, EnumType>& aIter2)
+template<typename EnumType>
+bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
+                const EnumeratedIterator<EnumType>& aIter2)
 {
   return aIter1.mCurrent >= aIter2.mCurrent;
 }
 
-template<typename IntTypeT, typename EnumTypeT>
+template<typename EnumTypeT>
 class EnumeratedRange
 {
 public:
-  typedef EnumeratedIterator<IntTypeT, EnumTypeT> iterator;
-  typedef EnumeratedIterator<IntTypeT, EnumTypeT> const_iterator;
+  typedef EnumeratedIterator<EnumTypeT> iterator;
+  typedef EnumeratedIterator<EnumTypeT> const_iterator;
   typedef ReverseIterator<iterator> reverse_iterator;
   typedef ReverseIterator<const_iterator> const_reverse_iterator;
 
   template<typename EnumType>
   EnumeratedRange(EnumType aBegin, EnumType aEnd)
     : mBegin(aBegin), mEnd(aEnd) { }
 
   iterator begin() const { return iterator(mBegin); }
@@ -166,48 +169,31 @@ private:
 // Enums can have an unsigned underlying type, which makes some of the
 // comparisons below always true or always false. Temporarily disable
 // -Wtype-limits to avoid breaking -Werror builds.
 #  pragma GCC diagnostic push
 #  pragma GCC diagnostic ignored "-Wtype-limits"
 #endif
 
 // Create a range to iterate from aBegin to aEnd, exclusive.
-//
-// (Once we can rely on std::underlying_type, we can remove the IntType
-// template parameter.)
-template<typename IntType, typename EnumType>
-inline detail::EnumeratedRange<IntType, EnumType>
+template<typename EnumType>
+inline detail::EnumeratedRange<EnumType>
 MakeEnumeratedRange(EnumType aBegin, EnumType aEnd)
 {
-#ifdef DEBUG
-  typedef typename MakeUnsigned<IntType>::Type UnsignedType;
-#endif
-  static_assert(sizeof(IntType) >= sizeof(EnumType),
-                "IntType should be at least as big as EnumType!");
   MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!");
-  MOZ_ASSERT_IF(aBegin < EnumType(0), IsSigned<IntType>::value);
-  MOZ_ASSERT_IF(aBegin >= EnumType(0) && IsSigned<IntType>::value,
-                UnsignedType(aEnd) <= UnsignedType(MaxValue<IntType>::value));
-  return detail::EnumeratedRange<IntType, EnumType>(aBegin, aEnd);
+  return detail::EnumeratedRange<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<
-  typename UnsignedStdintTypeForSize<sizeof(EnumType)>::Type,
-  EnumType>
+inline detail::EnumeratedRange<EnumType>
 MakeEnumeratedRange(EnumType aEnd)
 {
-  return MakeEnumeratedRange<
-    typename UnsignedStdintTypeForSize<sizeof(EnumType)>::Type>(EnumType(0),
-                                                                aEnd);
+  return MakeEnumeratedRange(EnumType(0), aEnd);
 }
 
 #ifdef __GNUC__
 #  pragma GCC diagnostic pop
 #endif
 
 } // namespace mozilla