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