git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / pzstd / utils / Range.h
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
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 #include "utils/Portability.h"
18
19 #include <algorithm>
20 #include <cstddef>
21 #include <cstring>
22 #include <stdexcept>
23 #include <string>
24 #include <type_traits>
25
26 namespace pzstd {
27
28 namespace detail {
29 /*
30  *Use IsCharPointer<T>::type to enable const char* or char*.
31  *Use IsCharPointer<T>::const_type to enable only const char*.
32 */
33 template <class T>
34 struct IsCharPointer {};
35
36 template <>
37 struct IsCharPointer<char*> {
38   typedef int type;
39 };
40
41 template <>
42 struct IsCharPointer<const char*> {
43   typedef int const_type;
44   typedef int type;
45 };
46
47 } // namespace detail
48
49 template <typename Iter>
50 class Range {
51   Iter b_;
52   Iter e_;
53
54  public:
55   using size_type = std::size_t;
56   using iterator = Iter;
57   using const_iterator = Iter;
58   using value_type = typename std::remove_reference<
59       typename std::iterator_traits<Iter>::reference>::type;
60   using reference = typename std::iterator_traits<Iter>::reference;
61
62   constexpr Range() : b_(), e_() {}
63   constexpr Range(Iter begin, Iter end) : b_(begin), e_(end) {}
64
65   constexpr Range(Iter begin, size_type size) : b_(begin), e_(begin + size) {}
66
67   template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
68   /* implicit */ Range(Iter str) : b_(str), e_(str + std::strlen(str)) {}
69
70   template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
71   /* implicit */ Range(const std::string& str)
72       : b_(str.data()), e_(b_ + str.size()) {}
73
74   // Allow implicit conversion from Range<From> to Range<To> if From is
75   // implicitly convertible to To.
76   template <
77       class OtherIter,
78       typename std::enable_if<
79           (!std::is_same<Iter, OtherIter>::value &&
80            std::is_convertible<OtherIter, Iter>::value),
81           int>::type = 0>
82   constexpr /* implicit */ Range(const Range<OtherIter>& other)
83       : b_(other.begin()), e_(other.end()) {}
84
85   Range(const Range&) = default;
86   Range(Range&&) = default;
87
88   Range& operator=(const Range&) = default;
89   Range& operator=(Range&&) = default;
90
91   constexpr size_type size() const {
92     return e_ - b_;
93   }
94   bool empty() const {
95     return b_ == e_;
96   }
97   Iter data() const {
98     return b_;
99   }
100   Iter begin() const {
101     return b_;
102   }
103   Iter end() const {
104     return e_;
105   }
106
107   void advance(size_type n) {
108     if (UNLIKELY(n > size())) {
109       throw std::out_of_range("index out of range");
110     }
111     b_ += n;
112   }
113
114   void subtract(size_type n) {
115     if (UNLIKELY(n > size())) {
116       throw std::out_of_range("index out of range");
117     }
118     e_ -= n;
119   }
120
121   Range subpiece(size_type first, size_type length = std::string::npos) const {
122     if (UNLIKELY(first > size())) {
123       throw std::out_of_range("index out of range");
124     }
125
126     return Range(b_ + first, std::min(length, size() - first));
127   }
128 };
129
130 using ByteRange = Range<const unsigned char*>;
131 using MutableByteRange = Range<unsigned char*>;
132 using StringPiece = Range<const char*>;
133 }