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