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