Remove unnecessary constraint from Range subpiece constructor
authorGiuseppe Ottaviano <ott@fb.com>
Fri, 19 Dec 2014 17:50:57 +0000 (09:50 -0800)
committerDave Watson <davejwatson@fb.com>
Mon, 29 Dec 2014 18:39:47 +0000 (10:39 -0800)
Summary:
D1746899 enforced the constraint (previously in a comment) on the
constructor `Range(const Range&, size_t, size_t)` that `Iter` is a
`const char*`. There is however no reason for this constraint.

This patch generalizes and simplifies the constructor, and since it
has the same semantics as `subpiece`, the latter is implemented in
terms of the constructor.

Test Plan:
fbconfig -r folly && fbmake runtests_opt

Reviewed By: soren@fb.com

Subscribers: trunkagent, folly-diffs@

FB internal diff: D1747958

Signature: t1:1747958:1418930360:fcd6beeda34e64ec8a34b9491a57674ae2265596

folly/Range.h
folly/test/RangeTest.cpp

index dccb92d011c54d515bd020447da76a3f65cc8029..f22d30e9418461e9085884ad0dd977e1b75698e0 100644 (file)
@@ -213,6 +213,7 @@ public:
     b_ = str.data() + startFrom;
     e_ = str.data() + str.size();
   }
+
   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
   Range(const std::string& str,
         std::string::size_type startFrom,
@@ -227,23 +228,17 @@ public:
       e_ = b_ + size;
     }
   }
-  template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
-  Range(const Range<Iter>& str,
-        size_t startFrom,
-        size_t size) {
-    if (UNLIKELY(startFrom > str.size())) {
-      throw std::out_of_range("index out of range");
-    }
-    b_ = str.b_ + startFrom;
-    if (str.size() - startFrom < size) {
-      e_ = str.e_;
-    } else {
-      e_ = b_ + size;
-    }
-  }
+
+  Range(const Range& other,
+        size_type first,
+        size_type length = npos)
+      : Range(other.subpiece(first, length))
+    { }
+
   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
   /* implicit */ Range(const fbstring& str)
     : b_(str.data()), e_(b_ + str.size()) { }
+
   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
   Range(const fbstring& str, fbstring::size_type startFrom) {
     if (UNLIKELY(startFrom > str.size())) {
@@ -252,6 +247,7 @@ public:
     b_ = str.data() + startFrom;
     e_ = str.data() + str.size();
   }
+
   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
   Range(const fbstring& str, fbstring::size_type startFrom,
         fbstring::size_type size) {
@@ -452,13 +448,12 @@ public:
     --e_;
   }
 
-  Range subpiece(size_type first,
-                 size_type length = std::string::npos) const {
+  Range subpiece(size_type first, size_type length = npos) const {
     if (UNLIKELY(first > size())) {
       throw std::out_of_range("index out of range");
     }
-    return Range(b_ + first,
-                 std::min<std::string::size_type>(length, size() - first));
+
+    return Range(b_ + first, std::min(length, size() - first));
   }
 
   // string work-alike functions
index 29ea85bfd50947764cd3cdde1568810108593d8f..02568dbcd8a22bc030c83789d6d1e0391d84c4f3 100644 (file)
@@ -1177,3 +1177,15 @@ TEST(ReplaceAll, BadArg) {
 
   EXPECT_EQ(count, 2);
 }
+
+TEST(Range, Constructors) {
+  vector<int> c = {1, 2, 3};
+  typedef Range<vector<int>::iterator> RangeType;
+  typedef Range<vector<int>::const_iterator> ConstRangeType;
+  RangeType cr(c.begin(), c.end());
+  auto subpiece1 = ConstRangeType(cr, 1, 5);
+  auto subpiece2 = ConstRangeType(cr, 1);
+  EXPECT_EQ(subpiece1.size(), 2);
+  EXPECT_EQ(subpiece1.begin(), subpiece2.begin());
+  EXPECT_EQ(subpiece1.end(), subpiece2.end());
+}