Enable a missing test in the CMake build
[folly.git] / folly / Range.h
index bfbb4eb0f609c0547da193f3f0875a36f36219cd..f80e635de58d5686ff59b0115070a8c72a492da8 100644 (file)
 #include <folly/detail/RangeSse42.h>
 
 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
+FOLLY_PUSH_WARNING
+FOLLY_GCC_DISABLE_WARNING("-Wshadow")
 
 namespace folly {
 
-template <class T> class Range;
+template <class Iter> class Range;
 
 /**
  * Finds the first occurrence of needle in haystack. The algorithm is on
@@ -69,9 +69,10 @@ template <class T> class Range;
  * as Boyer-Moore. On the upside, it does not do any upfront
  * preprocessing and does not allocate memory.
  */
-template <class T, class Comp = std::equal_to<typename Range<T>::value_type>>
-inline size_t qfind(const Range<T> & haystack,
-                    const Range<T> & needle,
+template <class Iter,
+          class Comp = std::equal_to<typename Range<Iter>::value_type>>
+inline size_t qfind(const Range<Iter> & haystack,
+                    const Range<Iter> & needle,
                     Comp eq = Comp());
 
 /**
@@ -79,27 +80,27 @@ inline size_t qfind(const Range<T> & haystack,
  * offset reported to the beginning of haystack, or string::npos if
  * needle wasn't found.
  */
-template <class T>
-size_t qfind(const Range<T> & haystack,
-             const typename Range<T>::value_type& needle);
+template <class Iter>
+size_t qfind(const Range<Iter> & haystack,
+             const typename Range<Iter>::value_type& needle);
 
 /**
  * Finds the last occurrence of needle in haystack. The result is the
  * offset reported to the beginning of haystack, or string::npos if
  * needle wasn't found.
  */
-template <class T>
-size_t rfind(const Range<T> & haystack,
-             const typename Range<T>::value_type& needle);
+template <class Iter>
+size_t rfind(const Range<Iter> & haystack,
+             const typename Range<Iter>::value_type& needle);
 
 
 /**
  * Finds the first occurrence of any element of needle in
  * haystack. The algorithm is O(haystack.size() * needle.size()).
  */
-template <class T>
-inline size_t qfind_first_of(const Range<T> & haystack,
-                             const Range<T> & needle);
+template <class Iter>
+inline size_t qfind_first_of(const Range<Iter> & haystack,
+                             const Range<Iter> & needle);
 
 /**
  * Small internal helper - returns the value just before an iterator.
@@ -360,6 +361,9 @@ public:
   Range& operator=(const Range& rhs) & = default;
   Range& operator=(Range&& rhs) & = default;
 
+  template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
+  Range& operator=(std::string&& rhs) = delete;
+
   void clear() {
     b_ = Iter();
     e_ = Iter();
@@ -659,6 +663,16 @@ public:
     return !empty() && front() == c;
   }
 
+  template <class Comp>
+  bool startsWith(const const_range_type& other, Comp&& eq) const {
+    if (size() < other.size()) {
+      return false;
+    }
+    auto const trunc = subpiece(0, other.size());
+    return std::equal(
+        trunc.begin(), trunc.end(), other.begin(), std::forward<Comp>(eq));
+  }
+
   /**
    * Does this Range end with another range?
    */
@@ -670,6 +684,22 @@ public:
     return !empty() && back() == c;
   }
 
+  template <class Comp>
+  bool endsWith(const const_range_type& other, Comp&& eq) const {
+    if (size() < other.size()) {
+      return false;
+    }
+    auto const trunc = subpiece(size() - other.size());
+    return std::equal(
+        trunc.begin(), trunc.end(), other.begin(), std::forward<Comp>(eq));
+  }
+
+  template <class Comp>
+  bool equals(const const_range_type& other, Comp&& eq) const {
+    return size() == other.size() &&
+        std::equal(begin(), end(), other.begin(), std::forward<Comp>(eq));
+  }
+
   /**
    * Remove the items in [b, e), as long as this subrange is at the beginning
    * or end of the Range.
@@ -900,8 +930,8 @@ private:
 template <class Iter>
 const typename Range<Iter>::size_type Range<Iter>::npos = std::string::npos;
 
-template <class T>
-void swap(Range<T>& lhs, Range<T>& rhs) {
+template <class Iter>
+void swap(Range<Iter>& lhs, Range<Iter>& rhs) {
   lhs.swap(rhs);
 }
 
@@ -956,13 +986,13 @@ inline std::ostream& operator<<(std::ostream& os,
  * Templated comparison operators
  */
 
-template <class T>
-inline bool operator==(const Range<T>& lhs, const Range<T>& rhs) {
+template <class Iter>
+inline bool operator==(const Range<Iter>& lhs, const Range<Iter>& rhs) {
   return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
 }
 
-template <class T>
-inline bool operator<(const Range<T>& lhs, const Range<T>& rhs) {
+template <class Iter>
+inline bool operator<(const Range<Iter>& lhs, const Range<Iter>& rhs) {
   return lhs.compare(rhs) < 0;
 }
 
@@ -1039,9 +1069,9 @@ operator>=(const T& lhs, const U& rhs) {
 /**
  * Finds substrings faster than brute force by borrowing from Boyer-Moore
  */
-template <class T, class Comp>
-size_t qfind(const Range<T>& haystack,
-             const Range<T>& needle,
+template <class Iter, class Comp>
+size_t qfind(const Range<Iter>& haystack,
+             const Range<Iter>& needle,
              Comp eq) {
   // Don't use std::search, use a Boyer-Moore-like trick by comparing
   // the last characters first
@@ -1107,9 +1137,9 @@ inline size_t qfind_first_byte_of(const StringPiece haystack,
 
 } // namespace detail
 
-template <class T, class Comp>
-size_t qfind_first_of(const Range<T> & haystack,
-                      const Range<T> & needles,
+template <class Iter, class Comp>
+size_t qfind_first_of(const Range<Iter> & haystack,
+                      const Range<Iter> & needles,
                       Comp eq) {
   auto ret = std::find_first_of(haystack.begin(), haystack.end(),
                                 needles.begin(), needles.end(),
@@ -1138,16 +1168,16 @@ struct AsciiCaseInsensitive {
   }
 };
 
-template <class T>
-size_t qfind(const Range<T>& haystack,
-             const typename Range<T>::value_type& needle) {
+template <class Iter>
+size_t qfind(const Range<Iter>& haystack,
+             const typename Range<Iter>::value_type& needle) {
   auto pos = std::find(haystack.begin(), haystack.end(), needle);
   return pos == haystack.end() ? std::string::npos : pos - haystack.data();
 }
 
-template <class T>
-size_t rfind(const Range<T>& haystack,
-             const typename Range<T>::value_type& needle) {
+template <class Iter>
+size_t rfind(const Range<Iter>& haystack,
+             const typename Range<Iter>::value_type& needle) {
   for (auto i = haystack.size(); i-- > 0; ) {
     if (haystack[i] == needle) {
       return i;
@@ -1204,9 +1234,9 @@ inline size_t rfind(const Range<const unsigned char*>& haystack,
   return pos == nullptr ? std::string::npos : pos - haystack.data();
 }
 
-template <class T>
-size_t qfind_first_of(const Range<T>& haystack,
-                      const Range<T>& needles) {
+template <class Iter>
+size_t qfind_first_of(const Range<Iter>& haystack,
+                      const Range<Iter>& needles) {
   return qfind_first_of(haystack, needles, AsciiCaseSensitive());
 }
 
@@ -1246,6 +1276,6 @@ template <class T> struct IsSomeString {
 
 }  // !namespace folly
 
-#pragma GCC diagnostic pop
+FOLLY_POP_WARNING
 
 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(folly::Range);