MXVK Vulkan Framework 0.35.0
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> class Wrapper {
37 public:
38 /** @brief Default constructor — initialises to nullopt (no value). */
39 Wrapper() = default;
40
41 /**
42 * @brief Construct from a raw pointer.
43 * @param t Pointer to wrap.
44 */
45 Wrapper(T t) : type{t} {}
46
47 /**
48 * @brief Construct in the empty (nullopt) state.
49 * @param nullopt std::nullopt.
50 */
51 Wrapper(std::nullopt_t nullopt) : type{nullopt} {}
52
53 /** @brief Copy constructor. */
54 Wrapper(const Wrapper<T> &) = default;
55
56 /** @brief Move constructor. */
57 Wrapper(Wrapper<T> &&) noexcept = default;
58
59 ~Wrapper() = default;
60
61 /**
62 * @brief Assign from a raw pointer.
63 * @param t Pointer to store.
64 * @return Reference to this.
65 */
66 Wrapper<T> &operator=(T t) {
67 type = t;
68 return *this;
69 }
70
71 /**
72 * @brief Reset to the empty (nullopt) state.
73 * @param nullopt std::nullopt.
74 * @return Reference to this.
75 */
76 Wrapper<T> &operator=(std::nullopt_t nullopt) {
77 type = nullopt;
78 return *this;
79 }
80
81 /** @brief Copy-assign from another Wrapper. */
82 Wrapper<T> &operator=(const Wrapper<T> &) = default;
83
84 /** @brief Move-assign from another Wrapper. */
85 Wrapper<T> &operator=(Wrapper<T> &&) noexcept = default;
86
87 /**
88 * @brief Check whether a non-null value is held.
89 * @return @c true if a non-null pointer is stored.
90 */
91 [[nodiscard]] bool has_value() const noexcept { return type.has_value() && type.value() != nullptr; }
92
93 /** @brief Check if a value is present and non-null. */
94 [[nodiscard]] explicit operator bool() const noexcept { return has_value(); }
95
96 /**
97 * @brief Access the stored pointer without null checking.
98 * @return The stored pointer (may be nullptr if constructed from nullopt).
99 */
100 [[nodiscard]] T value() const { return type.value_or(nullptr); }
101
102 /**
103 * @brief Unwrap with a custom panic message on null.
104 * @param msg Message to include in the thrown mx::Exception.
105 * @return The stored pointer.
106 * @throws mx::Exception if the value is null or absent.
107 */
108 [[nodiscard]] T expect(const std::string &msg) const {
109 if (has_value()) {
110 return type.value();
111 }
112 throw mxvk::Exception(std::format("panic: {}", msg));
113 }
114
115 /**
116 * @brief Unwrap the stored pointer, panicking on null.
117 * @return The stored pointer.
118 * @throws mx::Exception if the value is null or absent.
119 */
120 [[nodiscard]] T unwrap() const {
121 if (has_value()) {
122 return type.value();
123 }
124 throw mxvk::Exception("mxvk panic: Wrapper value is null");
125 }
126
127 /**
128 * @brief Return the stored pointer or a fallback if null.
129 * @param fallback Pointer returned when no value is held.
130 * @return The stored pointer, or @p fallback if null/absent.
131 */
132 [[nodiscard]] T unwrap_or(T fallback) const noexcept {
133 if (has_value()) {
134 return type.value();
135 }
136 return fallback;
137 }
138
139 private:
140 std::optional<T> type = std::nullopt; ///< Internal optional storage.
141 };
142
143} // namespace mxvk
144
145namespace mx {
146 template <mxvk::WrapType T> using Wrapper = mxvk::Wrapper<T>;
147} // 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