blob: 99ae5dedaa4852957c66fa99433af9a528b8847a [file] [log] [blame]
// 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_