openMSX
optional_fixed_span.hh
Go to the documentation of this file.
1#ifndef OPTIONAL_FIXED_SPAN_HH
2#define OPTIONAL_FIXED_SPAN_HH
3
4#include <optional>
5#include <span>
6
7// This class acts like std::optional<std::span<T, N>>, but only stores a single
8// pointer (which can be nullptr). A plain std::span<T, N> is not sufficient
9// because it cannot represent an invalid state (nullptr). This class provides
10// a lightweight way to optionally hold a fixed-size span without the overhead
11// of std::optional.
12//
13// An alternative could be to use a plain pointer (T*). Though that doesn't give
14// the guarantee that it points to N elements. This class enforces that on
15// construction, and retains that information on usage.
16//
17// In the past we tried to use std::span<T, N> initialized with
18// std::span<T, N>(static_cast<T*>(nullptr), N)
19// That appeared to work, but it's actually undefined behavior. And with gcc
20// debug STL mode it indeed triggers an error.
21template<typename T, size_t N> class optional_fixed_span
22{
23public:
24 // Constructor for invalid state
25 constexpr optional_fixed_span() noexcept = default;
26
27 // Constructor for valid state
28 constexpr optional_fixed_span(std::span<T, N> span) noexcept
29 : ptr(span.data()) {}
30
31 // Named function to get optional span
32 [[nodiscard]] constexpr std::optional<std::span<T, N>> asOptional() const noexcept {
33 if (ptr) {
34 return std::span<T, N>(ptr, N);
35 }
36 return {};
37 }
38
39private:
40 T* ptr = nullptr;
41};
42
43#endif
constexpr optional_fixed_span() noexcept=default
constexpr std::optional< std::span< T, N > > asOptional() const noexcept
STL namespace.