util/{Const,Writable}Buffer: add std::span cast operators

This commit is contained in:
Max Kellermann 2022-05-10 08:49:21 +02:00 committed by Max Kellermann
parent fc6c274c97
commit 957d3e51e0
2 changed files with 70 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2021 Max Kellermann <max.kellermann@gmail.com> * Copyright 2013-2022 Max Kellermann <max.kellermann@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -27,12 +27,19 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef CONST_BUFFER_HXX #pragma once
#define CONST_BUFFER_HXX
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#if __cplusplus >= 202002 || (defined(__GNUC__) && __GNUC__ >= 10)
#include <version>
#endif
#ifdef __cpp_lib_span
#include <span>
#endif
template<typename T> template<typename T>
struct ConstBuffer; struct ConstBuffer;
@ -56,6 +63,11 @@ struct ConstBuffer<void> {
constexpr ConstBuffer(pointer _data, size_type _size) noexcept constexpr ConstBuffer(pointer _data, size_type _size) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
#ifdef __cpp_lib_span
constexpr ConstBuffer(std::span<const std::byte> s) noexcept
:data(s.data()), size(s.size()) {}
#endif
constexpr static ConstBuffer<void> FromVoid(ConstBuffer<void> other) noexcept { constexpr static ConstBuffer<void> FromVoid(ConstBuffer<void> other) noexcept {
return other; return other;
} }
@ -79,6 +91,12 @@ struct ConstBuffer<void> {
constexpr bool empty() const noexcept { constexpr bool empty() const noexcept {
return size == 0; return size == 0;
} }
#ifdef __cpp_lib_span
constexpr operator std::span<const std::byte>() const noexcept {
return {static_cast<const std::byte *>(data), size};
}
#endif
}; };
/** /**
@ -116,6 +134,11 @@ struct ConstBuffer {
constexpr ConstBuffer(const T (&_data)[_size]) noexcept constexpr ConstBuffer(const T (&_data)[_size]) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
#ifdef __cpp_lib_span
constexpr ConstBuffer(std::span<const T> s) noexcept
:data(s.data()), size(s.size()) {}
#endif
/** /**
* Cast a ConstBuffer<void> to a ConstBuffer<T>, rounding down * Cast a ConstBuffer<void> to a ConstBuffer<T>, rounding down
* to the next multiple of T's size. * to the next multiple of T's size.
@ -268,6 +291,10 @@ struct ConstBuffer {
size = new_end - data; size = new_end - data;
} }
};
#ifdef __cpp_lib_span
constexpr operator std::span<const T>() const noexcept {
return {data, size};
}
#endif #endif
};

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2021 Max Kellermann <max.kellermann@gmail.com> * Copyright 2013-2022 Max Kellermann <max.kellermann@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -27,14 +27,21 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef WRITABLE_BUFFER_HXX #pragma once
#define WRITABLE_BUFFER_HXX
#include "ConstBuffer.hxx" #include "ConstBuffer.hxx"
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#if __cplusplus >= 202002 || (defined(__GNUC__) && __GNUC__ >= 10)
#include <version>
#endif
#ifdef __cpp_lib_span
#include <span>
#endif
template<typename T> template<typename T>
struct WritableBuffer; struct WritableBuffer;
@ -58,6 +65,11 @@ struct WritableBuffer<void> {
constexpr WritableBuffer(pointer _data, size_type _size) noexcept constexpr WritableBuffer(pointer _data, size_type _size) noexcept
:data(_data), size(_size) {} :data(_data), size(_size) {}
#ifdef __cpp_lib_span
constexpr WritableBuffer(std::span<std::byte> s) noexcept
:data(s.data()), size(s.size()) {}
#endif
constexpr static WritableBuffer<void> FromVoid(WritableBuffer<void> other) noexcept { constexpr static WritableBuffer<void> FromVoid(WritableBuffer<void> other) noexcept {
return other; return other;
} }
@ -85,6 +97,16 @@ struct WritableBuffer<void> {
constexpr bool empty() const noexcept { constexpr bool empty() const noexcept {
return size == 0; return size == 0;
} }
#ifdef __cpp_lib_span
constexpr operator std::span<std::byte>() const noexcept {
return {static_cast<std::byte *>(data), size};
}
constexpr operator std::span<const std::byte>() const noexcept {
return {static_cast<const std::byte *>(data), size};
}
#endif
}; };
/** /**
@ -117,6 +139,11 @@ struct WritableBuffer {
constexpr WritableBuffer(pointer _data, pointer _end) noexcept constexpr WritableBuffer(pointer _data, pointer _end) noexcept
:data(_data), size(_end - _data) {} :data(_data), size(_end - _data) {}
#ifdef __cpp_lib_span
constexpr WritableBuffer(std::span<T> s) noexcept
:data(s.data()), size(s.size()) {}
#endif
/** /**
* Convert array to WritableBuffer instance. * Convert array to WritableBuffer instance.
*/ */
@ -271,6 +298,14 @@ struct WritableBuffer {
size = new_end - data; size = new_end - data;
} }
};
#ifdef __cpp_lib_span
constexpr operator std::span<T>() const noexcept {
return {data, size};
}
constexpr operator std::span<const T>() const noexcept {
return {data, size};
}
#endif #endif
};