Update SSLContext to use folly::Random and discrete_distribution
[folly.git] / folly / Range.h
1 /*
2  * Copyright 2015 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // @author Mark Rabkin (mrabkin@fb.com)
18 // @author Andrei Alexandrescu (andrei.alexandrescu@fb.com)
19
20 #ifndef FOLLY_RANGE_H_
21 #define FOLLY_RANGE_H_
22
23 #include <folly/Portability.h>
24 #include <folly/FBString.h>
25 #include <folly/SpookyHashV2.h>
26
27 #include <algorithm>
28 #include <boost/operators.hpp>
29 #include <climits>
30 #include <cstddef>
31 #include <cstring>
32 #include <glog/logging.h>
33 #include <iosfwd>
34 #include <stdexcept>
35 #include <string>
36 #include <type_traits>
37
38 // libc++ doesn't provide this header, nor does msvc
39 #ifdef FOLLY_HAVE_BITS_CXXCONFIG_H
40 // This file appears in two locations: inside fbcode and in the
41 // libstdc++ source code (when embedding fbstring as std::string).
42 // To aid in this schizophrenic use, two macros are defined in
43 // c++config.h:
44 //   _LIBSTDCXX_FBSTRING - Set inside libstdc++.  This is useful to
45 //      gate use inside fbcode v. libstdc++
46 #include <bits/c++config.h>
47 #endif
48
49 #include <folly/CpuId.h>
50 #include <folly/Traits.h>
51 #include <folly/Likely.h>
52 #include <folly/detail/RangeCommon.h>
53 #include <folly/detail/RangeSse42.h>
54
55 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
56 #pragma GCC diagnostic push
57 #pragma GCC diagnostic ignored "-Wshadow"
58
59 namespace folly {
60
61 template <class T> class Range;
62
63 /**
64  * Finds the first occurrence of needle in haystack. The algorithm is on
65  * average faster than O(haystack.size() * needle.size()) but not as fast
66  * as Boyer-Moore. On the upside, it does not do any upfront
67  * preprocessing and does not allocate memory.
68  */
69 template <class T, class Comp = std::equal_to<typename Range<T>::value_type>>
70 inline size_t qfind(const Range<T> & haystack,
71                     const Range<T> & needle,
72                     Comp eq = Comp());
73
74 /**
75  * Finds the first occurrence of needle in haystack. The result is the
76  * offset reported to the beginning of haystack, or string::npos if
77  * needle wasn't found.
78  */
79 template <class T>
80 size_t qfind(const Range<T> & haystack,
81              const typename Range<T>::value_type& needle);
82
83 /**
84  * Finds the last occurrence of needle in haystack. The result is the
85  * offset reported to the beginning of haystack, or string::npos if
86  * needle wasn't found.
87  */
88 template <class T>
89 size_t rfind(const Range<T> & haystack,
90              const typename Range<T>::value_type& needle);
91
92
93 /**
94  * Finds the first occurrence of any element of needle in
95  * haystack. The algorithm is O(haystack.size() * needle.size()).
96  */
97 template <class T>
98 inline size_t qfind_first_of(const Range<T> & haystack,
99                              const Range<T> & needle);
100
101 /**
102  * Small internal helper - returns the value just before an iterator.
103  */
104 namespace detail {
105
106 /**
107  * For random-access iterators, the value before is simply i[-1].
108  */
109 template <class Iter>
110 typename std::enable_if<
111   std::is_same<typename std::iterator_traits<Iter>::iterator_category,
112                std::random_access_iterator_tag>::value,
113   typename std::iterator_traits<Iter>::reference>::type
114 value_before(Iter i) {
115   return i[-1];
116 }
117
118 /**
119  * For all other iterators, we need to use the decrement operator.
120  */
121 template <class Iter>
122 typename std::enable_if<
123   !std::is_same<typename std::iterator_traits<Iter>::iterator_category,
124                 std::random_access_iterator_tag>::value,
125   typename std::iterator_traits<Iter>::reference>::type
126 value_before(Iter i) {
127   return *--i;
128 }
129
130 /*
131  * Use IsCharPointer<T>::type to enable const char* or char*.
132  * Use IsCharPointer<T>::const_type to enable only const char*.
133  */
134 template <class T> struct IsCharPointer {};
135
136 template <>
137 struct IsCharPointer<char*> {
138   typedef int type;
139 };
140
141 template <>
142 struct IsCharPointer<const char*> {
143   typedef int const_type;
144   typedef int type;
145 };
146
147 } // namespace detail
148
149 /**
150  * Range abstraction keeping a pair of iterators. We couldn't use
151  * boost's similar range abstraction because we need an API identical
152  * with the former StringPiece class, which is used by a lot of other
153  * code. This abstraction does fulfill the needs of boost's
154  * range-oriented algorithms though.
155  *
156  * (Keep memory lifetime in mind when using this class, since it
157  * doesn't manage the data it refers to - just like an iterator
158  * wouldn't.)
159  */
160 template <class Iter>
161 class Range : private boost::totally_ordered<Range<Iter> > {
162 public:
163   typedef std::size_t size_type;
164   typedef Iter iterator;
165   typedef Iter const_iterator;
166   typedef typename std::remove_reference<
167     typename std::iterator_traits<Iter>::reference>::type
168   value_type;
169   typedef typename std::iterator_traits<Iter>::reference reference;
170
171   /**
172    * For MutableStringPiece and MutableByteRange we define StringPiece
173    * and ByteRange as const_range_type (for everything else its just
174    * identity). We do that to enable operations such as find with
175    * args which are const.
176    */
177   typedef typename std::conditional<
178     std::is_same<Iter, char*>::value
179       || std::is_same<Iter, unsigned char*>::value,
180     Range<const value_type*>,
181     Range<Iter>>::type const_range_type;
182
183   typedef std::char_traits<typename std::remove_const<value_type>::type>
184     traits_type;
185
186   static const size_type npos;
187
188   // Works for all iterators
189   constexpr Range() : b_(), e_() {
190   }
191
192   constexpr Range(const Range&) = default;
193   constexpr Range(Range&&) = default;
194
195 public:
196   // Works for all iterators
197   constexpr Range(Iter start, Iter end) : b_(start), e_(end) {
198   }
199
200   // Works only for random-access iterators
201   constexpr Range(Iter start, size_t size)
202       : b_(start), e_(start + size) { }
203
204 # if !__clang__ || __CLANG_PREREQ(3, 7) // Clang 3.6 crashes on this line
205   /* implicit */ Range(std::nullptr_t) = delete;
206 # endif
207
208   template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
209   constexpr /* implicit */ Range(Iter str)
210       : b_(str), e_(str + constexpr_strlen(str)) {}
211
212   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
213   /* implicit */ Range(const std::string& str)
214       : b_(str.data()), e_(b_ + str.size()) {}
215
216   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
217   Range(const std::string& str, std::string::size_type startFrom) {
218     if (UNLIKELY(startFrom > str.size())) {
219       throw std::out_of_range("index out of range");
220     }
221     b_ = str.data() + startFrom;
222     e_ = str.data() + str.size();
223   }
224
225   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
226   Range(const std::string& str,
227         std::string::size_type startFrom,
228         std::string::size_type size) {
229     if (UNLIKELY(startFrom > str.size())) {
230       throw std::out_of_range("index out of range");
231     }
232     b_ = str.data() + startFrom;
233     if (str.size() - startFrom < size) {
234       e_ = str.data() + str.size();
235     } else {
236       e_ = b_ + size;
237     }
238   }
239
240   Range(const Range& other,
241         size_type first,
242         size_type length = npos)
243       : Range(other.subpiece(first, length))
244     { }
245
246   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
247   /* implicit */ Range(const fbstring& str)
248     : b_(str.data()), e_(b_ + str.size()) { }
249
250   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
251   Range(const fbstring& str, fbstring::size_type startFrom) {
252     if (UNLIKELY(startFrom > str.size())) {
253       throw std::out_of_range("index out of range");
254     }
255     b_ = str.data() + startFrom;
256     e_ = str.data() + str.size();
257   }
258
259   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
260   Range(const fbstring& str, fbstring::size_type startFrom,
261         fbstring::size_type size) {
262     if (UNLIKELY(startFrom > str.size())) {
263       throw std::out_of_range("index out of range");
264     }
265     b_ = str.data() + startFrom;
266     if (str.size() - startFrom < size) {
267       e_ = str.data() + str.size();
268     } else {
269       e_ = b_ + size;
270     }
271   }
272
273   // Allow implicit conversion from Range<const char*> (aka StringPiece) to
274   // Range<const unsigned char*> (aka ByteRange), as they're both frequently
275   // used to represent ranges of bytes.  Allow explicit conversion in the other
276   // direction.
277   template <class OtherIter, typename std::enable_if<
278       (std::is_same<Iter, const unsigned char*>::value &&
279        (std::is_same<OtherIter, const char*>::value ||
280         std::is_same<OtherIter, char*>::value)), int>::type = 0>
281   /* implicit */ Range(const Range<OtherIter>& other)
282     : b_(reinterpret_cast<const unsigned char*>(other.begin())),
283       e_(reinterpret_cast<const unsigned char*>(other.end())) {
284   }
285
286   template <class OtherIter, typename std::enable_if<
287       (std::is_same<Iter, unsigned char*>::value &&
288        std::is_same<OtherIter, char*>::value), int>::type = 0>
289   /* implicit */ Range(const Range<OtherIter>& other)
290     : b_(reinterpret_cast<unsigned char*>(other.begin())),
291       e_(reinterpret_cast<unsigned char*>(other.end())) {
292   }
293
294   template <class OtherIter, typename std::enable_if<
295       (std::is_same<Iter, const char*>::value &&
296        (std::is_same<OtherIter, const unsigned char*>::value ||
297         std::is_same<OtherIter, unsigned char*>::value)), int>::type = 0>
298   explicit Range(const Range<OtherIter>& other)
299     : b_(reinterpret_cast<const char*>(other.begin())),
300       e_(reinterpret_cast<const char*>(other.end())) {
301   }
302
303   template <class OtherIter, typename std::enable_if<
304       (std::is_same<Iter, char*>::value &&
305        std::is_same<OtherIter, unsigned char*>::value), int>::type = 0>
306   explicit Range(const Range<OtherIter>& other)
307     : b_(reinterpret_cast<char*>(other.begin())),
308       e_(reinterpret_cast<char*>(other.end())) {
309   }
310
311   // Allow implicit conversion from Range<From> to Range<To> if From is
312   // implicitly convertible to To.
313   template <class OtherIter, typename std::enable_if<
314      (!std::is_same<Iter, OtherIter>::value &&
315       std::is_convertible<OtherIter, Iter>::value), int>::type = 0>
316   constexpr /* implicit */ Range(const Range<OtherIter>& other)
317     : b_(other.begin()),
318       e_(other.end()) {
319   }
320
321   // Allow explicit conversion from Range<From> to Range<To> if From is
322   // explicitly convertible to To.
323   template <class OtherIter, typename std::enable_if<
324     (!std::is_same<Iter, OtherIter>::value &&
325      !std::is_convertible<OtherIter, Iter>::value &&
326      std::is_constructible<Iter, const OtherIter&>::value), int>::type = 0>
327   constexpr explicit Range(const Range<OtherIter>& other)
328     : b_(other.begin()),
329       e_(other.end()) {
330   }
331
332   Range& operator=(const Range& rhs) & = default;
333   Range& operator=(Range&& rhs) & = default;
334
335   void clear() {
336     b_ = Iter();
337     e_ = Iter();
338   }
339
340   void assign(Iter start, Iter end) {
341     b_ = start;
342     e_ = end;
343   }
344
345   void reset(Iter start, size_type size) {
346     b_ = start;
347     e_ = start + size;
348   }
349
350   // Works only for Range<const char*>
351   void reset(const std::string& str) {
352     reset(str.data(), str.size());
353   }
354
355   size_type size() const {
356     assert(b_ <= e_);
357     return e_ - b_;
358   }
359   size_type walk_size() const {
360     return std::distance(b_, e_);
361   }
362   bool empty() const { return b_ == e_; }
363   Iter data() const { return b_; }
364   Iter start() const { return b_; }
365   Iter begin() const { return b_; }
366   Iter end() const { return e_; }
367   Iter cbegin() const { return b_; }
368   Iter cend() const { return e_; }
369   value_type& front() {
370     assert(b_ < e_);
371     return *b_;
372   }
373   value_type& back() {
374     assert(b_ < e_);
375     return detail::value_before(e_);
376   }
377   const value_type& front() const {
378     assert(b_ < e_);
379     return *b_;
380   }
381   const value_type& back() const {
382     assert(b_ < e_);
383     return detail::value_before(e_);
384   }
385   // Works only for Range<const char*> and Range<char*>
386   std::string str() const { return std::string(b_, size()); }
387   std::string toString() const { return str(); }
388   // Works only for Range<const char*> and Range<char*>
389   fbstring fbstr() const { return fbstring(b_, size()); }
390   fbstring toFbstring() const { return fbstr(); }
391
392   const_range_type castToConst() const {
393     return const_range_type(*this);
394   };
395
396   // Works only for Range<const char*> and Range<char*>
397   int compare(const const_range_type& o) const {
398     const size_type tsize = this->size();
399     const size_type osize = o.size();
400     const size_type msize = std::min(tsize, osize);
401     int r = traits_type::compare(data(), o.data(), msize);
402     if (r == 0 && tsize != osize) {
403       // We check the signed bit of the subtraction and bit shift it
404       // to produce either 0 or 2. The subtraction yields the
405       // comparison values of either -1 or 1.
406       r = (static_cast<int>(
407              (osize - tsize) >> (CHAR_BIT * sizeof(size_t) - 1)) << 1) - 1;
408     }
409     return r;
410   }
411
412   value_type& operator[](size_t i) {
413     DCHECK_GT(size(), i);
414     return b_[i];
415   }
416
417   const value_type& operator[](size_t i) const {
418     DCHECK_GT(size(), i);
419     return b_[i];
420   }
421
422   value_type& at(size_t i) {
423     if (i >= size()) throw std::out_of_range("index out of range");
424     return b_[i];
425   }
426
427   const value_type& at(size_t i) const {
428     if (i >= size()) throw std::out_of_range("index out of range");
429     return b_[i];
430   }
431
432   // Do NOT use this function, which was left behind for backwards
433   // compatibility.  Use SpookyHashV2 instead -- it is faster, and produces
434   // a 64-bit hash, which means dramatically fewer collisions in large maps.
435   // (The above advice does not apply if you are targeting a 32-bit system.)
436   //
437   // Works only for Range<const char*> and Range<char*>
438   uint32_t hash() const {
439     // Taken from fbi/nstring.h:
440     //    Quick and dirty bernstein hash...fine for short ascii strings
441     uint32_t hash = 5381;
442     for (size_t ix = 0; ix < size(); ix++) {
443       hash = ((hash << 5) + hash) + b_[ix];
444     }
445     return hash;
446   }
447
448   void advance(size_type n) {
449     if (UNLIKELY(n > size())) {
450       throw std::out_of_range("index out of range");
451     }
452     b_ += n;
453   }
454
455   void subtract(size_type n) {
456     if (UNLIKELY(n > size())) {
457       throw std::out_of_range("index out of range");
458     }
459     e_ -= n;
460   }
461
462   void pop_front() {
463     assert(b_ < e_);
464     ++b_;
465   }
466
467   void pop_back() {
468     assert(b_ < e_);
469     --e_;
470   }
471
472   Range subpiece(size_type first, size_type length = npos) const {
473     if (UNLIKELY(first > size())) {
474       throw std::out_of_range("index out of range");
475     }
476
477     return Range(b_ + first, std::min(length, size() - first));
478   }
479
480   // string work-alike functions
481   size_type find(const_range_type str) const {
482     return qfind(castToConst(), str);
483   }
484
485   size_type find(const_range_type str, size_t pos) const {
486     if (pos > size()) return std::string::npos;
487     size_t ret = qfind(castToConst().subpiece(pos), str);
488     return ret == npos ? ret : ret + pos;
489   }
490
491   size_type find(Iter s, size_t pos, size_t n) const {
492     if (pos > size()) return std::string::npos;
493     auto forFinding = castToConst();
494     size_t ret = qfind(
495         pos ? forFinding.subpiece(pos) : forFinding, const_range_type(s, n));
496     return ret == npos ? ret : ret + pos;
497   }
498
499   // Works only for Range<(const) (unsigned) char*> which have Range(Iter) ctor
500   size_type find(const Iter s) const {
501     return qfind(castToConst(), const_range_type(s));
502   }
503
504   // Works only for Range<(const) (unsigned) char*> which have Range(Iter) ctor
505   size_type find(const Iter s, size_t pos) const {
506     if (pos > size()) return std::string::npos;
507     size_type ret = qfind(castToConst().subpiece(pos), const_range_type(s));
508     return ret == npos ? ret : ret + pos;
509   }
510
511   size_type find(value_type c) const {
512     return qfind(castToConst(), c);
513   }
514
515   size_type rfind(value_type c) const {
516     return folly::rfind(castToConst(), c);
517   }
518
519   size_type find(value_type c, size_t pos) const {
520     if (pos > size()) return std::string::npos;
521     size_type ret = qfind(castToConst().subpiece(pos), c);
522     return ret == npos ? ret : ret + pos;
523   }
524
525   size_type find_first_of(const_range_type needles) const {
526     return qfind_first_of(castToConst(), needles);
527   }
528
529   size_type find_first_of(const_range_type needles, size_t pos) const {
530     if (pos > size()) return std::string::npos;
531     size_type ret = qfind_first_of(castToConst().subpiece(pos), needles);
532     return ret == npos ? ret : ret + pos;
533   }
534
535   // Works only for Range<(const) (unsigned) char*> which have Range(Iter) ctor
536   size_type find_first_of(Iter needles) const {
537     return find_first_of(const_range_type(needles));
538   }
539
540   // Works only for Range<(const) (unsigned) char*> which have Range(Iter) ctor
541   size_type find_first_of(Iter needles, size_t pos) const {
542     return find_first_of(const_range_type(needles), pos);
543   }
544
545   size_type find_first_of(Iter needles, size_t pos, size_t n) const {
546     return find_first_of(const_range_type(needles, n), pos);
547   }
548
549   size_type find_first_of(value_type c) const {
550     return find(c);
551   }
552
553   size_type find_first_of(value_type c, size_t pos) const {
554     return find(c, pos);
555   }
556
557   /**
558    * Determine whether the range contains the given subrange or item.
559    *
560    * Note: Call find() directly if the index is needed.
561    */
562   bool contains(const const_range_type& other) const {
563     return find(other) != std::string::npos;
564   }
565
566   bool contains(const value_type& other) const {
567     return find(other) != std::string::npos;
568   }
569
570   void swap(Range& rhs) {
571     std::swap(b_, rhs.b_);
572     std::swap(e_, rhs.e_);
573   }
574
575   /**
576    * Does this Range start with another range?
577    */
578   bool startsWith(const const_range_type& other) const {
579     return size() >= other.size()
580       && castToConst().subpiece(0, other.size()) == other;
581   }
582   bool startsWith(value_type c) const {
583     return !empty() && front() == c;
584   }
585
586   /**
587    * Does this Range end with another range?
588    */
589   bool endsWith(const const_range_type& other) const {
590     return size() >= other.size()
591       && castToConst().subpiece(size() - other.size()) == other;
592   }
593   bool endsWith(value_type c) const {
594     return !empty() && back() == c;
595   }
596
597   /**
598    * Remove the given prefix and return true if the range starts with the given
599    * prefix; return false otherwise.
600    */
601   bool removePrefix(const const_range_type& prefix) {
602     return startsWith(prefix) && (b_ += prefix.size(), true);
603   }
604   bool removePrefix(value_type prefix) {
605     return startsWith(prefix) && (++b_, true);
606   }
607
608   /**
609    * Remove the given suffix and return true if the range ends with the given
610    * suffix; return false otherwise.
611    */
612   bool removeSuffix(const const_range_type& suffix) {
613     return endsWith(suffix) && (e_ -= suffix.size(), true);
614   }
615   bool removeSuffix(value_type suffix) {
616     return endsWith(suffix) && (--e_, true);
617   }
618
619   /**
620    * Replaces the content of the range, starting at position 'pos', with
621    * contents of 'replacement'. Entire 'replacement' must fit into the
622    * range. Returns false if 'replacements' does not fit. Example use:
623    *
624    * char in[] = "buffer";
625    * auto msp = MutablesStringPiece(input);
626    * EXPECT_TRUE(msp.replaceAt(2, "tt"));
627    * EXPECT_EQ(msp, "butter");
628    *
629    * // not enough space
630    * EXPECT_FALSE(msp.replace(msp.size() - 1, "rr"));
631    * EXPECT_EQ(msp, "butter"); // unchanged
632    */
633   bool replaceAt(size_t pos, const_range_type replacement) {
634     if (size() < pos + replacement.size()) {
635       return false;
636     }
637
638     std::copy(replacement.begin(), replacement.end(), begin() + pos);
639
640     return true;
641   }
642
643   /**
644    * Replaces all occurences of 'source' with 'dest'. Returns number
645    * of replacements made. Source and dest have to have the same
646    * length. Throws if the lengths are different. If 'source' is a
647    * pattern that is overlapping with itself, we perform sequential
648    * replacement: "aaaaaaa".replaceAll("aa", "ba") --> "bababaa"
649    *
650    * Example use:
651    *
652    * char in[] = "buffer";
653    * auto msp = MutablesStringPiece(input);
654    * EXPECT_EQ(msp.replaceAll("ff","tt"), 1);
655    * EXPECT_EQ(msp, "butter");
656    */
657   size_t replaceAll(const_range_type source, const_range_type dest) {
658     if (source.size() != dest.size()) {
659       throw std::invalid_argument(
660           "replacement must have the same size as source");
661     }
662
663     if (dest.empty()) {
664       return 0;
665     }
666
667     size_t pos = 0;
668     size_t num_replaced = 0;
669     size_type found = std::string::npos;
670     while ((found = find(source, pos)) != std::string::npos) {
671       replaceAt(found, dest);
672       pos += source.size();
673       ++num_replaced;
674     }
675
676     return num_replaced;
677   }
678
679   /**
680    * Splits this `Range` `[b, e)` in the position `i` dictated by the next
681    * occurence of `delimiter`.
682    *
683    * Returns a new `Range` `[b, i)` and adjusts this range to start right after
684    * the delimiter's position. This range will be empty if the delimiter is not
685    * found. If called on an empty `Range`, both this and the returned `Range`
686    * will be empty.
687    *
688    * Example:
689    *
690    *  folly::StringPiece s("sample string for split_next");
691    *  auto p = s.split_step(' ');
692    *
693    *  // prints "string for split_next"
694    *  cout << s << endl;
695    *
696    *  // prints "sample"
697    *  cout << p << endl;
698    *
699    * Example 2:
700    *
701    *  void tokenize(StringPiece s, char delimiter) {
702    *    while (!s.empty()) {
703    *      cout << s.split_step(delimiter);
704    *    }
705    *  }
706    *
707    * @author: Marcelo Juchem <marcelo@fb.com>
708    */
709   Range split_step(value_type delimiter) {
710     auto i = std::find(b_, e_, delimiter);
711     Range result(b_, i);
712
713     b_ = i == e_ ? e_ : std::next(i);
714
715     return result;
716   }
717
718   Range split_step(Range delimiter) {
719     auto i = find(delimiter);
720     Range result(b_, i == std::string::npos ? size() : i);
721
722     b_ = result.end() == e_ ? e_ : std::next(result.end(), delimiter.size());
723
724     return result;
725   }
726
727   /**
728    * Convenience method that calls `split_step()` and passes the result to a
729    * functor, returning whatever the functor does. Any additional arguments
730    * `args` passed to this function are perfectly forwarded to the functor.
731    *
732    * Say you have a functor with this signature:
733    *
734    *  Foo fn(Range r) { }
735    *
736    * `split_step()`'s return type will be `Foo`. It works just like:
737    *
738    *  auto result = fn(myRange.split_step(' '));
739    *
740    * A functor returning `void` is also supported.
741    *
742    * Example:
743    *
744    *  void do_some_parsing(folly::StringPiece s) {
745    *    auto version = s.split_step(' ', [&](folly::StringPiece x) {
746    *      if (x.empty()) {
747    *        throw std::invalid_argument("empty string");
748    *      }
749    *      return std::strtoull(x.begin(), x.end(), 16);
750    *    });
751    *
752    *    // ...
753    *  }
754    *
755    *  struct Foo {
756    *    void parse(folly::StringPiece s) {
757    *      s.split_step(' ', parse_field, bar, 10);
758    *      s.split_step('\t', parse_field, baz, 20);
759    *
760    *      auto const kludge = [](folly::StringPiece x, int &out, int def) {
761    *        if (x == "null") {
762    *          out = 0;
763    *        } else {
764    *          parse_field(x, out, def);
765    *        }
766    *      };
767    *
768    *      s.split_step('\t', kludge, gaz);
769    *      s.split_step(' ', kludge, foo);
770    *    }
771    *
772    *  private:
773    *    int bar;
774    *    int baz;
775    *    int gaz;
776    *    int foo;
777    *
778    *    static parse_field(folly::StringPiece s, int &out, int def) {
779    *      try {
780    *        out = folly::to<int>(s);
781    *      } catch (std::exception const &) {
782    *        value = def;
783    *      }
784    *    }
785    *  };
786    *
787    * @author: Marcelo Juchem <marcelo@fb.com>
788    */
789   template <typename TProcess, typename... Args>
790   auto split_step(value_type delimiter, TProcess &&process, Args &&...args)
791     -> decltype(process(std::declval<Range>(), std::forward<Args>(args)...))
792   { return process(split_step(delimiter), std::forward<Args>(args)...); }
793
794   template <typename TProcess, typename... Args>
795   auto split_step(Range delimiter, TProcess &&process, Args &&...args)
796     -> decltype(process(std::declval<Range>(), std::forward<Args>(args)...))
797   { return process(split_step(delimiter), std::forward<Args>(args)...); }
798
799 private:
800   Iter b_, e_;
801 };
802
803 template <class Iter>
804 const typename Range<Iter>::size_type Range<Iter>::npos = std::string::npos;
805
806 template <class T>
807 void swap(Range<T>& lhs, Range<T>& rhs) {
808   lhs.swap(rhs);
809 }
810
811 /**
812  * Create a range from two iterators, with type deduction.
813  */
814 template <class Iter>
815 Range<Iter> range(Iter first, Iter last) {
816   return Range<Iter>(first, last);
817 }
818
819 /*
820  * Creates a range to reference the contents of a contiguous-storage container.
821  */
822 // Use pointers for types with '.data()' member
823 template <class Collection,
824           class T = typename std::remove_pointer<
825               decltype(std::declval<Collection>().data())>::type>
826 Range<T*> range(Collection&& v) {
827   return Range<T*>(v.data(), v.data() + v.size());
828 }
829
830 template <class T, size_t n>
831 Range<T*> range(T (&array)[n]) {
832   return Range<T*>(array, array + n);
833 }
834
835 typedef Range<const char*> StringPiece;
836 typedef Range<char*> MutableStringPiece;
837 typedef Range<const unsigned char*> ByteRange;
838 typedef Range<unsigned char*> MutableByteRange;
839
840 inline std::ostream& operator<<(std::ostream& os,
841                                 const StringPiece piece) {
842   os.write(piece.start(), piece.size());
843   return os;
844 }
845
846 inline std::ostream& operator<<(std::ostream& os,
847                                 const MutableStringPiece piece) {
848   os.write(piece.start(), piece.size());
849   return os;
850 }
851
852 /**
853  * Templated comparison operators
854  */
855
856 template <class T>
857 inline bool operator==(const Range<T>& lhs, const Range<T>& rhs) {
858   return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
859 }
860
861 template <class T>
862 inline bool operator<(const Range<T>& lhs, const Range<T>& rhs) {
863   return lhs.compare(rhs) < 0;
864 }
865
866 /**
867  * Specializations of comparison operators for StringPiece
868  */
869
870 namespace detail {
871
872 template <class A, class B>
873 struct ComparableAsStringPiece {
874   enum {
875     value =
876     (std::is_convertible<A, StringPiece>::value
877      && std::is_same<B, StringPiece>::value)
878     ||
879     (std::is_convertible<B, StringPiece>::value
880      && std::is_same<A, StringPiece>::value)
881   };
882 };
883
884 } // namespace detail
885
886 /**
887  * operator== through conversion for Range<const char*>
888  */
889 template <class T, class U>
890 typename
891 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
892 operator==(const T& lhs, const U& rhs) {
893   return StringPiece(lhs) == StringPiece(rhs);
894 }
895
896 /**
897  * operator< through conversion for Range<const char*>
898  */
899 template <class T, class U>
900 typename
901 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
902 operator<(const T& lhs, const U& rhs) {
903   return StringPiece(lhs) < StringPiece(rhs);
904 }
905
906 /**
907  * operator> through conversion for Range<const char*>
908  */
909 template <class T, class U>
910 typename
911 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
912 operator>(const T& lhs, const U& rhs) {
913   return StringPiece(lhs) > StringPiece(rhs);
914 }
915
916 /**
917  * operator< through conversion for Range<const char*>
918  */
919 template <class T, class U>
920 typename
921 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
922 operator<=(const T& lhs, const U& rhs) {
923   return StringPiece(lhs) <= StringPiece(rhs);
924 }
925
926 /**
927  * operator> through conversion for Range<const char*>
928  */
929 template <class T, class U>
930 typename
931 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
932 operator>=(const T& lhs, const U& rhs) {
933   return StringPiece(lhs) >= StringPiece(rhs);
934 }
935
936 // Do NOT use this, use SpookyHashV2 instead, see commment on hash() above.
937 struct StringPieceHash {
938   std::size_t operator()(const StringPiece str) const {
939     return static_cast<std::size_t>(str.hash());
940   }
941 };
942
943 /**
944  * Finds substrings faster than brute force by borrowing from Boyer-Moore
945  */
946 template <class T, class Comp>
947 size_t qfind(const Range<T>& haystack,
948              const Range<T>& needle,
949              Comp eq) {
950   // Don't use std::search, use a Boyer-Moore-like trick by comparing
951   // the last characters first
952   auto const nsize = needle.size();
953   if (haystack.size() < nsize) {
954     return std::string::npos;
955   }
956   if (!nsize) return 0;
957   auto const nsize_1 = nsize - 1;
958   auto const lastNeedle = needle[nsize_1];
959
960   // Boyer-Moore skip value for the last char in the needle. Zero is
961   // not a valid value; skip will be computed the first time it's
962   // needed.
963   std::string::size_type skip = 0;
964
965   auto i = haystack.begin();
966   auto iEnd = haystack.end() - nsize_1;
967
968   while (i < iEnd) {
969     // Boyer-Moore: match the last element in the needle
970     while (!eq(i[nsize_1], lastNeedle)) {
971       if (++i == iEnd) {
972         // not found
973         return std::string::npos;
974       }
975     }
976     // Here we know that the last char matches
977     // Continue in pedestrian mode
978     for (size_t j = 0; ; ) {
979       assert(j < nsize);
980       if (!eq(i[j], needle[j])) {
981         // Not found, we can skip
982         // Compute the skip value lazily
983         if (skip == 0) {
984           skip = 1;
985           while (skip <= nsize_1 && !eq(needle[nsize_1 - skip], lastNeedle)) {
986             ++skip;
987           }
988         }
989         i += skip;
990         break;
991       }
992       // Check if done searching
993       if (++j == nsize) {
994         // Yay
995         return i - haystack.begin();
996       }
997     }
998   }
999   return std::string::npos;
1000 }
1001
1002 namespace detail {
1003
1004 inline size_t qfind_first_byte_of(const StringPiece haystack,
1005                                   const StringPiece needles) {
1006   static auto const qfind_first_byte_of_fn =
1007     folly::CpuId().sse42() ? qfind_first_byte_of_sse42
1008                            : qfind_first_byte_of_nosse;
1009   return qfind_first_byte_of_fn(haystack, needles);
1010 }
1011
1012 } // namespace detail
1013
1014 template <class T, class Comp>
1015 size_t qfind_first_of(const Range<T> & haystack,
1016                       const Range<T> & needles,
1017                       Comp eq) {
1018   auto ret = std::find_first_of(haystack.begin(), haystack.end(),
1019                                 needles.begin(), needles.end(),
1020                                 eq);
1021   return ret == haystack.end() ? std::string::npos : ret - haystack.begin();
1022 }
1023
1024 struct AsciiCaseSensitive {
1025   bool operator()(char lhs, char rhs) const {
1026     return lhs == rhs;
1027   }
1028 };
1029
1030 /**
1031  * Check if two ascii characters are case insensitive equal.
1032  * The difference between the lower/upper case characters are the 6-th bit.
1033  * We also check they are alpha chars, in case of xor = 32.
1034  */
1035 struct AsciiCaseInsensitive {
1036   bool operator()(char lhs, char rhs) const {
1037     char k = lhs ^ rhs;
1038     if (k == 0) return true;
1039     if (k != 32) return false;
1040     k = lhs | rhs;
1041     return (k >= 'a' && k <= 'z');
1042   }
1043 };
1044
1045 template <class T>
1046 size_t qfind(const Range<T>& haystack,
1047              const typename Range<T>::value_type& needle) {
1048   auto pos = std::find(haystack.begin(), haystack.end(), needle);
1049   return pos == haystack.end() ? std::string::npos : pos - haystack.data();
1050 }
1051
1052 template <class T>
1053 size_t rfind(const Range<T>& haystack,
1054              const typename Range<T>::value_type& needle) {
1055   for (auto i = haystack.size(); i-- > 0; ) {
1056     if (haystack[i] == needle) {
1057       return i;
1058     }
1059   }
1060   return std::string::npos;
1061 }
1062
1063 // specialization for StringPiece
1064 template <>
1065 inline size_t qfind(const Range<const char*>& haystack, const char& needle) {
1066   auto pos = static_cast<const char*>(
1067     ::memchr(haystack.data(), needle, haystack.size()));
1068   return pos == nullptr ? std::string::npos : pos - haystack.data();
1069 }
1070
1071 #if FOLLY_HAVE_MEMRCHR
1072 template <>
1073 inline size_t rfind(const Range<const char*>& haystack, const char& needle) {
1074   auto pos = static_cast<const char*>(
1075     ::memrchr(haystack.data(), needle, haystack.size()));
1076   return pos == nullptr ? std::string::npos : pos - haystack.data();
1077 }
1078 #endif
1079
1080 // specialization for ByteRange
1081 template <>
1082 inline size_t qfind(const Range<const unsigned char*>& haystack,
1083                     const unsigned char& needle) {
1084   auto pos = static_cast<const unsigned char*>(
1085     ::memchr(haystack.data(), needle, haystack.size()));
1086   return pos == nullptr ? std::string::npos : pos - haystack.data();
1087 }
1088
1089 #if FOLLY_HAVE_MEMRCHR
1090 template <>
1091 inline size_t rfind(const Range<const unsigned char*>& haystack,
1092                     const unsigned char& needle) {
1093   auto pos = static_cast<const unsigned char*>(
1094     ::memrchr(haystack.data(), needle, haystack.size()));
1095   return pos == nullptr ? std::string::npos : pos - haystack.data();
1096 }
1097 #endif
1098
1099 template <class T>
1100 size_t qfind_first_of(const Range<T>& haystack,
1101                       const Range<T>& needles) {
1102   return qfind_first_of(haystack, needles, AsciiCaseSensitive());
1103 }
1104
1105 // specialization for StringPiece
1106 template <>
1107 inline size_t qfind_first_of(const Range<const char*>& haystack,
1108                              const Range<const char*>& needles) {
1109   return detail::qfind_first_byte_of(haystack, needles);
1110 }
1111
1112 // specialization for ByteRange
1113 template <>
1114 inline size_t qfind_first_of(const Range<const unsigned char*>& haystack,
1115                              const Range<const unsigned char*>& needles) {
1116   return detail::qfind_first_byte_of(StringPiece(haystack),
1117                                      StringPiece(needles));
1118 }
1119
1120 template<class Key, class Enable>
1121 struct hasher;
1122
1123 template <class T>
1124 struct hasher<folly::Range<T*>,
1125               typename std::enable_if<std::is_pod<T>::value, void>::type> {
1126   size_t operator()(folly::Range<T*> r) const {
1127     return hash::SpookyHashV2::Hash64(r.begin(), r.size() * sizeof(T), 0);
1128   }
1129 };
1130
1131 }  // !namespace folly
1132
1133 #pragma GCC diagnostic pop
1134
1135 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(folly::Range);
1136
1137 #endif // FOLLY_RANGE_H_