| // Copyright 2021 The PDFium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CORE_FXCRT_SPAN_UTIL_H_ |
| #define CORE_FXCRT_SPAN_UTIL_H_ |
| |
| #include <stdint.h> |
| |
| #include <type_traits> |
| |
| #include "core/fxcrt/fx_memcpy_wrappers.h" |
| #include "third_party/base/check_op.h" |
| #include "third_party/base/containers/span.h" |
| |
| namespace fxcrt { |
| |
| // Bounds-checked byte-for-byte copies from spans into spans. Returns a |
| // span describing the remaining portion of the destination span. |
| template <typename T, |
| typename U, |
| typename = std::enable_if_t<sizeof(T) == sizeof(U) && |
| std::is_trivially_copyable_v<T> && |
| std::is_trivially_copyable_v<U>>> |
| pdfium::span<T> spancpy(pdfium::span<T> dst, pdfium::span<U> src) { |
| CHECK_GE(dst.size(), src.size()); |
| FXSYS_memcpy(dst.data(), src.data(), src.size_bytes()); |
| return dst.subspan(src.size()); |
| } |
| |
| // Bounds-checked byte-for-byte moves from spans into spans. Returns a |
| // span describing the remaining portion of the destination span. |
| template <typename T, |
| typename U, |
| typename = std::enable_if_t<sizeof(T) == sizeof(U) && |
| std::is_trivially_copyable_v<T> && |
| std::is_trivially_copyable_v<U>>> |
| pdfium::span<T> spanmove(pdfium::span<T> dst, pdfium::span<U> src) { |
| CHECK_GE(dst.size(), src.size()); |
| FXSYS_memmove(dst.data(), src.data(), src.size_bytes()); |
| return dst.subspan(src.size()); |
| } |
| |
| // Bounds-checked sets into spans. |
| template <typename T, |
| typename = std::enable_if_t<std::is_trivially_constructible_v<T> && |
| std::is_trivially_destructible_v<T>>> |
| void spanset(pdfium::span<T> dst, uint8_t val) { |
| FXSYS_memset(dst.data(), val, dst.size_bytes()); |
| } |
| |
| // Bounds-checked zeroing of spans. |
| template <typename T, |
| typename = std::enable_if_t<std::is_trivially_constructible_v<T> && |
| std::is_trivially_destructible_v<T>>> |
| void spanclr(pdfium::span<T> dst) { |
| FXSYS_memset(dst.data(), 0, dst.size_bytes()); |
| } |
| |
| // Bounds-checked byte-for-byte equality of same-sized spans. This is |
| // helpful because span does not (yet) have an operator==(). |
| template <typename T, |
| typename U, |
| typename = std::enable_if_t<sizeof(T) == sizeof(U) && |
| std::is_trivially_copyable_v<T> && |
| std::is_trivially_copyable_v<U>>> |
| bool span_equals(pdfium::span<T> s1, pdfium::span<U> s2) { |
| return s1.size_bytes() == s2.size_bytes() && |
| FXSYS_memcmp(s1.data(), s2.data(), s1.size_bytes()) == 0; |
| } |
| |
| template <typename T, |
| typename U, |
| typename = typename std::enable_if_t<std::is_const_v<T> || |
| !std::is_const_v<U>>> |
| inline pdfium::span<T> reinterpret_span(pdfium::span<U> s) noexcept { |
| CHECK_EQ(s.size_bytes() % sizeof(T), 0u); |
| CHECK_EQ(reinterpret_cast<uintptr_t>(s.data()) % alignof(T), 0u); |
| return {reinterpret_cast<T*>(s.data()), s.size_bytes() / sizeof(T)}; |
| } |
| |
| } // namespace fxcrt |
| |
| #endif // CORE_FXCRT_SPAN_UTIL_H_ |