Bug 1315352 - enable Range<T> -> Range<const T> conversion; r=Waldo
authorNathan Froyd <froydnj@mozilla.com>
Mon, 07 Nov 2016 19:30:34 -0400
changeset 351481 478f38ea7eca5d6d05ef64854798768b99278815
parent 351480 23667d366a5d4e04e7ee2e327596d8256d439bd0
child 351482 d18a718eb96f8418438556121661c0005135e511
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1315352
milestone52.0a1
Bug 1315352 - enable Range<T> -> Range<const T> conversion; r=Waldo Since |T*| converts into |const T*|, if we want to rewrite code such as: void DoSomething(const T*, size_t); void DoSomethingElse(T* x, size_t len) { ... DoSomething(x, len); } to use ranges: void DoSomething(Range<const T>); void DoSomethingElse(Range<T> x) { ... DoSomething(x); } we need to ensure this conversion works. gsl::span<T> already provides something like this as well.
mfbt/Range.h
mfbt/tests/TestRange.cpp
mfbt/tests/moz.build
--- a/mfbt/Range.h
+++ b/mfbt/Range.h
@@ -3,16 +3,17 @@
 /* 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/. */
 
 #ifndef mozilla_Range_h
 #define mozilla_Range_h
 
 #include "mozilla/RangedPtr.h"
+#include "mozilla/TypeTraits.h"
 
 #include <stddef.h>
 
 namespace mozilla {
 
 // Range<T> is a tuple containing a pointer and a length.
 template <typename T>
 class Range
@@ -30,16 +31,24 @@ public:
     : mStart(aStart.get(), aStart.get(), aEnd.get()),
       mEnd(aEnd.get(), aStart.get(), aEnd.get())
   {
     // Only accept two RangedPtrs within the same range.
     aStart.checkIdenticalRange(aEnd);
     MOZ_ASSERT(aStart <= aEnd);
   }
 
+  template<typename U,
+           class = typename EnableIf<IsConvertible<U (*)[], T (*)[]>::value,
+                                     int>::Type>
+  Range(const Range<U>& aOther)
+    : mStart(aOther.mStart),
+      mEnd(aOther.mEnd)
+  {}
+
   RangedPtr<T> begin() const { return mStart; }
   RangedPtr<T> end() const { return mEnd; }
   size_t length() const { return mEnd - mStart; }
 
   T& operator[](size_t aOffset) const { return mStart[aOffset]; }
 
   explicit operator bool() const { return mStart != nullptr; }
 };
new file mode 100644
--- /dev/null
+++ b/mfbt/tests/TestRange.cpp
@@ -0,0 +1,23 @@
+/* -*- 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/. */
+
+#include "mozilla/Range.h"
+#include "mozilla/TypeTraits.h"
+
+using mozilla::IsConvertible;
+using mozilla::Range;
+
+static_assert(IsConvertible<Range<int>, Range<const int>>::value,
+              "Range should convert into const");
+static_assert(!IsConvertible<Range<const int>, Range<int>>::value,
+              "Range should not drop const in conversion");
+
+// We need a proper program so we have someplace to hang the static_asserts.
+int
+main()
+{
+  return 0;
+}
--- a/mfbt/tests/moz.build
+++ b/mfbt/tests/moz.build
@@ -28,16 +28,17 @@ CppUnitTests([
     'TestJSONWriter',
     'TestLinkedList',
     'TestMacroArgs',
     'TestMacroForEach',
     'TestMathAlgorithms',
     'TestMaybe',
     'TestNotNull',
     'TestPair',
+    'TestRange',
     'TestRefPtr',
     'TestRollingMean',
     'TestSaturate',
     'TestScopeExit',
     'TestSegmentedVector',
     'TestSHA1',
     'TestSplayTree',
     'TestTemplateLib',