// 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 #include #include #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 inline void SpanMemcpy(angle::Span dst, angle::Span src) { static_assert(sizeof(T1) == sizeof(T2) && std::is_trivially_copyable_v && std::is_trivially_copyable_v); 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 inline void SpanMemmove(angle::Span dst, angle::Span src) { static_assert(sizeof(T1) == sizeof(T2) && std::is_trivially_copyable_v && std::is_trivially_copyable_v); 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 inline void SpanMemset(angle::Span dst, uint8_t val) { static_assert(std::is_trivially_copyable_v); 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_