git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / pzstd / utils / Range.h
diff --git a/deps/libchdr/deps/zstd-1.5.5/contrib/pzstd/utils/Range.h b/deps/libchdr/deps/zstd-1.5.5/contrib/pzstd/utils/Range.h
new file mode 100644 (file)
index 0000000..0fd8f9f
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+/**
+ * A subset of `folly/Range.h`.
+ * All code copied verbatim modulo formatting
+ */
+#pragma once
+
+#include "utils/Likely.h"
+#include "utils/Portability.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+
+namespace pzstd {
+
+namespace detail {
+/*
+ *Use IsCharPointer<T>::type to enable const char* or char*.
+ *Use IsCharPointer<T>::const_type to enable only const char*.
+*/
+template <class T>
+struct IsCharPointer {};
+
+template <>
+struct IsCharPointer<char*> {
+  typedef int type;
+};
+
+template <>
+struct IsCharPointer<const char*> {
+  typedef int const_type;
+  typedef int type;
+};
+
+} // namespace detail
+
+template <typename Iter>
+class Range {
+  Iter b_;
+  Iter e_;
+
+ public:
+  using size_type = std::size_t;
+  using iterator = Iter;
+  using const_iterator = Iter;
+  using value_type = typename std::remove_reference<
+      typename std::iterator_traits<Iter>::reference>::type;
+  using reference = typename std::iterator_traits<Iter>::reference;
+
+  constexpr Range() : b_(), e_() {}
+  constexpr Range(Iter begin, Iter end) : b_(begin), e_(end) {}
+
+  constexpr Range(Iter begin, size_type size) : b_(begin), e_(begin + size) {}
+
+  template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
+  /* implicit */ Range(Iter str) : b_(str), e_(str + std::strlen(str)) {}
+
+  template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
+  /* implicit */ Range(const std::string& str)
+      : b_(str.data()), e_(b_ + str.size()) {}
+
+  // Allow implicit conversion from Range<From> to Range<To> if From is
+  // implicitly convertible to To.
+  template <
+      class OtherIter,
+      typename std::enable_if<
+          (!std::is_same<Iter, OtherIter>::value &&
+           std::is_convertible<OtherIter, Iter>::value),
+          int>::type = 0>
+  constexpr /* implicit */ Range(const Range<OtherIter>& other)
+      : b_(other.begin()), e_(other.end()) {}
+
+  Range(const Range&) = default;
+  Range(Range&&) = default;
+
+  Range& operator=(const Range&) = default;
+  Range& operator=(Range&&) = default;
+
+  constexpr size_type size() const {
+    return e_ - b_;
+  }
+  bool empty() const {
+    return b_ == e_;
+  }
+  Iter data() const {
+    return b_;
+  }
+  Iter begin() const {
+    return b_;
+  }
+  Iter end() const {
+    return e_;
+  }
+
+  void advance(size_type n) {
+    if (UNLIKELY(n > size())) {
+      throw std::out_of_range("index out of range");
+    }
+    b_ += n;
+  }
+
+  void subtract(size_type n) {
+    if (UNLIKELY(n > size())) {
+      throw std::out_of_range("index out of range");
+    }
+    e_ -= n;
+  }
+
+  Range subpiece(size_type first, size_type length = std::string::npos) const {
+    if (UNLIKELY(first > size())) {
+      throw std::out_of_range("index out of range");
+    }
+
+    return Range(b_ + first, std::min(length, size() - first));
+  }
+};
+
+using ByteRange = Range<const unsigned char*>;
+using MutableByteRange = Range<unsigned char*>;
+using StringPiece = Range<const char*>;
+}