libER 0.1.4.2
ELDEN RING API library
Loading...
Searching...
No Matches
optref.hpp
Go to the documentation of this file.
1
8#pragma once
9
10#include <concepts>
11#include <optional>
12#include <type_traits>
13#include <utility>
14
15namespace liber {
17template <typename T>
18concept not_reference = !std::is_reference_v<T>;
20
29template <typename T>
30 requires not_reference<T>
31struct optref {
36 using value_type = T;
37
42 using reference_type = std::add_lvalue_reference_t<T>;
43
48 using const_reference_type = std::add_const_t<reference_type>;
49
54 using reference_wrapper_type = std::reference_wrapper<value_type>;
55
60 constexpr optref() noexcept : opt(std::nullopt) {}
61
66 constexpr optref(std::nullopt_t) noexcept : opt(std::nullopt) {}
67
72 constexpr optref(const optref& other) noexcept : opt(other.opt) {}
73
80 template <typename U>
81 requires std::convertible_to<U, T>
82 constexpr optref(const optref<U>& other) noexcept
83 : optref([&]() -> optref {
84 if (!other.has_reference())
85 return std::nullopt;
86 return static_cast<reference_type>(other.reference());
87 }()) {}
88
93 constexpr optref(T& reference) noexcept
95
100 constexpr optref(std::reference_wrapper<T> wrapper) noexcept
101 : opt(wrapper) {}
102
107 constexpr optref(T* pointer) noexcept
108 : optref([&]() -> optref {
109 if (!pointer)
110 return std::nullopt;
111 return *pointer;
112 }()) {}
113
120 constexpr bool has_reference() const noexcept {
121 return this->opt.has_value();
122 }
123
130 explicit constexpr operator bool() const noexcept {
131 return static_cast<bool>(this->opt);
132 }
133
142 return this->opt.value();
143 }
144
152 constexpr const_reference_type reference() const {
153 return this->opt.value();
154 }
155
156 // Other std::optional functions
157 // std::optional::operator(s) *,-> and std::optional::value_or aren't
158 // applicable to references Would overload operator . if it was possible
159
165 void swap(optref& other) noexcept {
166 this->opt.swap(other.opt);
167 }
168
173 void reset() noexcept {
174 this->opt.reset();
175 }
176
177private:
178 std::optional<reference_wrapper_type> opt;
179};
180} // namespace liber
A std::optional<std::reference_wrapper<T>> wrapper for lvalue references.
Definition optref.hpp:31
constexpr optref(const optref &other) noexcept
Copy constructor.
Definition optref.hpp:72
constexpr bool has_reference() const noexcept
Does it contain a reference?
Definition optref.hpp:120
constexpr optref(std::nullopt_t) noexcept
Nullopt constructor - no reference.
Definition optref.hpp:66
constexpr optref(std::reference_wrapper< T > wrapper) noexcept
Construct an optref from std::reference_wrapper.
Definition optref.hpp:100
std::add_lvalue_reference_t< T > reference_type
Reference type.
Definition optref.hpp:42
void reset() noexcept
Reset (cannot assign after).
Definition optref.hpp:173
constexpr const_reference_type reference() const
Get the contained const reference; throws if none.
Definition optref.hpp:152
constexpr optref(T &reference) noexcept
Construct an optref from reference.
Definition optref.hpp:93
constexpr optref(const optref< U > &other) noexcept
Converting copy constructor for base/derived class references.
Definition optref.hpp:82
void swap(optref &other) noexcept
Swap implementation.
Definition optref.hpp:165
std::reference_wrapper< value_type > reference_wrapper_type
Reference wrapper type for std::optional.
Definition optref.hpp:54
std::add_const_t< reference_type > const_reference_type
Const reference type.
Definition optref.hpp:48
T value_type
Value type.
Definition optref.hpp:36
constexpr reference_type reference()
Get the contained reference; throws if none.
Definition optref.hpp:141
constexpr optref() noexcept
Default constructor - std::optional contains no reference.
Definition optref.hpp:60
constexpr optref(T *pointer) noexcept
Construct an optref from a pointer.
Definition optref.hpp:107