pjmsg_mcap_wrapper
Loading...
Searching...
No Matches
optional.hpp
Go to the documentation of this file.
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
24namespace eprosima {
25namespace fastcdr {
26
27//! An empty class type used to indicate optional type with uninitialized state.
29{
30 constexpr explicit nullopt_t(
31 int)
32 {
33 }
34
35};
36
37/*!
38 * @brief nullopt is a constant of type nullopt_t that is used to indicate optional type with uninitialized state.
39 */
40static constexpr nullopt_t nullopt {0};
41
42/*!
43 * @brief This class template manages an optional contained value, i.e. a value that may or may not be present.
44 */
45template<class T>
47{
48public:
49
50 using type = T;
51
52 //! Default constructor
53 optional() = default;
54
55 //! Copy constructor from an instance of the templated class.
57 const T& val) noexcept
58 {
59 ::new(&storage_.val_)T(val);
60 storage_.engaged_ = true;
61 }
62
63 //! Move constructor from an instance of the templated class.
65 T&& val) noexcept
66 {
67 ::new(&storage_.val_)T(std::move(val));
68 storage_.engaged_ = true;
69 }
70
71 //! Copy constructor.
73 const optional<T>& val) noexcept
74 {
75 ::new(&storage_.val_)T(val.storage_.val_);
76 storage_.engaged_ = val.storage_.engaged_;
77 }
78
79 //! Move constructor.
81 optional<T>&& val) noexcept
82 {
83 ::new(&storage_.val_)T(std::move(val.storage_.val_));
84 storage_.engaged_ = val.storage_.engaged_;
85 }
86
87 //! Destructor
88 ~optional() = default;
89
90 /*!
91 * @brief Constructs the contained value in-place
92 *
93 * @param[in] _args The arguments to pass to the constructor.
94 */
95 template<class ... Args> void emplace(
96 Args&&... _args)
97 {
98 reset();
99 storage_.val_.T(std::forward<Args>(_args)...);
100 storage_.engaged_ = true;
101 }
102
103 /*!
104 * @brief Reset the state of the optional
105 *
106 * @param[in] initial_engaged True value initializes the state with a default instance of the templated class.
107 * False value leaves the optional in a uninitialized state.
108 */
109 void reset(
110 bool initial_engaged = false)
111 {
112 if (storage_.engaged_)
113 {
114 storage_.val_.~T();
115 }
116 storage_.engaged_ = initial_engaged;
117 if (storage_.engaged_)
118 {
119 ::new(&storage_.val_)T();
120 }
121 }
122
123 /*!
124 * @brief Returns the contained value.
125 *
126 * @return The contained value.
127 * @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
128 */
129 T& value()&
130 {
131 if (!storage_.engaged_)
132 {
135 }
136
137 return storage_.val_;
138 }
139
140 /*!
141 * @brief Returns the contained value.
142 *
143 * @return The contained value.
144 * @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
145 */
146 const T& value() const&
147 {
148 if (!storage_.engaged_)
149 {
152 }
153
154 return storage_.val_;
155 }
156
157 /*!
158 * @brief Returns the contained value.
159 *
160 * @return The contained value.
161 * @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
162 */
163 T&& value() &&
164 {
165 if (!storage_.engaged_)
166 {
169 }
170
171 return std::move(storage_.val_);
172 }
173
174 /*!
175 * @brief Returns the contained value.
176 *
177 * @return The contained value.
178 * @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
179 */
180 const T&& value() const&&
181 {
182 if (!storage_.engaged_)
183 {
186 }
187
188 return std::move(storage_.val_);
189 }
190
191 /*!
192 * @brief Checks whether the optional contains a value.
193 *
194 * @return Whether the optional contains a value.
195 */
196 bool has_value() const
197 {
198 return storage_.engaged_;
199 }
200
201 //! Assigns content from an optional.
203 const optional& opt)
204 {
205 reset();
206 storage_.engaged_ = opt.storage_.engaged_;
207 if (opt.storage_.engaged_)
208 {
209 ::new(&storage_.val_)T(opt.storage_.val_);
210 }
211 return *this;
212 }
213
214 //! Assigns content from an optional.
216 optional&& opt)
217 {
218 reset();
219 storage_.engaged_ = opt.storage_.engaged_;
220 if (opt.storage_.engaged_)
221 {
222 ::new(&storage_.val_)T(std::move(opt.storage_.val_));
223 }
224 return *this;
225 }
226
227 //! Assigns content from an instance of the templated class.
229 const T& val)
230 {
231 reset();
232 ::new(&storage_.val_)T(val);
233 storage_.engaged_ = true;
234 return *this;
235 }
236
237 //! Assigns content from an instance of the templated class.
239 T&& val)
240 {
241 reset();
242 ::new(&storage_.val_)T(std::move(val));
243 storage_.engaged_ = true;
244 return *this;
245 }
246
247 //! Uninitialized the optional.
249 nullopt_t) noexcept
250 {
251 reset();
252 return *this;
253 }
254
255 //! Compares optional values.
257 const optional& opt_val) const
258 {
259 return opt_val.storage_.engaged_ == storage_.engaged_ &&
260 (storage_.engaged_ ? opt_val.storage_.val_ == storage_.val_ : true);
261 }
262
263 //! Compares optional values.
265 const optional& opt_val) const
266 {
267 return !operator ==(opt_val);
268 }
269
270 /*!
271 * @brief Accesses the contained value.
272 *
273 * The behavior is undefined if *this does not contain a value.
274 *
275 * @return The contained value.
276 */
277 T& operator *() & noexcept
278 {
279 return storage_.val_;
280 }
281
282 /*!
283 * @brief Accesses the contained value.
284 *
285 * The behavior is undefined if *this does not contain a value.
286 *
287 * @return The contained value.
288 */
289 const T& operator *() const& noexcept
290 {
291 return storage_.val_;
292 }
293
294 /*!
295 * @brief Accesses the contained value.
296 *
297 * The behavior is undefined if *this does not contain a value.
298 *
299 * @return The contained value.
300 */
301 T&& operator *() && noexcept
302 {
303 return std::move(storage_.val_);
304 }
305
306 /*!
307 * @brief Accesses the contained value.
308 *
309 * The behavior is undefined if *this does not contain a value.
310 *
311 * @return The contained value.
312 */
313 const T&& operator *() const&& noexcept
314 {
315 return std::move(storage_.val_);
316 }
317
318 /*!
319 * @brief Accesses the contained value.
320 *
321 * The behavior is undefined if *this does not contain a value.
322 *
323 * @return The contained value.
324 */
325 T* operator ->() noexcept
326 {
327 return std::addressof(storage_.val_);
328 }
329
330 /*!
331 * @brief Accesses the contained value.
332 *
333 * The behavior is undefined if *this does not contain a value.
334 *
335 * @return The contained value.
336 */
337 const T* operator ->() const noexcept
338 {
339 return std::addressof(storage_.val_);
340 }
341
342 //! Checks whether the optional contains a value.
343 explicit operator bool() const noexcept
344 {
345 return storage_.engaged_;
346 }
347
348private:
349
351};
352
353} // namespace fastcdr
354} // namespace eprosima
355
356#endif //_FASTCDR_XCDR_OPTIONAL_HPP_
T addressof(T... args)
This class is thrown as an exception when accessing the value of a null optional.
static Cdr_DllAPI const char *const BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT
Default message used in the library.
This class template manages an optional contained value, i.e. a value that may or may not be present.
Definition optional.hpp:47
optional(const T &val) noexcept
Copy constructor from an instance of the templated class.
Definition optional.hpp:56
optional()=default
Default constructor.
T & value() &
Returns the contained value.
Definition optional.hpp:129
~optional()=default
Destructor.
T && value() &&
Returns the contained value.
Definition optional.hpp:163
optional(const optional< T > &val) noexcept
Copy constructor.
Definition optional.hpp:72
optional(T &&val) noexcept
Move constructor from an instance of the templated class.
Definition optional.hpp:64
T * operator->() noexcept
Accesses the contained value.
Definition optional.hpp:325
optional & operator=(const optional &opt)
Assigns content from an optional.
Definition optional.hpp:202
void reset(bool initial_engaged=false)
Reset the state of the optional.
Definition optional.hpp:109
void emplace(Args &&... _args)
Constructs the contained value in-place.
Definition optional.hpp:95
detail::optional_storage< T > storage_
Definition optional.hpp:350
bool operator==(const optional &opt_val) const
Compares optional values.
Definition optional.hpp:256
T & operator*() &noexcept
Accesses the contained value.
Definition optional.hpp:277
optional(optional< T > &&val) noexcept
Move constructor.
Definition optional.hpp:80
const T && value() const &&
Returns the contained value.
Definition optional.hpp:180
bool has_value() const
Checks whether the optional contains a value.
Definition optional.hpp:196
bool operator!=(const optional &opt_val) const
Compares optional values.
Definition optional.hpp:264
const T & value() const &
Returns the contained value.
Definition optional.hpp:146
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 Cdr.h:49
An empty class type used to indicate optional type with uninitialized state.
Definition optional.hpp:29