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