31#ifndef ETL_OPTIONAL_INCLUDED
32#define ETL_OPTIONAL_INCLUDED
63 void operator&()
const ETL_DELETE;
80 optional_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
81 :
exception(reason_, file_name_, line_number_)
107 template <typename T, bool is_pod = etl::is_pod<T>::value>
113 template <
typename T>
143 if (other.has_value())
145 storage.construct(other.value());
157 if (other.has_value())
159 storage.construct(etl::move(other.value()));
170 storage.construct(value_);
180 storage.construct(etl::move(value_));
215 if (other.has_value())
217 storage.construct(other.value());
237 if (other.has_value())
239 storage.construct(etl::move(other.value()));
257 storage.construct(value_);
269 storage.construct(etl::move(value_));
281#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
285 return &storage.u.value;
292 const T* operator ->()
const
294#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
298 return &storage.u.value;
305 T& operator *() ETL_LVALUE_REF_QUALIFIER
307#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
311 return storage.u.value;
318 const T& operator *() const ETL_LVALUE_REF_QUALIFIER
320#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
324 return storage.u.value;
334#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
338 return etl::move(storage.u.value);
345 const T&& operator *() const&&
347#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
348 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
351 return etl::move(storage.u.value);
359 bool has_value() const ETL_NOEXCEPT
361 return storage.valid;
368 ETL_EXPLICIT
operator bool()
const
379#if ETL_IS_DEBUG_BUILD
383 return storage.u.value;
390 const T&
value() const ETL_LVALUE_REF_QUALIFIER
392#if ETL_IS_DEBUG_BUILD
396 return storage.u.value;
403 T
value_or(
const T& default_value)
const ETL_LVALUE_REF_QUALIFIER
405 return has_value() ? value() : default_value;
415#if ETL_IS_DEBUG_BUILD
419 return etl::move(storage.u.value);
426 const T&& value() const&&
428#if ETL_IS_DEBUG_BUILD
429 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
432 return etl::move(storage.u.value);
438 template <
typename U>
440 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
441 value_or(U&& default_value)
const&
443 return has_value() ? value() :
etl::forward<T>(default_value);
449 template <
typename U>
451 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
452 value_or(U&& default_value) &&
454 return has_value() ? etl::move(value()) :
etl::forward<T>(default_value);
478#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
483 template <
typename ... TArgs>
485 void emplace(TArgs&& ... args)
487 storage.construct(etl::forward<TArgs>(args)...);
494 template <
typename T1>
503 T* p = ::new (&storage.u.value) T(value1);
504 storage.valid =
true;
513 template <
typename T1,
typename T2>
514 T&
emplace(
const T1& value1,
const T2& value2)
522 T* p = ::new (&storage.u.value) T(value1, value2);
523 storage.valid =
true;
532 template <
typename T1,
typename T2,
typename T3>
533 T&
emplace(
const T1& value1,
const T2& value2,
const T3& value3)
541 T* p = ::new (&storage.u.value) T(value1, value2, value3);
542 storage.valid =
true;
551 template <
typename T1,
typename T2,
typename T3,
typename T4>
552 T&
emplace(
const T1& value1,
const T2& value2,
const T3& value3,
const T4& value4)
560 T* p = ::new (&storage.u.value) T(value1, value2, value3, value4);
561 storage.valid =
true;
588 void construct(
const T& value_)
604 void construct(T&& value_)
608 u.value = etl::move(value_);
618 template <
typename... TArgs>
620 void construct(TArgs&&... args)
660 storage_type storage;
668 template <
typename T>
696 , storage(other.storage)
706 , storage(
etl::move(other.storage))
717 storage.u.value = value_;
724 ETL_CONSTEXPR14
optional(T&& value_)
727 storage.u.value = etl::move(value_);
747 storage.u = other.storage.u;
762 storage.u = etl::move(other.storage.u);
773 ETL_CONSTEXPR14
optional& operator =(
const T& value_)
775 storage.u.value = value_;
785 ETL_CONSTEXPR14
optional& operator =(T&& value_)
787 storage.u.value = etl::move(value_);
797 ETL_CONSTEXPR14 T* operator ->()
799#if ETL_IS_DEBUG_BUILD
803 return &storage.u.value;
809 ETL_CONSTEXPR14
const T* operator ->()
const
811#if ETL_IS_DEBUG_BUILD
815 return &storage.u.value;
821 ETL_CONSTEXPR14 T& operator *() ETL_LVALUE_REF_QUALIFIER
823#if ETL_IS_DEBUG_BUILD
827 return storage.u.value;
833 ETL_CONSTEXPR14
const T& operator *() const ETL_LVALUE_REF_QUALIFIER
835#if ETL_IS_DEBUG_BUILD
839 return storage.u.value;
846 ETL_CONSTEXPR14 T&& operator *()&&
848#if ETL_IS_DEBUG_BUILD
852 return etl::move(storage.u.value);
858 ETL_CONSTEXPR14
const T&& operator *() const&&
860#if ETL_IS_DEBUG_BUILD
861 ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
864 return etl::move(storage.u.value);
872 ETL_EXPLICIT
operator bool()
const
880 ETL_CONSTEXPR14
bool has_value() const ETL_NOEXCEPT
888 ETL_CONSTEXPR14 T& value() ETL_LVALUE_REF_QUALIFIER
890#if ETL_IS_DEBUG_BUILD
894 return storage.u.value;
900 ETL_CONSTEXPR14
const T& value() const ETL_LVALUE_REF_QUALIFIER
902#if ETL_IS_DEBUG_BUILD
906 return storage.u.value;
912 ETL_CONSTEXPR14 T value_or(
const T& default_value)
const ETL_LVALUE_REF_QUALIFIER
914 return valid ? value() : default_value;
921 ETL_CONSTEXPR14 T&& value()&&
923#if ETL_IS_DEBUG_BUILD
927 return etl::move(storage.u.value);
933 ETL_CONSTEXPR14
const T&& value() const&&
935#if ETL_IS_DEBUG_BUILD
936 ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
939 return etl::move(storage.u.value);
945 template <
typename U>
947 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
948 value_or(U&& default_value)
const&
956 return static_cast<T
>(etl::forward<U>(default_value));
963 template <
typename U>
965 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
966 value_or(U&& default_value) &&
970 return etl::move(value());
974 return static_cast<T
>(etl::forward<U>(default_value));
992 ETL_CONSTEXPR14
void reset()
997#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
1002 template <
typename ... Args>
1003 ETL_CONSTEXPR14
void emplace(Args && ... args)
1005 storage.u.value = T(ETL_OR_STD::forward<Args>(args)...);
1013 template <
typename T1>
1016 storage.u.value = value1;
1024 template <
typename T1,
typename T2>
1027 storage.u.value = T(value1, value2);
1035 template <
typename T1,
typename T2,
typename T3>
1036 void emplace(
const T1& value1,
const T2& value2,
const T3& value3)
1038 storage.u.value = T(value1, value2, value3);
1046 template <
typename T1,
typename T2,
typename T3,
typename T4>
1047 void emplace(
const T1& value1,
const T2& value2,
const T3& value3,
const T4& value4)
1049 storage.u.value = T(value1, value2, value3, value4);
1078 storage_type storage;
1086 template <
typename T>
1089 if (lhs.has_value() != rhs.has_value())
1093 else if (!lhs.has_value() && !rhs.has_value())
1099 return lhs.value() == rhs.value();
1106 template <
typename T>
1109 return !(lhs == rhs);
1115 template <
typename T>
1118 if (!rhs.has_value())
1122 else if (!lhs.has_value())
1128 return lhs.value() < rhs.value();
1135 template <
typename T>
1138 return !(rhs < lhs);
1144 template <
typename T>
1153 template <
typename T>
1156 return !(lhs < rhs);
1162 template <
typename T>
1165 return !lhs.has_value();
1171 template <
typename T>
1174 return !rhs.has_value();
1180 template <
typename T>
1189 template <
typename T>
1198 template <
typename T>
1207 template <
typename T>
1210 return rhs.has_value();
1216 template <
typename T>
1219 return !lhs.has_value();
1225 template <
typename T>
1234 template <
typename T>
1237 return lhs.has_value();
1243 template <
typename T>
1252 template <
typename T>
1261 template <
typename T>
1264 return !rhs.has_value();
1270 template <
typename T,
typename U>
1273 return lhs.has_value() ? lhs.value() == rhs :
false;
1279 template <
typename T,
typename U>
1282 return !(lhs == rhs);
1288 template <
typename T,
typename U>
1291 return rhs.has_value() ? rhs.value() == lhs :
false;
1297 template <
typename T,
typename U>
1300 return !(lhs == rhs);
1306 template <
typename T,
typename U>
1309 return lhs.has_value() ? lhs.value() < rhs :
true;
1315 template <
typename T,
typename U>
1318 return rhs.has_value() ? lhs < rhs.value() :
false;
1324 template <
typename T,
typename U>
1327 return lhs.has_value() ? lhs.value() <= rhs :
true;
1333 template <
typename T,
typename U>
1336 return rhs.has_value() ? lhs <= rhs.value() :
false;
1342 template <
typename T,
typename U>
1345 return lhs.has_value() ? lhs.value() > rhs :
false;
1351 template <
typename T,
typename U>
1354 return rhs.has_value() ? lhs > rhs.value() :
true;
1360 template <
typename T,
typename U>
1363 return lhs.has_value() ? lhs.value() >= rhs :
false;
1369 template <
typename T,
typename U>
1372 return rhs.has_value() ? lhs >= rhs.value() :
true;
1380 template <
typename T>
1389#if ETL_CPP17_SUPPORTED
1390 template <
typename T>
1391 optional(T) -> optional<T>;
1398template <
typename T>
Definition: optional.h:50
ETL_CONSTEXPR20_STL T value_or(const T &default_value) const ETL_LVALUE_REF_QUALIFIER
Gets the value or a default if not valid.
Definition: optional.h:403
ETL_CONSTEXPR20_STL void reset()
Reset back to invalid.
Definition: optional.h:473
ETL_CONSTEXPR20_STL ~optional()
Destructor.
Definition: optional.h:188
ETL_CONSTEXPR20_STL optional(const optional &other)
Copy constructor.
Definition: optional.h:141
ETL_CONSTEXPR optional()
Constructor.
Definition: optional.h:122
T & emplace(const T1 &value1, const T2 &value2)
Definition: optional.h:514
ETL_CONSTEXPR optional(etl::nullopt_t)
Constructor with nullopt.
Definition: optional.h:131
T & emplace(const T1 &value1)
Definition: optional.h:495
ETL_CONSTEXPR20_STL const T & value() const ETL_LVALUE_REF_QUALIFIER
Get a const reference to the value.
Definition: optional.h:390
ETL_CONSTEXPR20_STL T & value() ETL_LVALUE_REF_QUALIFIER
Get a reference to the value.
Definition: optional.h:377
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition: optional.h:533
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition: optional.h:552
ETL_CONSTEXPR20_STL void swap(optional &other)
Swaps this value with another.
Definition: optional.h:462
ETL_CONSTEXPR20_STL optional(const T &value_)
Constructor from value type.
Definition: optional.h:168
void emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition: optional.h:1036
void emplace(const T1 &value1, const T2 &value2)
Definition: optional.h:1025
void emplace(const T1 &value1)
Definition: optional.h:1014
void emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition: optional.h:1047
Definition: optional.h:108
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: exception.h:47
Definition: optional.h:77
Definition: optional.h:91
T * construct_at(T *p)
Definition: memory.h:956
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition: memory.h:1006
bitset_ext
Definition: absolute.h:38
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:684
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:696
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:621
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
void destroy(const T *const p)
Destroys the object.
Definition: variant_pool_generator.h:256
ETL_CONSTEXPR14 etl::optional< typename etl::decay< T >::type > make_optional(T &value)
Make an optional.
Definition: optional.h:1381
const nullopt_t nullopt
Definition: optional.h:70
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:657
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:672
ETL_CONSTEXPR14 void swap(etl::optional< T > &lhs, etl::optional< T > &rhs)
Swaps the values.
Definition: optional.h:1399