sandbox
Loading...
Searching...
No Matches
optional_ref.hpp
1#ifndef LIBSBX_MEMORY_OPTIONAL_REF_HPP_
2#define LIBSBX_MEMORY_OPTIONAL_REF_HPP_
3
4namespace sbx::memory {
5
6template<typename Type>
8
9public:
10
11 using value_type = Type;
12
13 constexpr optional_ref() noexcept
14 : _pointer{nullptr} {}
15
16 constexpr optional_ref(value_type& value) noexcept
17 : _pointer{std::addressof(value)} {}
18
19 constexpr optional_ref(std::nullopt_t) noexcept
20 : _pointer{nullptr} {}
21
22 optional_ref(value_type&&) = delete;
23
24 optional_ref(value_type*) = delete;
25
26 auto operator=(value_type& value) noexcept -> optional_ref& {
27 _pointer = std::addressof(value);
28 return *this;
29 }
30
31 auto operator=(std::nullopt_t) noexcept -> optional_ref& {
32 _pointer = nullptr;
33 return *this;
34 }
35
36 auto operator=(value_type*) -> optional_ref& = delete;
37
38 [[nodiscard]] auto has_value() const noexcept -> bool {
39 return _pointer != nullptr;
40 }
41
42 explicit operator bool() const noexcept {
43 return has_value();
44 }
45
46 [[nodiscard]] auto value() const -> Type& {
47 if (!_pointer) {
48 throw std::bad_optional_access{};
49 }
50
51 return *_pointer;
52 }
53
54 [[nodiscard]] auto operator*() const noexcept -> Type& {
55 return *_pointer;
56 }
57
58 [[nodiscard]] auto operator->() const noexcept -> Type* {
59 return _pointer;
60 }
61
62 template<typename U>
63 [[nodiscard]] auto value_or(U&& fallback) const noexcept -> Type& {
64 return _pointer ? *_pointer : static_cast<Type&>(fallback);
65 }
66
67 auto reset() noexcept -> void {
68 _pointer = nullptr;
69 }
70
71private:
72
73 Type* _pointer;
74
75}; // class optional_ref
76
77} // namespace sbx::memory
78
79#endif // LIBSBX_MEMORY_OPTIONAL_REF_HPP_
Definition: optional_ref.hpp:7