Add mechanizm for caching local and peer addresses in AsyncSSLSocket.
[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 items in [b, e), as long as this subrange is at the beginning
599    * or end of the Range.
600    *
601    * Required for boost::algorithm::trim()
602    */
603   void erase(Iter b, Iter e) {
604     if (b == b_) {
605       b_ = e;
606     } else if (e == e_) {
607       e_ = b;
608     } else {
609       throw std::out_of_range("index out of range");
610     }
611   }
612
613   /**
614    * Remove the given prefix and return true if the range starts with the given
615    * prefix; return false otherwise.
616    */
617   bool removePrefix(const const_range_type& prefix) {
618     return startsWith(prefix) && (b_ += prefix.size(), true);
619   }
620   bool removePrefix(value_type prefix) {
621     return startsWith(prefix) && (++b_, true);
622   }
623
624   /**
625    * Remove the given suffix and return true if the range ends with the given
626    * suffix; return false otherwise.
627    */
628   bool removeSuffix(const const_range_type& suffix) {
629     return endsWith(suffix) && (e_ -= suffix.size(), true);
630   }
631   bool removeSuffix(value_type suffix) {
632     return endsWith(suffix) && (--e_, true);
633   }
634
635   /**
636    * Replaces the content of the range, starting at position 'pos', with
637    * contents of 'replacement'. Entire 'replacement' must fit into the
638    * range. Returns false if 'replacements' does not fit. Example use:
639    *
640    * char in[] = "buffer";
641    * auto msp = MutablesStringPiece(input);
642    * EXPECT_TRUE(msp.replaceAt(2, "tt"));
643    * EXPECT_EQ(msp, "butter");
644    *
645    * // not enough space
646    * EXPECT_FALSE(msp.replace(msp.size() - 1, "rr"));
647    * EXPECT_EQ(msp, "butter"); // unchanged
648    */
649   bool replaceAt(size_t pos, const_range_type replacement) {
650     if (size() < pos + replacement.size()) {
651       return false;
652     }
653
654     std::copy(replacement.begin(), replacement.end(), begin() + pos);
655
656     return true;
657   }
658
659   /**
660    * Replaces all occurences of 'source' with 'dest'. Returns number
661    * of replacements made. Source and dest have to have the same
662    * length. Throws if the lengths are different. If 'source' is a
663    * pattern that is overlapping with itself, we perform sequential
664    * replacement: "aaaaaaa".replaceAll("aa", "ba") --> "bababaa"
665    *
666    * Example use:
667    *
668    * char in[] = "buffer";
669    * auto msp = MutablesStringPiece(input);
670    * EXPECT_EQ(msp.replaceAll("ff","tt"), 1);
671    * EXPECT_EQ(msp, "butter");
672    */
673   size_t replaceAll(const_range_type source, const_range_type dest) {
674     if (source.size() != dest.size()) {
675       throw std::invalid_argument(
676           "replacement must have the same size as source");
677     }
678
679     if (dest.empty()) {
680       return 0;
681     }
682
683     size_t pos = 0;
684     size_t num_replaced = 0;
685     size_type found = std::string::npos;
686     while ((found = find(source, pos)) != std::string::npos) {
687       replaceAt(found, dest);
688       pos += source.size();
689       ++num_replaced;
690     }
691
692     return num_replaced;
693   }
694
695   /**
696    * Splits this `Range` `[b, e)` in the position `i` dictated by the next
697    * occurence of `delimiter`.
698    *
699    * Returns a new `Range` `[b, i)` and adjusts this range to start right after
700    * the delimiter's position. This range will be empty if the delimiter is not
701    * found. If called on an empty `Range`, both this and the returned `Range`
702    * will be empty.
703    *
704    * Example:
705    *
706    *  folly::StringPiece s("sample string for split_next");
707    *  auto p = s.split_step(' ');
708    *
709    *  // prints "string for split_next"
710    *  cout << s << endl;
711    *
712    *  // prints "sample"
713    *  cout << p << endl;
714    *
715    * Example 2:
716    *
717    *  void tokenize(StringPiece s, char delimiter) {
718    *    while (!s.empty()) {
719    *      cout << s.split_step(delimiter);
720    *    }
721    *  }
722    *
723    * @author: Marcelo Juchem <marcelo@fb.com>
724    */
725   Range split_step(value_type delimiter) {
726     auto i = std::find(b_, e_, delimiter);
727     Range result(b_, i);
728
729     b_ = i == e_ ? e_ : std::next(i);
730
731     return result;
732   }
733
734   Range split_step(Range delimiter) {
735     auto i = find(delimiter);
736     Range result(b_, i == std::string::npos ? size() : i);
737
738     b_ = result.end() == e_ ? e_ : std::next(result.end(), delimiter.size());
739
740     return result;
741   }
742
743   /**
744    * Convenience method that calls `split_step()` and passes the result to a
745    * functor, returning whatever the functor does. Any additional arguments
746    * `args` passed to this function are perfectly forwarded to the functor.
747    *
748    * Say you have a functor with this signature:
749    *
750    *  Foo fn(Range r) { }
751    *
752    * `split_step()`'s return type will be `Foo`. It works just like:
753    *
754    *  auto result = fn(myRange.split_step(' '));
755    *
756    * A functor returning `void` is also supported.
757    *
758    * Example:
759    *
760    *  void do_some_parsing(folly::StringPiece s) {
761    *    auto version = s.split_step(' ', [&](folly::StringPiece x) {
762    *      if (x.empty()) {
763    *        throw std::invalid_argument("empty string");
764    *      }
765    *      return std::strtoull(x.begin(), x.end(), 16);
766    *    });
767    *
768    *    // ...
769    *  }
770    *
771    *  struct Foo {
772    *    void parse(folly::StringPiece s) {
773    *      s.split_step(' ', parse_field, bar, 10);
774    *      s.split_step('\t', parse_field, baz, 20);
775    *
776    *      auto const kludge = [](folly::StringPiece x, int &out, int def) {
777    *        if (x == "null") {
778    *          out = 0;
779    *        } else {
780    *          parse_field(x, out, def);
781    *        }
782    *      };
783    *
784    *      s.split_step('\t', kludge, gaz);
785    *      s.split_step(' ', kludge, foo);
786    *    }
787    *
788    *  private:
789    *    int bar;
790    *    int baz;
791    *    int gaz;
792    *    int foo;
793    *
794    *    static parse_field(folly::StringPiece s, int &out, int def) {
795    *      try {
796    *        out = folly::to<int>(s);
797    *      } catch (std::exception const &) {
798    *        value = def;
799    *      }
800    *    }
801    *  };
802    *
803    * @author: Marcelo Juchem <marcelo@fb.com>
804    */
805   template <typename TProcess, typename... Args>
806   auto split_step(value_type delimiter, TProcess &&process, Args &&...args)
807     -> decltype(process(std::declval<Range>(), std::forward<Args>(args)...))
808   { return process(split_step(delimiter), std::forward<Args>(args)...); }
809
810   template <typename TProcess, typename... Args>
811   auto split_step(Range delimiter, TProcess &&process, Args &&...args)
812     -> decltype(process(std::declval<Range>(), std::forward<Args>(args)...))
813   { return process(split_step(delimiter), std::forward<Args>(args)...); }
814
815 private:
816   Iter b_, e_;
817 };
818
819 template <class Iter>
820 const typename Range<Iter>::size_type Range<Iter>::npos = std::string::npos;
821
822 template <class T>
823 void swap(Range<T>& lhs, Range<T>& rhs) {
824   lhs.swap(rhs);
825 }
826
827 /**
828  * Create a range from two iterators, with type deduction.
829  */
830 template <class Iter>
831 Range<Iter> range(Iter first, Iter last) {
832   return Range<Iter>(first, last);
833 }
834
835 /*
836  * Creates a range to reference the contents of a contiguous-storage container.
837  */
838 // Use pointers for types with '.data()' member
839 template <class Collection,
840           class T = typename std::remove_pointer<
841               decltype(std::declval<Collection>().data())>::type>
842 Range<T*> range(Collection&& v) {
843   return Range<T*>(v.data(), v.data() + v.size());
844 }
845
846 template <class T, size_t n>
847 Range<T*> range(T (&array)[n]) {
848   return Range<T*>(array, array + n);
849 }
850
851 typedef Range<const char*> StringPiece;
852 typedef Range<char*> MutableStringPiece;
853 typedef Range<const unsigned char*> ByteRange;
854 typedef Range<unsigned char*> MutableByteRange;
855
856 inline std::ostream& operator<<(std::ostream& os,
857                                 const StringPiece piece) {
858   os.write(piece.start(), piece.size());
859   return os;
860 }
861
862 inline std::ostream& operator<<(std::ostream& os,
863                                 const MutableStringPiece piece) {
864   os.write(piece.start(), piece.size());
865   return os;
866 }
867
868 /**
869  * Templated comparison operators
870  */
871
872 template <class T>
873 inline bool operator==(const Range<T>& lhs, const Range<T>& rhs) {
874   return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
875 }
876
877 template <class T>
878 inline bool operator<(const Range<T>& lhs, const Range<T>& rhs) {
879   return lhs.compare(rhs) < 0;
880 }
881
882 /**
883  * Specializations of comparison operators for StringPiece
884  */
885
886 namespace detail {
887
888 template <class A, class B>
889 struct ComparableAsStringPiece {
890   enum {
891     value =
892     (std::is_convertible<A, StringPiece>::value
893      && std::is_same<B, StringPiece>::value)
894     ||
895     (std::is_convertible<B, StringPiece>::value
896      && std::is_same<A, StringPiece>::value)
897   };
898 };
899
900 } // namespace detail
901
902 /**
903  * operator== through conversion for Range<const char*>
904  */
905 template <class T, class U>
906 typename
907 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
908 operator==(const T& lhs, const U& rhs) {
909   return StringPiece(lhs) == StringPiece(rhs);
910 }
911
912 /**
913  * operator< through conversion for Range<const char*>
914  */
915 template <class T, class U>
916 typename
917 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
918 operator<(const T& lhs, const U& rhs) {
919   return StringPiece(lhs) < StringPiece(rhs);
920 }
921
922 /**
923  * operator> through conversion for Range<const char*>
924  */
925 template <class T, class U>
926 typename
927 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
928 operator>(const T& lhs, const U& rhs) {
929   return StringPiece(lhs) > StringPiece(rhs);
930 }
931
932 /**
933  * operator< through conversion for Range<const char*>
934  */
935 template <class T, class U>
936 typename
937 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
938 operator<=(const T& lhs, const U& rhs) {
939   return StringPiece(lhs) <= StringPiece(rhs);
940 }
941
942 /**
943  * operator> through conversion for Range<const char*>
944  */
945 template <class T, class U>
946 typename
947 std::enable_if<detail::ComparableAsStringPiece<T, U>::value, bool>::type
948 operator>=(const T& lhs, const U& rhs) {
949   return StringPiece(lhs) >= StringPiece(rhs);
950 }
951
952 // Do NOT use this, use SpookyHashV2 instead, see commment on hash() above.
953 struct StringPieceHash {
954   std::size_t operator()(const StringPiece str) const {
955     return static_cast<std::size_t>(str.hash());
956   }
957 };
958
959 /**
960  * Finds substrings faster than brute force by borrowing from Boyer-Moore
961  */
962 template <class T, class Comp>
963 size_t qfind(const Range<T>& haystack,
964              const Range<T>& needle,
965              Comp eq) {
966   // Don't use std::search, use a Boyer-Moore-like trick by comparing
967   // the last characters first
968   auto const nsize = needle.size();
969   if (haystack.size() < nsize) {
970     return std::string::npos;
971   }
972   if (!nsize) return 0;
973   auto const nsize_1 = nsize - 1;
974   auto const lastNeedle = needle[nsize_1];
975
976   // Boyer-Moore skip value for the last char in the needle. Zero is
977   // not a valid value; skip will be computed the first time it's
978   // needed.
979   std::string::size_type skip = 0;
980
981   auto i = haystack.begin();
982   auto iEnd = haystack.end() - nsize_1;
983
984   while (i < iEnd) {
985     // Boyer-Moore: match the last element in the needle
986     while (!eq(i[nsize_1], lastNeedle)) {
987       if (++i == iEnd) {
988         // not found
989         return std::string::npos;
990       }
991     }
992     // Here we know that the last char matches
993     // Continue in pedestrian mode
994     for (size_t j = 0; ; ) {
995       assert(j < nsize);
996       if (!eq(i[j], needle[j])) {
997         // Not found, we can skip
998         // Compute the skip value lazily
999         if (skip == 0) {
1000           skip = 1;
1001           while (skip <= nsize_1 && !eq(needle[nsize_1 - skip], lastNeedle)) {
1002             ++skip;
1003           }
1004         }
1005         i += skip;
1006         break;
1007       }
1008       // Check if done searching
1009       if (++j == nsize) {
1010         // Yay
1011         return i - haystack.begin();
1012       }
1013     }
1014   }
1015   return std::string::npos;
1016 }
1017
1018 namespace detail {
1019
1020 inline size_t qfind_first_byte_of(const StringPiece haystack,
1021                                   const StringPiece needles) {
1022   static auto const qfind_first_byte_of_fn =
1023     folly::CpuId().sse42() ? qfind_first_byte_of_sse42
1024                            : qfind_first_byte_of_nosse;
1025   return qfind_first_byte_of_fn(haystack, needles);
1026 }
1027
1028 } // namespace detail
1029
1030 template <class T, class Comp>
1031 size_t qfind_first_of(const Range<T> & haystack,
1032                       const Range<T> & needles,
1033                       Comp eq) {
1034   auto ret = std::find_first_of(haystack.begin(), haystack.end(),
1035                                 needles.begin(), needles.end(),
1036                                 eq);
1037   return ret == haystack.end() ? std::string::npos : ret - haystack.begin();
1038 }
1039
1040 struct AsciiCaseSensitive {
1041   bool operator()(char lhs, char rhs) const {
1042     return lhs == rhs;
1043   }
1044 };
1045
1046 /**
1047  * Check if two ascii characters are case insensitive equal.
1048  * The difference between the lower/upper case characters are the 6-th bit.
1049  * We also check they are alpha chars, in case of xor = 32.
1050  */
1051 struct AsciiCaseInsensitive {
1052   bool operator()(char lhs, char rhs) const {
1053     char k = lhs ^ rhs;
1054     if (k == 0) return true;
1055     if (k != 32) return false;
1056     k = lhs | rhs;
1057     return (k >= 'a' && k <= 'z');
1058   }
1059 };
1060
1061 template <class T>
1062 size_t qfind(const Range<T>& haystack,
1063              const typename Range<T>::value_type& needle) {
1064   auto pos = std::find(haystack.begin(), haystack.end(), needle);
1065   return pos == haystack.end() ? std::string::npos : pos - haystack.data();
1066 }
1067
1068 template <class T>
1069 size_t rfind(const Range<T>& haystack,
1070              const typename Range<T>::value_type& needle) {
1071   for (auto i = haystack.size(); i-- > 0; ) {
1072     if (haystack[i] == needle) {
1073       return i;
1074     }
1075   }
1076   return std::string::npos;
1077 }
1078
1079 // specialization for StringPiece
1080 template <>
1081 inline size_t qfind(const Range<const char*>& haystack, const char& needle) {
1082   auto pos = static_cast<const char*>(
1083     ::memchr(haystack.data(), needle, haystack.size()));
1084   return pos == nullptr ? std::string::npos : pos - haystack.data();
1085 }
1086
1087 #if FOLLY_HAVE_MEMRCHR
1088 template <>
1089 inline size_t rfind(const Range<const char*>& haystack, const char& needle) {
1090   auto pos = static_cast<const char*>(
1091     ::memrchr(haystack.data(), needle, haystack.size()));
1092   return pos == nullptr ? std::string::npos : pos - haystack.data();
1093 }
1094 #endif
1095
1096 // specialization for ByteRange
1097 template <>
1098 inline size_t qfind(const Range<const unsigned char*>& haystack,
1099                     const unsigned char& needle) {
1100   auto pos = static_cast<const unsigned char*>(
1101     ::memchr(haystack.data(), needle, haystack.size()));
1102   return pos == nullptr ? std::string::npos : pos - haystack.data();
1103 }
1104
1105 #if FOLLY_HAVE_MEMRCHR
1106 template <>
1107 inline size_t rfind(const Range<const unsigned char*>& haystack,
1108                     const unsigned char& needle) {
1109   auto pos = static_cast<const unsigned char*>(
1110     ::memrchr(haystack.data(), needle, haystack.size()));
1111   return pos == nullptr ? std::string::npos : pos - haystack.data();
1112 }
1113 #endif
1114
1115 template <class T>
1116 size_t qfind_first_of(const Range<T>& haystack,
1117                       const Range<T>& needles) {
1118   return qfind_first_of(haystack, needles, AsciiCaseSensitive());
1119 }
1120
1121 // specialization for StringPiece
1122 template <>
1123 inline size_t qfind_first_of(const Range<const char*>& haystack,
1124                              const Range<const char*>& needles) {
1125   return detail::qfind_first_byte_of(haystack, needles);
1126 }
1127
1128 // specialization for ByteRange
1129 template <>
1130 inline size_t qfind_first_of(const Range<const unsigned char*>& haystack,
1131                              const Range<const unsigned char*>& needles) {
1132   return detail::qfind_first_byte_of(StringPiece(haystack),
1133                                      StringPiece(needles));
1134 }
1135
1136 template<class Key, class Enable>
1137 struct hasher;
1138
1139 template <class T>
1140 struct hasher<folly::Range<T*>,
1141               typename std::enable_if<std::is_pod<T>::value, void>::type> {
1142   size_t operator()(folly::Range<T*> r) const {
1143     return hash::SpookyHashV2::Hash64(r.begin(), r.size() * sizeof(T), 0);
1144   }
1145 };
1146
1147 }  // !namespace folly
1148
1149 #pragma GCC diagnostic pop
1150
1151 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(folly::Range);
1152
1153 #endif // FOLLY_RANGE_H_