LeviLamina
Loading...
Searching...
No Matches
ValueOrRef.h
1#pragma once
2
3#include "mc/_HeaderOutputPredefine.h"
4
5namespace Details {
6
7template <typename T>
8class ValueOrRef {
9public:
10 ValueOrRef(std::reference_wrapper<T> ref) : is_pointer_(true), variant_(&ref.get()) {}
11
12 ~ValueOrRef() {
13 if (!is_pointer_) {
14 variant_.value.~T();
15 }
16 }
17
18 ValueOrRef(const ValueOrRef& other) = delete;
19
20 ValueOrRef(ValueOrRef&& other) noexcept
21 : is_pointer_(other.is_pointer_),
22 variant_(other.is_pointer_ ? Variant(other.variant_.pointer) : Variant(std::move(other.variant_.value))) {}
23
24 T& value() noexcept { return is_pointer_ ? *variant_.pointer : variant_.value; }
25
26 const T& value() const noexcept { return is_pointer_ ? *variant_.pointer : variant_.value; }
27
28private:
29 ValueOrRef(T value) : is_pointer_(false), variant_(std::move(value)) {}
30
31 union Variant {
32 Variant() : pointer(nullptr) {}
33 Variant(T* ptr) : pointer(ptr) {}
34 Variant(T&& val) : value(std::move(val)) {}
35 ~Variant() {}
36 T* pointer;
37 T value;
38 };
39 Variant variant_;
40 const bool is_pointer_;
41};
42
43} // namespace Details
Definition ValueOrRef.h:8