xref: /aosp_15_r20/external/zstd/contrib/pzstd/utils/Range.h (revision 01826a4963a0d8a59bc3812d29bdf0fb76416722)
1*01826a49SYabin Cui /*
2*01826a49SYabin Cui  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*01826a49SYabin Cui  * All rights reserved.
4*01826a49SYabin Cui  *
5*01826a49SYabin Cui  * This source code is licensed under both the BSD-style license (found in the
6*01826a49SYabin Cui  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*01826a49SYabin Cui  * in the COPYING file in the root directory of this source tree).
8*01826a49SYabin Cui  */
9*01826a49SYabin Cui 
10*01826a49SYabin Cui /**
11*01826a49SYabin Cui  * A subset of `folly/Range.h`.
12*01826a49SYabin Cui  * All code copied verbatim modulo formatting
13*01826a49SYabin Cui  */
14*01826a49SYabin Cui #pragma once
15*01826a49SYabin Cui 
16*01826a49SYabin Cui #include "utils/Likely.h"
17*01826a49SYabin Cui #include "utils/Portability.h"
18*01826a49SYabin Cui 
19*01826a49SYabin Cui #include <algorithm>
20*01826a49SYabin Cui #include <cstddef>
21*01826a49SYabin Cui #include <cstring>
22*01826a49SYabin Cui #include <stdexcept>
23*01826a49SYabin Cui #include <string>
24*01826a49SYabin Cui #include <type_traits>
25*01826a49SYabin Cui 
26*01826a49SYabin Cui namespace pzstd {
27*01826a49SYabin Cui 
28*01826a49SYabin Cui namespace detail {
29*01826a49SYabin Cui /*
30*01826a49SYabin Cui  *Use IsCharPointer<T>::type to enable const char* or char*.
31*01826a49SYabin Cui  *Use IsCharPointer<T>::const_type to enable only const char*.
32*01826a49SYabin Cui */
33*01826a49SYabin Cui template <class T>
34*01826a49SYabin Cui struct IsCharPointer {};
35*01826a49SYabin Cui 
36*01826a49SYabin Cui template <>
37*01826a49SYabin Cui struct IsCharPointer<char*> {
38*01826a49SYabin Cui   typedef int type;
39*01826a49SYabin Cui };
40*01826a49SYabin Cui 
41*01826a49SYabin Cui template <>
42*01826a49SYabin Cui struct IsCharPointer<const char*> {
43*01826a49SYabin Cui   typedef int const_type;
44*01826a49SYabin Cui   typedef int type;
45*01826a49SYabin Cui };
46*01826a49SYabin Cui 
47*01826a49SYabin Cui } // namespace detail
48*01826a49SYabin Cui 
49*01826a49SYabin Cui template <typename Iter>
50*01826a49SYabin Cui class Range {
51*01826a49SYabin Cui   Iter b_;
52*01826a49SYabin Cui   Iter e_;
53*01826a49SYabin Cui 
54*01826a49SYabin Cui  public:
55*01826a49SYabin Cui   using size_type = std::size_t;
56*01826a49SYabin Cui   using iterator = Iter;
57*01826a49SYabin Cui   using const_iterator = Iter;
58*01826a49SYabin Cui   using value_type = typename std::remove_reference<
59*01826a49SYabin Cui       typename std::iterator_traits<Iter>::reference>::type;
60*01826a49SYabin Cui   using reference = typename std::iterator_traits<Iter>::reference;
61*01826a49SYabin Cui 
62*01826a49SYabin Cui   constexpr Range() : b_(), e_() {}
63*01826a49SYabin Cui   constexpr Range(Iter begin, Iter end) : b_(begin), e_(end) {}
64*01826a49SYabin Cui 
65*01826a49SYabin Cui   constexpr Range(Iter begin, size_type size) : b_(begin), e_(begin + size) {}
66*01826a49SYabin Cui 
67*01826a49SYabin Cui   template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
68*01826a49SYabin Cui   /* implicit */ Range(Iter str) : b_(str), e_(str + std::strlen(str)) {}
69*01826a49SYabin Cui 
70*01826a49SYabin Cui   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
71*01826a49SYabin Cui   /* implicit */ Range(const std::string& str)
72*01826a49SYabin Cui       : b_(str.data()), e_(b_ + str.size()) {}
73*01826a49SYabin Cui 
74*01826a49SYabin Cui   // Allow implicit conversion from Range<From> to Range<To> if From is
75*01826a49SYabin Cui   // implicitly convertible to To.
76*01826a49SYabin Cui   template <
77*01826a49SYabin Cui       class OtherIter,
78*01826a49SYabin Cui       typename std::enable_if<
79*01826a49SYabin Cui           (!std::is_same<Iter, OtherIter>::value &&
80*01826a49SYabin Cui            std::is_convertible<OtherIter, Iter>::value),
81*01826a49SYabin Cui           int>::type = 0>
82*01826a49SYabin Cui   constexpr /* implicit */ Range(const Range<OtherIter>& other)
83*01826a49SYabin Cui       : b_(other.begin()), e_(other.end()) {}
84*01826a49SYabin Cui 
85*01826a49SYabin Cui   Range(const Range&) = default;
86*01826a49SYabin Cui   Range(Range&&) = default;
87*01826a49SYabin Cui 
88*01826a49SYabin Cui   Range& operator=(const Range&) = default;
89*01826a49SYabin Cui   Range& operator=(Range&&) = default;
90*01826a49SYabin Cui 
91*01826a49SYabin Cui   constexpr size_type size() const {
92*01826a49SYabin Cui     return e_ - b_;
93*01826a49SYabin Cui   }
94*01826a49SYabin Cui   bool empty() const {
95*01826a49SYabin Cui     return b_ == e_;
96*01826a49SYabin Cui   }
97*01826a49SYabin Cui   Iter data() const {
98*01826a49SYabin Cui     return b_;
99*01826a49SYabin Cui   }
100*01826a49SYabin Cui   Iter begin() const {
101*01826a49SYabin Cui     return b_;
102*01826a49SYabin Cui   }
103*01826a49SYabin Cui   Iter end() const {
104*01826a49SYabin Cui     return e_;
105*01826a49SYabin Cui   }
106*01826a49SYabin Cui 
107*01826a49SYabin Cui   void advance(size_type n) {
108*01826a49SYabin Cui     if (UNLIKELY(n > size())) {
109*01826a49SYabin Cui       throw std::out_of_range("index out of range");
110*01826a49SYabin Cui     }
111*01826a49SYabin Cui     b_ += n;
112*01826a49SYabin Cui   }
113*01826a49SYabin Cui 
114*01826a49SYabin Cui   void subtract(size_type n) {
115*01826a49SYabin Cui     if (UNLIKELY(n > size())) {
116*01826a49SYabin Cui       throw std::out_of_range("index out of range");
117*01826a49SYabin Cui     }
118*01826a49SYabin Cui     e_ -= n;
119*01826a49SYabin Cui   }
120*01826a49SYabin Cui 
121*01826a49SYabin Cui   Range subpiece(size_type first, size_type length = std::string::npos) const {
122*01826a49SYabin Cui     if (UNLIKELY(first > size())) {
123*01826a49SYabin Cui       throw std::out_of_range("index out of range");
124*01826a49SYabin Cui     }
125*01826a49SYabin Cui 
126*01826a49SYabin Cui     return Range(b_ + first, std::min(length, size() - first));
127*01826a49SYabin Cui   }
128*01826a49SYabin Cui };
129*01826a49SYabin Cui 
130*01826a49SYabin Cui using ByteRange = Range<const unsigned char*>;
131*01826a49SYabin Cui using MutableByteRange = Range<unsigned char*>;
132*01826a49SYabin Cui using StringPiece = Range<const char*>;
133*01826a49SYabin Cui }
134