MXVK Vulkan Framework 0.33.1
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk_wrapper.hpp
Go to the documentation of this file.
1/**
2 * @file mxvk_wrapper.hpp
3 * @brief Type-safe nullable pointer wrapper inspired by Rust's Option<T>.
4 *
5 * Wrapper<T> holds an optional pointer value and provides panic-on-null
6 * accessors similar to Rust's unwrap() / expect() semantics.
7 */
8#pragma once
9
10#include "mxvk_exception.hpp"
11
12#include <format>
13#include <optional>
14#include <string>
15#include <type_traits>
16#include <utility>
17
18namespace mxvk {
19
20 /**
21 * @concept WrapType
22 * @brief Constrains Wrapper<T> to pointer types only.
23 */
24 template <typename T>
25 concept WrapType = std::is_pointer_v<T>;
26
27 /**
28 * @class Wrapper
29 * @brief A nullable smart wrapper around a raw pointer.
30 *
31 * Stores an optional pointer. Accessors throw mx::Exception if the
32 * pointer is null (unwrap, expect) or return a fallback (unwrap_or).
33 *
34 * @tparam T A raw pointer type (must satisfy WrapType concept).
35 */
36 template <WrapType T>
37 class Wrapper {
38 public:
39 /** @brief Default constructor — initialises to nullopt (no value). */
40 Wrapper() = default;
41
42 /**
43 * @brief Construct from a raw pointer.
44 * @param t Pointer to wrap.
45 */
46 Wrapper(T t) : type{t} {}
47
48 /**
49 * @brief Construct in the empty (nullopt) state.
50 * @param nullopt std::nullopt.
51 */
52 Wrapper(std::nullopt_t nullopt) : type{nullopt} {}
53
54 /** @brief Copy constructor. */
55 Wrapper(const Wrapper<T> &) = default;
56
57 /** @brief Move constructor. */
58 Wrapper(Wrapper<T> &&) noexcept = default;
59
60 ~Wrapper() = default;
61
62 /**
63 * @brief Assign from a raw pointer.
64 * @param t Pointer to store.
65 * @return Reference to this.
66 */
67 Wrapper<T> &operator=(T t) {
68 type = t;
69 return *this;
70 }
71
72 /**
73 * @brief Reset to the empty (nullopt) state.
74 * @param nullopt std::nullopt.
75 * @return Reference to this.
76 */
77 Wrapper<T> &operator=(std::nullopt_t nullopt) {
78 type = nullopt;
79 return *this;
80 }
81
82 /** @brief Copy-assign from another Wrapper. */
83 Wrapper<T> &operator=(const Wrapper<T> &) = default;
84
85 /** @brief Move-assign from another Wrapper. */
86 Wrapper<T> &operator=(Wrapper<T> &&) noexcept = default;
87
88 /**
89 * @brief Check whether a non-null value is held.
90 * @return @c true if a non-null pointer is stored.
91 */
92 [[nodiscard]] bool has_value() const noexcept {
93 return type.has_value() && type.value() != nullptr;
94 }
95
96 /** @brief Check if a value is present and non-null. */
97 [[nodiscard]] explicit operator bool() const noexcept { return has_value(); }
98
99 /**
100 * @brief Access the stored pointer without null checking.
101 * @return The stored pointer (may be nullptr if constructed from nullopt).
102 */
103 [[nodiscard]] T value() const { return type.value_or(nullptr); }
104
105 /**
106 * @brief Unwrap with a custom panic message on null.
107 * @param msg Message to include in the thrown mx::Exception.
108 * @return The stored pointer.
109 * @throws mx::Exception if the value is null or absent.
110 */
111 [[nodiscard]] T expect(const std::string &msg) const {
112 if (has_value()) {
113 return type.value();
114 }
115 throw mxvk::Exception(std::format("panic: {}", msg));
116 }
117
118 /**
119 * @brief Unwrap the stored pointer, panicking on null.
120 * @return The stored pointer.
121 * @throws mx::Exception if the value is null or absent.
122 */
123 [[nodiscard]] T unwrap() const {
124 if (has_value()) {
125 return type.value();
126 }
127 throw mxvk::Exception("mxvk panic: Wrapper value is null");
128 }
129
130 /**
131 * @brief Return the stored pointer or a fallback if null.
132 * @param fallback Pointer returned when no value is held.
133 * @return The stored pointer, or @p fallback if null/absent.
134 */
135 [[nodiscard]] T unwrap_or(T fallback) const noexcept {
136 if (has_value()) {
137 return type.value();
138 }
139 return fallback;
140 }
141
142 private:
143 std::optional<T> type = std::nullopt; ///< Internal optional storage.
144 };
145
146} // namespace mxvk
147
148namespace mx {
149 template <mxvk::WrapType T>
151} // namespace mx
A nullable smart wrapper around a raw pointer.
Wrapper(Wrapper< T > &&) noexcept=default
Move constructor.
T value() const
Access the stored pointer without null checking.
T unwrap() const
Unwrap the stored pointer, panicking on null.
Wrapper()=default
Default constructor — initialises to nullopt (no value).
Wrapper(std::nullopt_t nullopt)
Construct in the empty (nullopt) state.
Wrapper< T > & operator=(const Wrapper< T > &)=default
Copy-assign from another Wrapper.
T unwrap_or(T fallback) const noexcept
Return the stored pointer or a fallback if null.
Wrapper(const Wrapper< T > &)=default
Copy constructor.
T expect(const std::string &msg) const
Unwrap with a custom panic message on null.
Wrapper< T > & operator=(std::nullopt_t nullopt)
Reset to the empty (nullopt) state.
Wrapper< T > & operator=(Wrapper< T > &&) noexcept=default
Move-assign from another Wrapper.
bool has_value() const noexcept
Check whether a non-null value is held.
Wrapper(T t)
Construct from a raw pointer.
Constrains Wrapper<T> to pointer types only.
mxvk::Wrapper< T > Wrapper
Utilities for loading and saving PNG images.
Definition mxvk.hpp:31