AWS IoT Device SDK C++ v2  1.33.0
AWS IoT Device SDK C++ v2
Optional.h
Go to the documentation of this file.
1 #pragma once
2 
6 #include <aws/crt/Utility.h>
7 #include <utility>
8 
9 namespace Aws
10 {
11  namespace Crt
12  {
17  template <typename T> class Optional
18  {
19  public:
20  Optional() : m_value(nullptr) {}
21  Optional(const T &val)
22  {
23  new (m_storage) T(val);
24  m_value = reinterpret_cast<T *>(m_storage);
25  }
26 
27  Optional(T &&val)
28  {
29  new (m_storage) T(std::forward<T>(val));
30  m_value = reinterpret_cast<T *>(m_storage);
31  }
32 
34  {
35  if (m_value)
36  {
37  m_value->~T();
38  }
39  }
40 
41  template <typename U = T> Optional &operator=(U &&u)
42  {
43  if (m_value)
44  {
45  *m_value = std::forward<U>(u);
46  return *this;
47  }
48 
49  new (m_storage) T(std::forward<U>(u));
50  m_value = reinterpret_cast<T *>(m_storage);
51 
52  return *this;
53  }
54 
55  Optional(const Optional<T> &other)
56  {
57  if (other.m_value)
58  {
59  new (m_storage) T(*other.m_value);
60  m_value = reinterpret_cast<T *>(m_storage);
61  }
62  else
63  {
64  m_value = nullptr;
65  }
66  }
67 
69  {
70  if (other.m_value)
71  {
72  new (m_storage) T(std::forward<T>(*other.m_value));
73  m_value = reinterpret_cast<T *>(m_storage);
74  }
75  else
76  {
77  m_value = nullptr;
78  }
79  }
80 
81  template <typename... Args> explicit Optional(Aws::Crt::InPlaceT, Args &&...args)
82  {
83  new (m_storage) T(std::forward<Args>(args)...);
84  m_value = reinterpret_cast<T *>(m_storage);
85  }
86 
87  Optional &operator=(const Optional &other)
88  {
89  if (this == &other)
90  {
91  return *this;
92  }
93 
94  if (m_value)
95  {
96  if (other.m_value)
97  {
98  *m_value = *other.m_value;
99  }
100  else
101  {
102  m_value->~T();
103  m_value = nullptr;
104  }
105 
106  return *this;
107  }
108 
109  if (other.m_value)
110  {
111  new (m_storage) T(*other.m_value);
112  m_value = reinterpret_cast<T *>(m_storage);
113  }
114 
115  return *this;
116  }
117 
118  template <typename U = T> Optional<T> &operator=(const Optional<U> &other)
119  {
120  if (this == &other)
121  {
122  return *this;
123  }
124 
125  if (m_value)
126  {
127  if (other.m_value)
128  {
129  *m_value = *other.m_value;
130  }
131  else
132  {
133  m_value->~T();
134  m_value = nullptr;
135  }
136 
137  return *this;
138  }
139 
140  if (other.m_value)
141  {
142  new (m_storage) T(*other.m_value);
143  m_value = reinterpret_cast<T *>(m_storage);
144  }
145 
146  return *this;
147  }
148 
149  template <typename U = T> Optional<T> &operator=(Optional<U> &&other)
150  {
151  if (this == &other)
152  {
153  return *this;
154  }
155 
156  if (m_value)
157  {
158  if (other.m_value)
159  {
160  *m_value = std::forward<U>(*other.m_value);
161  }
162  else
163  {
164  m_value->~T();
165  m_value = nullptr;
166  }
167 
168  return *this;
169  }
170 
171  if (other.m_value)
172  {
173  new (m_storage) T(std::forward<U>(*other.m_value));
174  m_value = reinterpret_cast<T *>(m_storage);
175  }
176 
177  return *this;
178  }
179 
180  template <typename... Args> T &emplace(Args &&...args)
181  {
182  reset();
183 
184  new (m_storage) T(std::forward<Args>(args)...);
185  m_value = reinterpret_cast<T *>(m_storage);
186 
187  return *m_value;
188  }
189 
190  const T *operator->() const { return m_value; }
191  T *operator->() { return m_value; }
192  const T &operator*() const & { return *m_value; }
193  T &operator*() & { return *m_value; }
194  const T &&operator*() const && { return std::move(*m_value); }
195  T &&operator*() && { return std::move(*m_value); }
196 
197  explicit operator bool() const noexcept { return m_value != nullptr; }
198  bool has_value() const noexcept { return m_value != nullptr; }
199 
200  T &value() & { return *m_value; }
201  const T &value() const & { return *m_value; }
202 
203  T &&value() && { return std::move(*m_value); }
204  const T &&value() const && { return std::move(*m_value); }
205 
206  void reset()
207  {
208  if (m_value)
209  {
210  m_value->~T();
211  m_value = nullptr;
212  }
213  }
214 
215  private:
216  alignas(T) char m_storage[sizeof(T)];
217  T *m_value;
218  };
219  } // namespace Crt
220 } // namespace Aws
Aws::Crt::Optional::operator*
const T && operator*() const &&
Definition: Optional.h:194
Aws::Crt::Optional::Optional
Optional(const T &val)
Definition: Optional.h:21
Aws::Crt::InPlaceT
Definition: Utility.h:15
Aws::Crt::Optional::emplace
T & emplace(Args &&...args)
Definition: Optional.h:180
Aws::Crt::Optional::operator*
const T & operator*() const &
Definition: Optional.h:192
Aws::Crt::Optional::Optional
Optional(T &&val)
Definition: Optional.h:27
Aws::Crt::Optional::operator=
Optional & operator=(U &&u)
Definition: Optional.h:41
Aws::Crt::Optional::operator=
Optional< T > & operator=(Optional< U > &&other)
Definition: Optional.h:149
Aws::Crt::Optional::has_value
bool has_value() const noexcept
Definition: Optional.h:198
Aws::Crt::Optional
Definition: Optional.h:18
Aws::Crt::Optional::value
T & value() &
Definition: Optional.h:200
Aws::Crt::Optional::~Optional
~Optional()
Definition: Optional.h:33
Aws
Definition: Allocator.h:11
Aws::Crt::Optional::operator*
T & operator*() &
Definition: Optional.h:193
Aws::Crt::Optional::value
const T & value() const &
Definition: Optional.h:201
Aws::Crt::Optional::operator=
Optional< T > & operator=(const Optional< U > &other)
Definition: Optional.h:118
Aws::Crt::Optional::value
const T && value() const &&
Definition: Optional.h:204
Aws::Crt::Optional::operator*
T && operator*() &&
Definition: Optional.h:195
Aws::Crt::Optional::value
T && value() &&
Definition: Optional.h:203
Aws::Crt::Optional::Optional
Optional(Optional< T > &&other)
Definition: Optional.h:68
Aws::Crt::Optional::Optional
Optional()
Definition: Optional.h:20
Utility.h
Aws::Crt::Optional::Optional
Optional(const Optional< T > &other)
Definition: Optional.h:55
Aws::Crt::Optional::operator=
Optional & operator=(const Optional &other)
Definition: Optional.h:87
Aws::Crt::Optional::operator->
T * operator->()
Definition: Optional.h:191
Aws::Crt::Optional::operator->
const T * operator->() const
Definition: Optional.h:190
Aws::Crt::Optional::reset
void reset()
Definition: Optional.h:206
Aws::Crt::Optional::Optional
Optional(Aws::Crt::InPlaceT, Args &&...args)
Definition: Optional.h:81