blob: a0fc731b83b733726b8ee9820e7f0c6eaf487ad1 [file] [log] [blame] [edit]
// Copyright 2025 The ANGLE Project Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMMON_SPAN_UTIL_H_
#define COMMON_SPAN_UTIL_H_
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "common/base/anglebase/logging.h"
#include "common/span.h"
#include "common/unsafe_buffers.h"
namespace angle
{
// Bounds-checked byte-for-byte copies from spans into spans.
template <typename T1, typename T2, size_t N1, size_t N2>
inline void SpanMemcpy(angle::Span<T1, N1> dst, angle::Span<T2, N2> src)
{
static_assert(sizeof(T1) == sizeof(T2) && std::is_trivially_copyable_v<T1> &&
std::is_trivially_copyable_v<T2>);
CHECK(dst.size() >= src.size());
if (src.size())
{
// SAFETY: static_assert() ensures `sizeof(T1)` equals `sizeof(T2)`, so
// comparing `size()` for equality ensures `size_bytes()` are equal, and
// `size_bytes()` accurately describes `data()`.
ANGLE_UNSAFE_BUFFERS(memcpy(dst.data(), src.data(), src.size_bytes()));
}
}
// Bounds-checked byte-for-byte moves from spans into spans.
template <typename T1, typename T2, size_t N1, size_t N2>
inline void SpanMemmove(angle::Span<T1, N1> dst, angle::Span<T2, N2> src)
{
static_assert(sizeof(T1) == sizeof(T2) && std::is_trivially_copyable_v<T1> &&
std::is_trivially_copyable_v<T2>);
CHECK(dst.size() >= src.size());
if (src.size())
{
// SAFETY: static_assert() ensures `sizeof(T1)` equals `sizeof(T2)`, so
// comparing `size()` for equality ensures `size_bytes()` are equal, and
// `size_bytes()` accurately describes `data()`.
ANGLE_UNSAFE_BUFFERS(memmove(dst.data(), src.data(), src.size_bytes()));
}
}
// Bounds-checked memsets into spans.
template <typename T, size_t N>
inline void SpanMemset(angle::Span<T, N> dst, uint8_t val)
{
static_assert(std::is_trivially_copyable_v<T>);
if (dst.size())
{
// SAFETY: `dst.data()` is valid for `dst.size_bytes()` bytes.
ANGLE_UNSAFE_BUFFERS(memset(dst.data(), val, dst.size_bytes()));
}
}
} // namespace angle
#endif // COMMON_SPAN_UTIL_H_