OXYGENHUB
◆ main openmsx / src / utils / optional_fixed_span.hh
1.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
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.
21
template<typename T, size_t N> class optional_fixed_span
22
{
23
public:
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
39
private:
40
	T* ptr = nullptr;
41
};
42
43
#endif