-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathoptional.h
More file actions
81 lines (70 loc) · 1.46 KB
/
Copy pathoptional.h
File metadata and controls
81 lines (70 loc) · 1.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#ifndef E9D70610_1760_4E50_93F3_1129D8E51D1B
#define E9D70610_1760_4E50_93F3_1129D8E51D1B
#include <exception>
#include <optional>
/**
* @brief Similar to std::optional.
*
* A trivially constructible optional value class that can be used as a member of a union.
* @note std::optional objects cannot be a member of a union.
* @warning Init() must be called to properly initialize the object before using it.
*/
template <typename T>
class Optional
{
public:
static_assert(std::is_trivially_constructible_v<T>);
bool hasValue() const
{
return initialized_;
}
const T& value() const
{
if (!initialized_)
{
throw std::bad_optional_access();
}
return *reinterpret_cast<const T*>(storage);
}
Optional<T> operator=(const T& rhs)
{
if (initialized_)
{
*reinterpret_cast<T*>(storage) = rhs;
}
else
{
new (static_cast<void*>(storage)) T(rhs);
}
initialized_ = true;
return *this;
}
operator std::optional<T>() const
{
if (initialized_)
{
return std::optional<T>(value());
}
else
{
return std::optional<T>();
}
}
private:
template <typename U>
friend void Init(Optional<U>& opt);
bool initialized_;
char storage[sizeof(T)];
};
template <typename T>
void Init(Optional<T>& opt)
{
opt.initialized_ = false;
}
template <typename T>
void Init(Optional<T>& opt, const T& val)
{
Init(opt);
opt = val;
}
#endif /* E9D70610_1760_4E50_93F3_1129D8E51D1B */