Fast CDR  Version 2.3.0
Fast CDR
optional.hpp
1 // Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #ifndef _FASTCDR_XCDR_OPTIONAL_HPP_
16 #define _FASTCDR_XCDR_OPTIONAL_HPP_
17 
18 #include <new>
19 #include <utility>
20 
21 #include "detail/optional.hpp"
22 #include "../exceptions/BadOptionalAccessException.hpp"
23 
24 namespace eprosima {
25 namespace fastcdr {
26 
28 struct nullopt_t
29 {
30  constexpr explicit nullopt_t(
31  int)
32  {
33  }
34 
35 };
36 
40 static constexpr nullopt_t nullopt {0};
41 
45 template<class T>
46 class optional
47 {
48 public:
49 
50  using type = T;
51 
53  optional() = default;
54 
57  const T& val) noexcept
58  {
59  ::new(&storage_.val_)T(val);
60  storage_.engaged_ = true;
61  }
62 
65  T&& val) noexcept
66  {
67  ::new(&storage_.val_)T(std::move(val));
68  storage_.engaged_ = true;
69  }
70 
73  const optional<T>& val) noexcept
74  {
75  if (val.storage_.engaged_)
76  {
77  ::new(&storage_.val_)T(val.storage_.val_);
78  storage_.engaged_ = true;
79  }
80  }
81 
84  optional<T>&& val) noexcept
85  {
86  if (val.storage_.engaged_)
87  {
88  ::new(&storage_.val_)T(std::move(val.storage_.val_));
89  storage_.engaged_ = true;
90  }
91  }
92 
94  ~optional() = default;
95 
101  template<class ... Args> void emplace(
102  Args&&... _args)
103  {
104  reset();
105  storage_.val_.T(std::forward<Args>(_args)...);
106  storage_.engaged_ = true;
107  }
108 
115  void reset(
116  bool initial_engaged = false)
117  {
118  if (storage_.engaged_)
119  {
120  storage_.val_.~T();
121  }
122  storage_.engaged_ = initial_engaged;
123  if (storage_.engaged_)
124  {
125  ::new(&storage_.val_)T();
126  }
127  }
128 
135  T& value()&
136  {
137  if (!storage_.engaged_)
138  {
141  }
142 
143  return storage_.val_;
144  }
145 
152  const T& value() const&
153  {
154  if (!storage_.engaged_)
155  {
158  }
159 
160  return storage_.val_;
161  }
162 
169  T&& value() &&
170  {
171  if (!storage_.engaged_)
172  {
175  }
176 
177  return std::move(storage_.val_);
178  }
179 
186  const T&& value() const&&
187  {
188  if (!storage_.engaged_)
189  {
192  }
193 
194  return std::move(storage_.val_);
195  }
196 
202  bool has_value() const
203  {
204  return storage_.engaged_;
205  }
206 
209  const optional& opt)
210  {
211  reset();
212  storage_.engaged_ = opt.storage_.engaged_;
213  if (opt.storage_.engaged_)
214  {
215  ::new(&storage_.val_)T(opt.storage_.val_);
216  }
217  return *this;
218  }
219 
222  optional&& opt)
223  {
224  reset();
225  storage_.engaged_ = opt.storage_.engaged_;
226  if (opt.storage_.engaged_)
227  {
228  ::new(&storage_.val_)T(std::move(opt.storage_.val_));
229  }
230  return *this;
231  }
232 
235  const T& val)
236  {
237  reset();
238  ::new(&storage_.val_)T(val);
239  storage_.engaged_ = true;
240  return *this;
241  }
242 
245  T&& val)
246  {
247  reset();
248  ::new(&storage_.val_)T(std::move(val));
249  storage_.engaged_ = true;
250  return *this;
251  }
252 
255  nullopt_t) noexcept
256  {
257  reset();
258  return *this;
259  }
260 
263  const optional& opt_val) const
264  {
265  return opt_val.storage_.engaged_ == storage_.engaged_ &&
266  (storage_.engaged_ ? opt_val.storage_.val_ == storage_.val_ : true);
267  }
268 
271  const optional& opt_val) const
272  {
273  return !operator ==(opt_val);
274  }
275 
283  T& operator *() & noexcept
284  {
285  return storage_.val_;
286  }
287 
295  const T& operator *() const& noexcept
296  {
297  return storage_.val_;
298  }
299 
307  T&& operator *() && noexcept
308  {
309  return std::move(storage_.val_);
310  }
311 
319  const T&& operator *() const&& noexcept
320  {
321  return std::move(storage_.val_);
322  }
323 
331  T* operator ->() noexcept
332  {
333  return std::addressof(storage_.val_);
334  }
335 
343  const T* operator ->() const noexcept
344  {
345  return std::addressof(storage_.val_);
346  }
347 
349  explicit operator bool() const noexcept
350  {
351  return storage_.engaged_;
352  }
353 
354 private:
355 
357 };
358 
359 } // namespace fastcdr
360 } // namespace eprosima
361 
362 #endif //_FASTCDR_XCDR_OPTIONAL_HPP_
This class is thrown as an exception when accessing the value of a null optional.
Definition: BadOptionalAccessException.hpp:28
static const char *const BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT
Default message used in the library.
Definition: BadOptionalAccessException.hpp:78
This class template manages an optional contained value, i.e.
Definition: optional.hpp:47
bool operator!=(const optional &opt_val) const
Compares optional values.
Definition: optional.hpp:270
void reset(bool initial_engaged=false)
Reset the state of the optional.
Definition: optional.hpp:115
optional()=default
Default constructor.
const T && value() const &&
Returns the contained value.
Definition: optional.hpp:186
optional(optional< T > &&val) noexcept
Move constructor.
Definition: optional.hpp:83
optional & operator=(const optional &opt)
Assigns content from an optional.
Definition: optional.hpp:208
optional(const optional< T > &val) noexcept
Copy constructor.
Definition: optional.hpp:72
bool has_value() const
Checks whether the optional contains a value.
Definition: optional.hpp:202
T && value() &&
Returns the contained value.
Definition: optional.hpp:169
T type
Definition: optional.hpp:50
optional(const T &val) noexcept
Copy constructor from an instance of the templated class.
Definition: optional.hpp:56
const T & value() const &
Returns the contained value.
Definition: optional.hpp:152
T & operator*() &noexcept
Accesses the contained value.
Definition: optional.hpp:283
bool operator==(const optional &opt_val) const
Compares optional values.
Definition: optional.hpp:262
T & value() &
Returns the contained value.
Definition: optional.hpp:135
T * operator->() noexcept
Accesses the contained value.
Definition: optional.hpp:331
void emplace(Args &&... _args)
Constructs the contained value in-place.
Definition: optional.hpp:101
~optional()=default
Destructor.
optional(T &&val) noexcept
Move constructor from an instance of the templated class.
Definition: optional.hpp:64
static constexpr nullopt_t nullopt
nullopt is a constant of type nullopt_t that is used to indicate optional type with uninitialized sta...
Definition: optional.hpp:40
Definition: fixed_size_string.hpp:32
An empty class type used to indicate optional type with uninitialized state.
Definition: optional.hpp:29
constexpr nullopt_t(int)
Definition: optional.hpp:30