aws-crt-cpp
Optional.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License").
6  * You may not use this file except in compliance with the License.
7  * A copy of the License is located at
8  *
9  * http://aws.amazon.com/apache2.0
10  *
11  * or in the "license" file accompanying this file. This file is distributed
12  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 #if __cplusplus >= 201703L
17 # include <optional>
18 #else
19 # include <cstdint>
20 # include <type_traits>
21 # include <utility>
22 #endif
23 
24 namespace Aws
25 {
26  namespace Crt
27  {
28 #if __cplusplus >= 201703L
29  template <typename T> using Optional = std::optional<T>;
30 #else
31  template <typename T> class Optional
32  {
33  public:
34  Optional() : m_value(nullptr) {}
35  Optional(const T &val)
36  {
37  new (&m_storage) T(val);
38  m_value = reinterpret_cast<T *>(&m_storage);
39  }
40 
41  Optional(T &&val)
42  {
43  new (&m_storage) T(std::forward<T>(val));
44  m_value = reinterpret_cast<T *>(&m_storage);
45  }
46 
48  {
49  if (m_value)
50  {
51  m_value->~T();
52  }
53  }
54 
55  template <typename U = T> Optional &operator=(U &&u)
56  {
57  if (m_value)
58  {
59  *m_value = std::forward<U>(u);
60  return *this;
61  }
62 
63  new (&m_storage) T(std::forward<U>(u));
64  m_value = reinterpret_cast<T *>(&m_storage);
65 
66  return *this;
67  }
68 
69  Optional(const Optional<T> &other)
70  {
71  if (other.m_value)
72  {
73  new (&m_storage) T(*other.m_value);
74  m_value = reinterpret_cast<T *>(&m_storage);
75  }
76  else
77  {
78  m_value = nullptr;
79  }
80  }
81 
83  {
84  if (other.m_value)
85  {
86  new (&m_storage) T(std::forward<T>(*other.m_value));
87  m_value = reinterpret_cast<T *>(&m_storage);
88  }
89  else
90  {
91  m_value = nullptr;
92  }
93  }
94 
95  Optional &operator=(const Optional &other)
96  {
97  if (this == &other)
98  {
99  return *this;
100  }
101 
102  if (m_value)
103  {
104  if (other.m_value)
105  {
106  *m_value = *other.m_value;
107  }
108  else
109  {
110  m_value->~T();
111  m_value = nullptr;
112  }
113 
114  return *this;
115  }
116 
117  if (other.m_value)
118  {
119  new (&m_storage) T(*other.m_value);
120  m_value = reinterpret_cast<T *>(&m_storage);
121  }
122 
123  return *this;
124  }
125 
126  template <typename U = T> Optional<T> &operator=(const Optional<U> &other)
127  {
128  if (this == &other)
129  {
130  return *this;
131  }
132 
133  if (m_value)
134  {
135  if (other.m_value)
136  {
137  *m_value = *other.m_value;
138  }
139  else
140  {
141  m_value->~T();
142  m_value = nullptr;
143  }
144 
145  return *this;
146  }
147 
148  if (other.m_value)
149  {
150  new (&m_storage) T(*other.m_value);
151  m_value = reinterpret_cast<T *>(&m_storage);
152  }
153 
154  return *this;
155  }
156 
157  template <typename U = T> Optional<T> &operator=(Optional<U> &&other)
158  {
159  if (this == &other)
160  {
161  return *this;
162  }
163 
164  if (m_value)
165  {
166  if (other.m_value)
167  {
168  *m_value = std::forward<U>(*other.m_value);
169  }
170  else
171  {
172  m_value->~T();
173  m_value = nullptr;
174  }
175 
176  return *this;
177  }
178 
179  if (other.m_value)
180  {
181  new (&m_storage) T(std::forward<U>(*other.m_value));
182  m_value = reinterpret_cast<T *>(&m_storage);
183  }
184 
185  return *this;
186  }
187 
188  const T *operator->() const { return m_value; }
189  T *operator->() { return m_value; }
190  const T &operator*() const & { return *m_value; }
191  T &operator*() & { return *m_value; }
192  const T &&operator*() const && { return std::move(*m_value); }
193  T &&operator*() && { return std::move(*m_value); }
194 
195  explicit operator bool() const noexcept { return m_value != nullptr; }
196  bool has_value() const noexcept { return m_value != nullptr; }
197 
198  T &value() & { return *m_value; }
199  const T &value() const & { return *m_value; }
200 
201  T &&value() && { return std::move(*m_value); }
202  const T &&value() const && { return std::move(*m_value); }
203 
204  private:
205  typename std::aligned_storage<sizeof(T)>::type m_storage;
206  T *m_value;
207  };
208 #endif
209  } // namespace Crt
210 } // namespace Aws
Aws::Crt::Optional::operator->
T * operator->()
Definition: Optional.h:189
Aws::Crt::Optional::~Optional
~Optional()
Definition: Optional.h:47
Aws::Crt::Optional::value
const T && value() const &&
Definition: Optional.h:202
Aws::Crt::Optional::Optional
Optional(const T &val)
Definition: Optional.h:35
Aws::Crt::Optional::value
T && value() &&
Definition: Optional.h:201
Aws::Crt::Optional::operator=
Optional< T > & operator=(Optional< U > &&other)
Definition: Optional.h:157
Aws::Crt::Optional::operator=
Optional< T > & operator=(const Optional< U > &other)
Definition: Optional.h:126
Aws::Crt::Optional::Optional
Optional(Optional< T > &&other)
Definition: Optional.h:82
Aws::Crt::Optional::value
const T & value() const &
Definition: Optional.h:199
Aws::Crt::Optional::operator*
T && operator*() &&
Definition: Optional.h:193
Aws::Crt::Optional::operator*
const T && operator*() const &&
Definition: Optional.h:192
Aws
Definition: Api.h:25
Aws::Crt::Optional::operator*
T & operator*() &
Definition: Optional.h:191
Aws::Crt::Optional::operator=
Optional & operator=(U &&u)
Definition: Optional.h:55
Aws::Crt::Optional
Definition: Optional.h:32
Aws::Crt::Optional::Optional
Optional(const Optional< T > &other)
Definition: Optional.h:69
Aws::Crt::Optional::operator=
Optional & operator=(const Optional &other)
Definition: Optional.h:95
Aws::Crt::Optional::has_value
bool has_value() const noexcept
Definition: Optional.h:196
Aws::Crt::Optional::Optional
Optional()
Definition: Optional.h:34
Aws::Crt::Optional::Optional
Optional(T &&val)
Definition: Optional.h:41
Aws::Crt::Optional::operator*
const T & operator*() const &
Definition: Optional.h:190
Aws::type
newitem type
Definition: cJSON.cpp:2209
Aws::Crt::Optional::operator->
const T * operator->() const
Definition: Optional.h:188
Aws::Crt::Optional::value
T & value() &
Definition: Optional.h:198