Add unchecked versions of advance(), subtract(), and subpiece() in Range
authorGiuseppe Ottaviano <ott@fb.com>
Wed, 28 Sep 2016 22:37:33 +0000 (15:37 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Wed, 28 Sep 2016 22:38:32 +0000 (15:38 -0700)
Summary:
`Range` has a somewhat inconsistent API: most methods assume
argument validity as a precondition (mirroring their STL
counterparts), others check the arguments and throw for invalid ones.

Since `Range` is intended as a zero-cost abstraction on top of
pointers/iterators, unchecked methods should be preferred. At this
point however we cannot change the semantics of `advance()` and other
methods. This diff adds new unchecked versions of these methods.

Reviewed By: luciang

Differential Revision: D3938480

fbshipit-source-id: 6952683ee0716aa1584e79584158fbf3e083b52e

folly/Range.h
folly/Varint.h

index 0b63f45770efa5f29ec579b48d23c86d37bdd962..59e14bd5df84bb00b94ee975a347f879b079304f 100644 (file)
@@ -465,6 +465,30 @@ public:
     e_ -= n;
   }
 
+  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(length, size() - first));
+  }
+
+  // unchecked versions
+  void uncheckedAdvance(size_type n) {
+    DCHECK_LE(n, size());
+    b_ += n;
+  }
+
+  void uncheckedSubtract(size_type n) {
+    DCHECK_LE(n, size());
+    e_ -= n;
+  }
+
+  Range uncheckedSubpiece(size_type first, size_type length = npos) const {
+    DCHECK_LE(first, size());
+    return Range(b_ + first, std::min(length, size() - first));
+  }
+
   void pop_front() {
     assert(b_ < e_);
     ++b_;
@@ -475,14 +499,6 @@ public:
     --e_;
   }
 
-  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(length, size() - first));
-  }
-
   // string work-alike functions
   size_type find(const_range_type str) const {
     return qfind(castToConst(), str);
index e4af0c19000a02697f0d5aee3ad1711ff44791fb..859535736e764351cf32469473fb9a30bf010781 100644 (file)
@@ -133,7 +133,7 @@ inline uint64_t decodeVarint(Range<T*>& data) {
     val |= static_cast<uint64_t>(*p++) << shift;
   }
 
-  data.advance(p - begin);
+  data.uncheckedAdvance(p - begin);
   return val;
 }