git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / pzstd / utils / Range.h
CommitLineData
648db22b 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
26namespace pzstd {
27
28namespace 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*/
33template <class T>
34struct IsCharPointer {};
35
36template <>
37struct IsCharPointer<char*> {
38 typedef int type;
39};
40
41template <>
42struct IsCharPointer<const char*> {
43 typedef int const_type;
44 typedef int type;
45};
46
47} // namespace detail
48
49template <typename Iter>
50class 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
130using ByteRange = Range<const unsigned char*>;
131using MutableByteRange = Range<unsigned char*>;
132using StringPiece = Range<const char*>;
133}