-
Notifications
You must be signed in to change notification settings - Fork 0
/
optional
68 lines (63 loc) · 1.73 KB
/
optional
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
/**
* @file optional
* @author <[email protected]>
* @date Fri Oct 5 09:53:55 2018
*
* @brief
*
* Copyright © 2017 Jens Munk Hansen
*
*/
#pragma once
#include <sps/cenv.h>
#include <new>
namespace sps {
namespace details {
struct nullopt_t {};
static const nullopt_t nullopt;
template<typename T>
class optional {
public:
optional(const T& object) : m_initialized(true) { new (m_object) T(object); };
optional(nullopt_t) : m_initialized(false) {};
optional() : m_initialized(false) {};
optional(const optional& other) : m_initialized(other.m_initialized) {
if (other.m_initialized)
new (m_object) T(*other);
}
optional& operator=(const optional& other) {
clear();
new (m_object) T(*other);
m_initialized = other.m_initialized;
return *this;
}
optional& operator=(nullopt_t) { clear(); return *this; }
~optional() { clear(); }
operator bool() const { return m_initialized; };
T& operator*() { return *reinterpret_cast<T*>(m_object); };
const T& operator*() const { return *reinterpret_cast<const T*>(m_object); };
T* operator->() { return &**this; };
const T* operator->() const { return &**this; };
private:
void clear() { if (m_initialized) (&**this)->~T(); m_initialized = false; }
char m_object[sizeof(T)];
bool m_initialized;
};
} // namespace details
#ifdef CXX17
# include <optional>
template <typename T>
using optional = std::optional<T>;
constexpr std::nullopt_t nullopt = std::nullopt;
#else
template <typename T>
using optional = details::optional<T>;
const details::nullopt_t nullopt = details::nullopt;
#endif
} // namespace sps
/* Local variables: */
/* indent-tabs-mode: nil */
/* tab-width: 2 */
/* c-basic-offset: 2 */
/* mode: c++ */
/* End: */