aboutsummaryrefslogtreecommitdiff
path: root/src/deps/skia/include/core/SkSpan.h
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-04-03 16:34:10 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-04-03 16:34:10 -0700
commita87508008dfa1604baf2d4e39bf44704c00f261c (patch)
tree0be2ade96772037a02803b30e157c367d931e3d9 /src/deps/skia/include/core/SkSpan.h
parent4a19a3f07f1887903e5638a3be167f0c7b377ba3 (diff)
downloadbun-jarred/canvas.tar.gz
bun-jarred/canvas.tar.zst
bun-jarred/canvas.zip
Diffstat (limited to 'src/deps/skia/include/core/SkSpan.h')
-rw-r--r--src/deps/skia/include/core/SkSpan.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/deps/skia/include/core/SkSpan.h b/src/deps/skia/include/core/SkSpan.h
new file mode 100644
index 000000000..b09ec867a
--- /dev/null
+++ b/src/deps/skia/include/core/SkSpan.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSpan_DEFINED
+#define SkSpan_DEFINED
+
+#include <cstddef>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+#include "include/private/SkTLogic.h"
+
+/**
+ * An SkSpan is a view of a contiguous collection of elements of type T. It can be directly
+ * constructed from a pointer and size. SkMakeSpan can be used to construct one from an array,
+ * or a container (like std::vector).
+ *
+ * With C++17, we could add template deduction guides that eliminate the need for SkMakeSpan:
+ * https://skia-review.googlesource.com/c/skia/+/320264
+ */
+template <typename T>
+class SkSpan {
+public:
+ constexpr SkSpan() : fPtr{nullptr}, fSize{0} {}
+ constexpr SkSpan(T* ptr, size_t size) : fPtr{ptr}, fSize{size} {
+ SkASSERT(size < kMaxSize);
+ }
+ template <typename U, typename = typename std::enable_if<std::is_same<const U, T>::value>::type>
+ constexpr SkSpan(const SkSpan<U>& that) : fPtr(that.data()), fSize{that.size()} {}
+ constexpr SkSpan(const SkSpan& o) = default;
+
+ constexpr SkSpan& operator=(const SkSpan& that) {
+ fPtr = that.fPtr;
+ fSize = that.fSize;
+ return *this;
+ }
+ constexpr T& operator [] (size_t i) const {
+ SkASSERT(i < this->size());
+ return fPtr[i];
+ }
+ constexpr T& front() const { return fPtr[0]; }
+ constexpr T& back() const { return fPtr[fSize - 1]; }
+ constexpr T* begin() const { return fPtr; }
+ constexpr T* end() const { return fPtr + fSize; }
+ constexpr auto rbegin() const { return std::make_reverse_iterator(this->end()); }
+ constexpr auto rend() const { return std::make_reverse_iterator(this->begin()); }
+ constexpr T* data() const { return this->begin(); }
+ constexpr size_t size() const { return fSize; }
+ constexpr bool empty() const { return fSize == 0; }
+ constexpr size_t size_bytes() const { return fSize * sizeof(T); }
+ constexpr SkSpan<T> first(size_t prefixLen) const {
+ SkASSERT(prefixLen <= this->size());
+ return SkSpan{fPtr, prefixLen};
+ }
+ constexpr SkSpan<T> last(size_t postfixLen) const {
+ SkASSERT(postfixLen <= this->size());
+ return SkSpan{fPtr + (this->size() - postfixLen), postfixLen};
+ }
+ constexpr SkSpan<T> subspan(size_t offset, size_t count) const {
+ SkASSERT(offset <= this->size());
+ SkASSERT(count <= this->size() - offset);
+ return SkSpan{fPtr + offset, count};
+ }
+
+private:
+ static constexpr size_t kMaxSize = std::numeric_limits<size_t>::max() / sizeof(T);
+ T* fPtr;
+ size_t fSize;
+};
+
+template <typename T, typename S> inline constexpr SkSpan<T> SkMakeSpan(T* p, S s) {
+ return SkSpan<T>{p, SkTo<size_t>(s)};
+}
+
+template <size_t N, typename T> inline constexpr SkSpan<T> SkMakeSpan(T (&a)[N]) {
+ return SkSpan<T>{a, N};
+}
+
+template <typename Container>
+inline auto SkMakeSpan(Container& c)
+ -> SkSpan<typename std::remove_reference<decltype(*(c.data()))>::type> {
+ return {c.data(), c.size()};
+}
+
+#endif // SkSpan_DEFINED