| Fast CDR Version 2.3.6 Fast CDR

Loading...
Searching...
No Matches
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
56 optional(
57 const T& val) noexcept
58 {
59 ::new(&storage_.val_)T(val);
60 storage_.engaged_ = true;
61 }
62
64 optional(
65 T&& val) noexcept
66 {
67 ::new(&storage_.val_)T(std::move(val));
68 storage_.engaged_ = true;
69 }
70
72 optional(
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
83 optional(
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()
95#if defined(__GNUC__) && __GNUC__ >= 12
96 __attribute__(
97 (noinline))
98#endif // if defined(__GNUC__) && __GNUC__ >= 12
99 = default;
100
106 template<class ... Args> void emplace(
107 Args&&... _args)
108 {
109 reset();
110 storage_.val_.T(std::forward<Args>(_args)...);
111 storage_.engaged_ = true;
112 }
113
120 void reset(
121 bool initial_engaged = false)
122 {
123 if (storage_.engaged_)
124 {
125 storage_.val_.~T();
126 }
127 storage_.engaged_ = initial_engaged;
128 if (storage_.engaged_)
129 {
130 ::new(&storage_.val_)T();
131 }
132 }
133
140 T& value()&
141 {
142 if (!storage_.engaged_)
143 {
144 throw exception::BadOptionalAccessException(
145 exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT);
146 }
147
148 return storage_.val_;
149 }
150
157 const T& value() const&
158 {
159 if (!storage_.engaged_)
160 {
161 throw exception::BadOptionalAccessException(
162 exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT);
163 }
164
165 return storage_.val_;
166 }
167
174 T&& value() &&
175 {
176 if (!storage_.engaged_)
177 {
178 throw exception::BadOptionalAccessException(
179 exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT);
180 }
181
182 return std::move(storage_.val_);
183 }
184
191 const T&& value() const&&
192 {
193 if (!storage_.engaged_)
194 {
195 throw exception::BadOptionalAccessException(
196 exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT);
197 }
198
199 return std::move(storage_.val_);
200 }
201
207 bool has_value() const
208 {
209 return storage_.engaged_;
210 }
211
213 optional& operator =(
214 const optional& opt)
215#if defined(__GNUC__) && __GNUC__ >= 12
216 __attribute__(
217 (noinline))
218#endif // if defined(__GNUC__) && __GNUC__ >= 12
219 {
220 reset();
221 storage_.engaged_ = opt.storage_.engaged_;
222 if (opt.storage_.engaged_)
223 {
224 ::new(&storage_.val_)T(opt.storage_.val_);
225 }
226 return *this;
227 }
228
230 optional& operator =(
231 optional&& opt)
232#if defined(__GNUC__) && __GNUC__ >= 12
233 __attribute__(
234 (noinline))
235#endif // if defined(__GNUC__) && __GNUC__ >= 12
236 {
237 reset();
238 storage_.engaged_ = opt.storage_.engaged_;
239 if (opt.storage_.engaged_)
240 {
241 ::new(&storage_.val_)T(std::move(opt.storage_.val_));
242 }
243 return *this;
244 }
245
247 optional& operator =(
248 const T& val)
249 {
250 reset();
251 ::new(&storage_.val_)T(val);
252 storage_.engaged_ = true;
253 return *this;
254 }
255
257 optional& operator =(
258 T&& val)
259 {
260 reset();
261 ::new(&storage_.val_)T(std::move(val));
262 storage_.engaged_ = true;
263 return *this;
264 }
265
267 optional& operator = (
268 nullopt_t) noexcept
269 {
270 reset();
271 return *this;
272 }
273
275 bool operator ==(
276 const optional& opt_val) const
277 {
278 return opt_val.storage_.engaged_ == storage_.engaged_ &&
279 (storage_.engaged_ ? opt_val.storage_.val_ == storage_.val_ : true);
280 }
281
283 bool operator !=(
284 const optional& opt_val) const
285 {
286 return !operator ==(opt_val);
287 }
288
296 T& operator *() & noexcept
297 {
298 return storage_.val_;
299 }
300
308 const T& operator *() const& noexcept
309 {
310 return storage_.val_;
311 }
312
320 T && operator *() && noexcept
321 {
322 return std::move(storage_.val_);
323 }
324
332 const T && operator*() const && noexcept
333 {
334 return std::move(storage_.val_);
335 }
336
344 T* operator ->() noexcept
345 {
346 return std::addressof(storage_.val_);
347 }
348
356 const T* operator ->() const noexcept
357 {
358 return std::addressof(storage_.val_);
359 }
360
362 explicit operator bool() const noexcept
363 {
364 return storage_.engaged_;
365 }
366
367 private:
368
369 detail::optional_storage<T> storage_;
370};
371
372} // namespace fastcdr
373} // namespace eprosima
374
375#endif //_FASTCDR_XCDR_OPTIONAL_HPP_
eprosima::fastcdr::exception::BadOptionalAccessException
This class is thrown as an exception when accessing the value of a null optional.
Definition BadOptionalAccessException.hpp:28
eprosima::fastcdr::exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT
static const char *const BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT
Default message used in the library.
Definition BadOptionalAccessException.hpp:78
eprosima::fastcdr::optional::operator!=
bool operator!=(const optional &opt_val) const
Compares optional values.
Definition optional.hpp:283
eprosima::fastcdr::optional::reset
void reset(bool initial_engaged=false)
Reset the state of the optional.
Definition optional.hpp:120
eprosima::fastcdr::optional::optional
optional()=default
Default constructor.
eprosima::fastcdr::optional::value
T & value() &
Returns the contained value.
Definition optional.hpp:140
eprosima::fastcdr::optional::optional
optional(optional< T > &&val) noexcept
Move constructor.
Definition optional.hpp:83
eprosima::fastcdr::optional::operator*
const T && operator*() const &&noexcept
Accesses the contained value.
Definition optional.hpp:332
eprosima::fastcdr::optional::optional
optional(const optional< T > &val) noexcept
Copy constructor.
Definition optional.hpp:72
eprosima::fastcdr::optional::value
T && value() &&
Returns the contained value.
Definition optional.hpp:174
eprosima::fastcdr::optional::has_value
bool has_value() const
Checks whether the optional contains a value.
Definition optional.hpp:207
eprosima::fastcdr::optional::type
T type
Definition optional.hpp:50
eprosima::fastcdr::optional::optional
optional(const T &val) noexcept
Copy constructor from an instance of the templated class.
Definition optional.hpp:56
eprosima::fastcdr::optional::operator*
T & operator*() &noexcept
Accesses the contained value.
Definition optional.hpp:296
eprosima::fastcdr::optional::operator==
bool operator==(const optional &opt_val) const
Compares optional values.
Definition optional.hpp:275
eprosima::fastcdr::optional::operator->
T * operator->() noexcept
Accesses the contained value.
Definition optional.hpp:344
eprosima::fastcdr::optional::value
const T & value() const &
Returns the contained value.
Definition optional.hpp:157
eprosima::fastcdr::optional::emplace
void emplace(Args &&... _args)
Constructs the contained value in-place.
Definition optional.hpp:106
eprosima::fastcdr::optional::~optional
~optional()=default
Destructor.
eprosima::fastcdr::optional::value
const T && value() const &&
Returns the contained value.
Definition optional.hpp:191
eprosima::fastcdr::optional::operator=
optional & operator=(const optional &opt)
Assigns content from an optional.
Definition optional.hpp:213
eprosima::fastcdr::optional::optional
optional(T &&val) noexcept
Move constructor from an instance of the templated class.
Definition optional.hpp:64
eprosima::fastcdr
Definition Cdr.h:50
eprosima::fastcdr::nullopt
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
eprosima
Definition Cdr.h:49
eprosima::fastcdr::detail::optional_storage
Definition optional.hpp:25
eprosima::fastcdr::nullopt_t
An empty class type used to indicate optional type with uninitialized state.
Definition optional.hpp:29
eprosima::fastcdr::nullopt_t::nullopt_t
constexpr nullopt_t(int)
Definition optional.hpp:30