| Face Engine SDK 4.9.0 A face detection, recognition and tracking engine.

Optional.h
1 #pragma once
2
3 #include <type_traits>
4 #include <assert.h>
5 #include <stdexcept>
6
7 namespace fsdk {
8
9 struct In_place_t {
10 explicit In_place_t() = default;
11 };
12
13 template<typename BaseType>
14 class Optional {
15 using Storage = typename std::aligned_storage<sizeof(BaseType), std::alignment_of<BaseType>::value>::type;
16
17 Storage m_storage;
18 bool m_valid = false;
19
20 public:
21 typedef Optional<BaseType> self_type;
22
23 Optional() = default;
24
25 ~Optional() {
26 reset();
27 }
28
29 Optional(const Optional &src) : m_valid(src.m_valid) {
30 if (src.m_valid) {
31 new(&m_storage) BaseType(*src);
32 }
33 }
34
35 Optional(Optional &&src) : m_valid(src.m_valid) {
36 if (src.m_valid) {
37 new(&m_storage) BaseType(std::move(*src));
38 }
39 }
40
41 template<typename U = BaseType, typename =
42 typename std::enable_if<
43 std::is_constructible<BaseType, U &&>::value &&
44 !(std::is_same<typename std::decay<U>::type, self_type>::value)
45 >::type
46 >
47 Optional(U &&value) : m_valid(true) {
48 new(&m_storage) BaseType(std::forward<U>(value));
49 }
50
51 template<typename... Args, typename = typename std::enable_if<std::is_constructible<BaseType, Args...>::value>::type>
52 explicit Optional(In_place_t tag, Args &&... args) : m_valid(true) {
53 new(&m_storage) BaseType(std::forward<Args>(args)...);
54 }
55
56 Optional &operator=(Optional &&src) noexcept {
57 if (src.m_valid) {
58 if (m_valid) {
59 **this = std::move(*src);
60 } else {
61 new(&m_storage) BaseType(std::move(*src));
62 m_valid = true;
63 }
64 } else if (m_valid) {
65 reinterpret_cast<BaseType *>(&m_storage)->~BaseType();
66 m_valid = false;
67 }
68
69 return *this;
70 }
71
72 Optional &operator=(const Optional &src) {
73 if (src.m_valid) {
74 if (m_valid) {
75 **this = *src;
76 } else {
77 new(&m_storage) BaseType(*src);
78 m_valid = true;
79 }
80 } else if (m_valid) {
81 reinterpret_cast<BaseType *>(&m_storage)->~BaseType();
82 m_valid = false;
83 }
84
85 return *this;
86 }
87
88 template<typename U = BaseType, typename =
89 typename std::enable_if<
90 !std::is_same<typename std::decay<U>::type, self_type>::value &&
91 std::is_constructible<BaseType, U>::value &&
92 std::is_assignable<BaseType &, U>::value
93 >::type>
94 Optional &operator=(U &&value) {
95 if (m_valid) {
96 **this = std::forward<U>(value);
97 } else {
98 new(&m_storage) BaseType(std::forward<U>(value));
99 m_valid = true;
100 }
101
102 return *this;
103 }
104
105 void reset() {
106 if (m_valid) {
107 (**this).BaseType::~BaseType();
108 m_valid = false;
109 }
110 }
111
112 constexpr explicit operator bool() const {
113 return m_valid;
114 }
115
116 constexpr bool has_value() const {
117 return m_valid;
118 }
119
120 constexpr bool valid() const {
121 return has_value();
122 }
123
124 BaseType &operator*() &{
125 assert(m_valid);
126 return *reinterpret_cast<BaseType *>(&m_storage);
127 }
128
129 const BaseType &operator*() const &{
130 assert(m_valid);
131 return *reinterpret_cast<const BaseType *>(&m_storage);
132 }
133
134 BaseType &&operator*() &&{
135 assert(m_valid);
136 return std::move(*reinterpret_cast<BaseType *>(&m_storage));
137 }
138
139 const BaseType &&operator*() const &&{
140 assert(m_valid);
141 return std::move(*reinterpret_cast<BaseType *>(&m_storage));
142 }
143
144 BaseType *operator->() {
145 assert(m_valid);
146 return reinterpret_cast<BaseType *>(&m_storage);
147 }
148
149 const BaseType *operator->() const {
150 assert(m_valid);
151 return reinterpret_cast<const BaseType *>(&m_storage);
152 }
153
154 BaseType &value() {
155 if (!has_value()) {
156 throw std::logic_error("bad_optional_access");
157 }
158
159 return **this;
160 }
161
162 const BaseType &value() const {
163 if (!has_value()) {
164 throw std::logic_error("bad_optional_access");
165 }
166
167 return **this;
168 }
169
170 template<typename U>
171 BaseType value_or(U &&default_value) &&{
172 return has_value() ? std::move(**this) : static_cast<BaseType>(std::forward<U>(default_value));
173 }
174
175 template<typename U>
176 const BaseType value_or(U &&default_value) const &{
177 return has_value() ? **this : static_cast<BaseType>(std::forward<U>(default_value));
178 }
179
180 template<typename... Args>
181 BaseType &emplace(Args &&... args) {
182 reset();
183
184 new(&m_storage) BaseType(std::forward<Args>(args)...);
185 m_valid = true;
186
187 return **this;
188 }
189 };
190
191 template<typename T>
192 Optional<typename std::decay<T>::type> make_optional(T &&val) {
193 return Optional<typename std::decay<T>::type>(std::forward<T>(val));
194 }
195
196 template<typename T, typename... Args>
197 Optional<T> make_optional(Args &&... args) {
198 return Optional<T>(In_place_t{}, std::forward<Args>(args)...);
199 }
200 }
fsdk
SDK namespace.
Definition: IAGSEstimator.h:8
fsdk::Optional
Definition: Optional.h:14
fsdk::In_place_t
Definition: Optional.h:9