fsfw/contrib/fsfw_contrib/etl-20.39.4/include/etl/optional.h

2179 lines
72 KiB
C
Raw Permalink Normal View History

2024-10-29 10:49:46 +01:00
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2015 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_OPTIONAL_INCLUDED
#define ETL_OPTIONAL_INCLUDED
#include "platform.h"
#include "alignment.h"
#include "memory.h"
#include "type_traits.h"
#include "exception.h"
#include "error_handler.h"
#include "utility.h"
#include "placement_new.h"
namespace etl
{
//*****************************************************************************
/// A null option type.
///\ingroup utilities
//*****************************************************************************
class nullopt_t
{
public:
// Convertible to any type of null non-member pointer.
template<class T>
operator T*() const
{
return 0;
}
private:
// Can't take address of nullopt.
void operator&() const ETL_DELETE;
};
//*****************************************************************************
/// A null option.
///\ingroup utilities
//*****************************************************************************
const nullopt_t nullopt = {};
//***************************************************************************
/// Exception for optional.
///\ingroup list
//***************************************************************************
class optional_exception : public exception
{
public:
optional_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
/// Invalid exception for optional.
///\ingroup list
//***************************************************************************
class optional_invalid : public optional_exception
{
public:
optional_invalid(string_type file_name_, numeric_type line_number_)
: optional_exception("optional:invalid", file_name_, line_number_)
{
}
};
//*****************************************************************************
// Implementations for fundamental and non fundamental types.
//*****************************************************************************
namespace private_optional
{
template <typename T, bool IsDefaultConstructible = etl::is_integral<T>::value>
class optional_impl;
//*****************************************************************************
// Implementation for non fundamental types.
//*****************************************************************************
template <typename T>
class optional_impl<T, false>
{
protected:
typedef T value_type;
//***************************************************************************
/// Constructor.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl()
: storage()
{
}
//***************************************************************************
/// Constructor with nullopt.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl(etl::nullopt_t)
: storage()
{
}
#include "private/diagnostic_uninitialized_push.h"
//***************************************************************************
/// Copy constructor.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl(const optional_impl<T>& other)
{
if (other.has_value())
{
storage.construct(other.value());
}
}
#include "private/diagnostic_pop.h"
#if ETL_USING_CPP11
//***************************************************************************
/// Move constructor.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl(optional_impl<T>&& other)
{
if (other.has_value())
{
storage.construct(etl::move(other.value()));
}
}
#endif
//***************************************************************************
/// Constructor from value type.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl(const T& value_)
{
storage.construct(value_);
}
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor from value type.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl(T&& value_)
{
storage.construct(etl::move(value_));
}
#endif
//***************************************************************************
/// Destructor.
//***************************************************************************
ETL_CONSTEXPR20_STL
~optional_impl()
{
storage.destroy();
}
//***************************************************************************
/// Assignment operator from nullopt.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl& operator =(etl::nullopt_t)
{
if (has_value())
{
storage.destroy();
}
return *this;
}
//***************************************************************************
/// Assignment operator from optional_impl.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl& operator =(const optional_impl<T>& other)
{
if (this != &other)
{
if (other.has_value())
{
storage.construct(other.value());
}
else
{
storage.destroy();
}
}
return *this;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from optional_impl.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl& operator =(optional_impl&& other)
{
if (this != &other)
{
if (other.has_value())
{
storage.construct(etl::move(other.value()));
}
else
{
storage.destroy();
}
}
return *this;
}
#endif
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl& operator =(const T& value_)
{
storage.construct(value_);
return *this;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
ETL_CONSTEXPR20_STL
optional_impl& operator =(T&& value_)
{
storage.construct(etl::move(value_));
return *this;
}
#endif
public:
//***************************************************************************
/// Pointer operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
T* operator ->()
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return &storage.u.value;
}
//***************************************************************************
/// Pointer operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
const T* operator ->() const
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return &storage.u.value;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
T& operator *() ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.u.value;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
const T& operator *() const ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.u.value;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
T&& operator *()&&
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.u.value);
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
const T&& operator *() const&&
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.u.value);
}
#endif
//***************************************************************************
// Check whether optional contains value
//***************************************************************************
ETL_CONSTEXPR20_STL
bool has_value() const ETL_NOEXCEPT
{
return storage.valid;
}
//***************************************************************************
/// Bool conversion operator.
//***************************************************************************
ETL_CONSTEXPR20_STL
ETL_EXPLICIT operator bool() const
{
return has_value();
}
//***************************************************************************
/// Get a reference to the value.
//***************************************************************************
ETL_CONSTEXPR20_STL
T& value() ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.u.value;
}
//***************************************************************************
/// Get a const reference to the value.
//***************************************************************************
ETL_CONSTEXPR20_STL
const T& value() const ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.u.value;
}
//***************************************************************************
/// Gets the value or a default if not valid.
//***************************************************************************
ETL_CONSTEXPR20_STL
T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
{
return has_value() ? value() : default_value;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Get an rvalue reference to the value.
//***************************************************************************
ETL_CONSTEXPR20_STL
T&& value()&&
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.u.value);
}
//***************************************************************************
/// Get a const rvalue reference to the value.
//***************************************************************************
ETL_CONSTEXPR20_STL
const T&& value() const&&
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.u.value);
}
//***************************************************************************
/// Gets the value or a default if not valid.
//***************************************************************************
template <typename U>
ETL_CONSTEXPR20_STL
etl::enable_if_t<etl::is_convertible<U, T>::value, T>
value_or(U&& default_value) const&
{
return has_value() ? value() : etl::forward<T>(default_value);
}
//***************************************************************************
/// Gets the value or a default if not valid.
//***************************************************************************
template <typename U>
ETL_CONSTEXPR20_STL
etl::enable_if_t<etl::is_convertible<U, T>::value, T>
value_or(U&& default_value)&&
{
return has_value() ? etl::move(value()) : etl::forward<T>(default_value);
}
#endif
//***************************************************************************
/// Swaps this value with another.
//***************************************************************************
ETL_CONSTEXPR20_STL
void swap(optional_impl& other)
{
optional_impl temp(*this);
*this = other;
other = temp;
}
//***************************************************************************
/// Reset back to invalid.
//***************************************************************************
ETL_CONSTEXPR20_STL
void reset()
{
storage.destroy();
}
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
//*************************************************************************
/// Emplaces a value.
///\param args The arguments to construct with.
//*************************************************************************
template <typename... TArgs>
ETL_CONSTEXPR20_STL
void emplace(TArgs&& ... args)
{
storage.construct(etl::forward<TArgs>(args)...);
}
#else
//*************************************************************************
/// Emplaces a value.
/// 1 parameter.
//*************************************************************************
T& emplace()
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.u.value) T();
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 1 parameter.
//*************************************************************************
template <typename T1>
T& emplace(const T1& value1)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.u.value) T(value1);
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 2 parameters.
//*************************************************************************
template <typename T1, typename T2>
T& emplace(const T1& value1, const T2& value2)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.u.value) T(value1, value2);
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 3 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3>
T& emplace(const T1& value1, const T2& value2, const T3& value3)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.u.value) T(value1, value2, value3);
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 4 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.u.value) T(value1, value2, value3, value4);
storage.valid = true;
return *p;
}
#endif
private:
struct dummy_t {};
//*************************************
// The storage for the optional value.
//*************************************
struct storage_type
{
//*******************************
ETL_CONSTEXPR20_STL
storage_type()
: u()
, valid(false)
{
}
//*******************************
ETL_CONSTEXPR20_STL
void construct(const T& value_)
{
if (valid)
{
etl::destroy_at(&u.value);
}
etl::construct_at(&u.value, value_);
valid = true;
}
#if ETL_USING_CPP11
//*******************************
ETL_CONSTEXPR20_STL
void construct(T&& value_)
{
if (valid)
{
etl::destroy_at(&u.value);
}
etl::construct_at(&u.value, etl::move(value_));
valid = true;
}
//*******************************
template <typename... TArgs>
ETL_CONSTEXPR20_STL
void construct(TArgs&&... args)
{
if (valid)
{
etl::destroy_at(&u.value);
}
etl::construct_at(&u.value, etl::forward<TArgs>(args)...);
valid = true;
}
#endif
//*******************************
ETL_CONSTEXPR20_STL
void destroy()
{
if (valid)
{
etl::destroy_at(&u.value);
valid = false;
}
}
//*******************************
union union_type
{
ETL_CONSTEXPR20_STL
union_type()
: dummy()
{
}
ETL_CONSTEXPR20_STL
~union_type()
{
}
dummy_t dummy;
T value;
} u;
bool valid;
};
storage_type storage;
};
//*****************************************************************************
// Implementation for fundamental types.
//*****************************************************************************
template <typename T>
class optional_impl<T, true>
{
protected:
typedef T value_type;
//***************************************************************************
/// Constructor.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl()
: storage()
{
}
//***************************************************************************
/// Constructor with nullopt.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl(etl::nullopt_t)
: storage()
{
}
#include "private/diagnostic_uninitialized_push.h"
//***************************************************************************
/// Copy constructor.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl(const optional_impl<T>& other)
{
if (other.has_value())
{
storage.construct(other.value());
}
}
#include "private/diagnostic_pop.h"
#if ETL_USING_CPP11
//***************************************************************************
/// Move constructor.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl(optional_impl&& other)
{
if (other.has_value())
{
storage.construct(etl::move(other.value()));
}
}
#endif
//***************************************************************************
/// Constructor from value type.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl(const T& value_)
{
storage.construct(value_);
}
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor from value type.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl(T&& value_)
{
storage.construct(etl::move(value_));
}
#endif
//***************************************************************************
/// Assignment operator from nullopt.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl& operator =(etl::nullopt_t)
{
if (has_value())
{
storage.destroy();
}
return *this;
}
//***************************************************************************
/// Assignment operator from optional_impl.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl& operator =(const optional_impl<T>& other)
{
if (this != &other)
{
if (other.has_value())
{
storage.construct(other.value());
}
else
{
storage.destroy();
}
}
return *this;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from optional_impl.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl& operator =(optional_impl&& other)
{
if (this != &other)
{
if (other.has_value())
{
storage.construct(etl::move(other.value()));
}
else
{
storage.destroy();
}
}
return *this;
}
#endif
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl& operator =(const T& value_)
{
storage.construct(value_);
return *this;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
ETL_CONSTEXPR14
optional_impl& operator =(T&& value_)
{
storage.construct(etl::move(value_));
return *this;
}
#endif
public:
//***************************************************************************
/// Pointer operator.
//***************************************************************************
ETL_CONSTEXPR14
T* operator ->()
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return &storage.value;
}
//***************************************************************************
/// Pointer operator.
//***************************************************************************
ETL_CONSTEXPR14
const T* operator ->() const
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return &storage.value;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR14
T& operator *() ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.value;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR14
const T& operator *() const ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.value;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR14
T&& operator *()&&
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.value);
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR14
const T&& operator *() const&&
{
#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.value);
}
#endif
//***************************************************************************
// Check whether optional contains value
//***************************************************************************
ETL_CONSTEXPR14
bool has_value() const ETL_NOEXCEPT
{
return storage.valid;
}
//***************************************************************************
/// Bool conversion operator.
//***************************************************************************
ETL_CONSTEXPR14
ETL_EXPLICIT operator bool() const
{
return has_value();
}
//***************************************************************************
/// Get a reference to the value.
//***************************************************************************
ETL_CONSTEXPR14
T& value() ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.value;
}
//***************************************************************************
/// Get a const reference to the value.
//***************************************************************************
ETL_CONSTEXPR14
const T& value() const ETL_LVALUE_REF_QUALIFIER
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return storage.value;
}
//***************************************************************************
/// Gets the value or a default if not valid.
//***************************************************************************
ETL_CONSTEXPR14
T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
{
return has_value() ? value() : default_value;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Get an rvalue reference to the value.
//***************************************************************************
ETL_CONSTEXPR14
T&& value()&&
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.value);
}
//***************************************************************************
/// Get a const rvalue reference to the value.
//***************************************************************************
ETL_CONSTEXPR14
const T&& value() const&&
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
#endif
return etl::move(storage.value);
}
//***************************************************************************
/// Gets the value or a default if not valid.
//***************************************************************************
template <typename U>
ETL_CONSTEXPR14
etl::enable_if_t<etl::is_convertible<U, T>::value, T>
value_or(U&& default_value) const&
{
return has_value() ? value() : etl::forward<T>(default_value);
}
//***************************************************************************
/// Gets the value or a default if not valid.
//***************************************************************************
template <typename U>
ETL_CONSTEXPR14
etl::enable_if_t<etl::is_convertible<U, T>::value, T>
value_or(U&& default_value)&&
{
return has_value() ? etl::move(value()) : etl::forward<T>(default_value);
}
#endif
//***************************************************************************
/// Swaps this value with another.
//***************************************************************************
ETL_CONSTEXPR14
void swap(optional_impl& other)
{
optional_impl temp(*this);
*this = other;
other = temp;
}
//***************************************************************************
/// Reset back to invalid.
//***************************************************************************
ETL_CONSTEXPR14
void reset()
{
storage.destroy();
}
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
//*************************************************************************
/// Emplaces a value.
///\param args The arguments to construct with.
//*************************************************************************
template <typename... TArgs>
ETL_CONSTEXPR14
void emplace(TArgs&& ... args)
{
storage.construct(etl::forward<TArgs>(args)...);
}
#else
//*************************************************************************
/// Emplaces a value.
/// 1 parameter.
//*************************************************************************
T& emplace()
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.value) T();
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 1 parameter.
//*************************************************************************
template <typename T1>
T& emplace(const T1& value1)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.value) T(value1);
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 2 parameters.
//*************************************************************************
template <typename T1, typename T2>
T& emplace(const T1& value1, const T2& value2)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.value) T(value1, value2);
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 3 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3>
T& emplace(const T1& value1, const T2& value2, const T3& value3)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.value) T(value1, value2, value3);
storage.valid = true;
return *p;
}
//*************************************************************************
/// Emplaces a value.
/// 4 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
if (has_value())
{
// Destroy the old one.
storage.destroy();
}
T* p = ::new (&storage.value) T(value1, value2, value3, value4);
storage.valid = true;
return *p;
}
#endif
private:
//*************************************
// The storage for the optional value.
//*************************************
struct storage_type
{
//*******************************
ETL_CONSTEXPR14
storage_type()
: value()
, valid(false)
{
}
//*******************************
ETL_CONSTEXPR14
void construct(const T& value_)
{
value = value_;
valid = true;
}
#if ETL_USING_CPP11
//*******************************
ETL_CONSTEXPR14
void construct(T&& value_)
{
value = value_;
valid = true;
}
//*******************************
template <typename... TArgs>
ETL_CONSTEXPR14
void construct(TArgs&&... args)
{
value = T(etl::forward<TArgs>(args)...);
valid = true;
}
#endif
//*******************************
ETL_CONSTEXPR14
void destroy()
{
valid = false;
}
T value;
bool valid;
};
storage_type storage;
};
}
#define ETL_OPTIONAL_ENABLE_CPP14 typename etl::enable_if< etl::is_pod<U>::value, int>::type = 0
#define ETL_OPTIONAL_ENABLE_CPP20_STL typename etl::enable_if<!etl::is_pod<U>::value, int>::type = 0
#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 ETL_CONSTEXPR14 typename etl::enable_if< etl::is_pod<T>::value, bool>::type
#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL ETL_CONSTEXPR20_STL typename etl::enable_if<!etl::is_pod<T>::value, bool>::type
//*****************************************************************************
/// An optional type.
/// If the optional type is not initialised then a type is not constructed.
/// See http://en.cppreference.com/w/cpp/utility/optional
///\tparam T The type to store.
///\ingroup utilities
//*****************************************************************************
template <typename T>
class optional : public private_optional::optional_impl<T>
{
private:
typedef private_optional::optional_impl<T> impl_t;
public:
typedef T value_type;
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional()
: impl_t()
{
}
//***************************************************************************
/// Constructor.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional()
: impl_t()
{
}
#else
optional()
: impl_t()
{
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor with nullopt.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional(etl::nullopt_t)
: impl_t(etl::nullopt)
{
}
//***************************************************************************
/// Constructor with nullopt.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional(etl::nullopt_t)
: impl_t(etl::nullopt)
{
}
#else
//***************************************************************************
/// Constructor with nullopt.
//***************************************************************************
optional(etl::nullopt_t)
: impl_t(etl::nullopt)
{
}
#endif
#include "private/diagnostic_uninitialized_push.h"
#if ETL_USING_CPP11
//***************************************************************************
/// Copy constructor.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional(const optional& other)
: impl_t(other)
{
}
//***************************************************************************
/// Copy constructor.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional(const optional& other)
: impl_t(other)
{
}
#else
//***************************************************************************
/// Copy constructor.
//***************************************************************************
optional(const optional& other)
: impl_t(other)
{
}
#endif
#include "private/diagnostic_pop.h"
#if ETL_USING_CPP11
//***************************************************************************
/// Move constructor.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional(optional&& other)
: impl_t(other)
{
}
//***************************************************************************
/// Move constructor.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional(optional&& other)
: impl_t(other)
{
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Construct from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional(const T& value_)
: impl_t(value_)
{
}
//***************************************************************************
/// Construct from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional(const T& value_)
: impl_t(value_)
{
}
#else
//***************************************************************************
/// Construct from value type.
//***************************************************************************
optional(const T& value_)
: impl_t(value_)
{
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Move construct from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional(T&& value_)
: impl_t(etl::move(value_))
{
}
//***************************************************************************
/// Move construct from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional(T&& value_)
: impl_t(etl::move(value_))
{
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from nullopt.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional& operator =(etl::nullopt_t)
{
impl_t::operator=(etl::nullopt);
return *this;
}
//***************************************************************************
/// Assignment operator from nullopt.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional& operator =(etl::nullopt_t)
{
impl_t::operator=(etl::nullopt);
return *this;
}
#else
//***************************************************************************
/// Assignment operator from nullopt.
//***************************************************************************
optional& operator =(etl::nullopt_t)
{
impl_t::operator=(etl::nullopt);
return *this;
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from optional.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional& operator =(const optional& other)
{
impl_t::operator=(other);
return *this;
}
//***************************************************************************
/// Assignment operator from optional.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional& operator =(const optional& other)
{
impl_t::operator=(other);
return *this;
}
#else
//***************************************************************************
/// Assignment operator from optional.
//***************************************************************************
optional& operator =(const optional& other)
{
impl_t::operator=(other);
return *this;
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Move assignment operator from optional.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional& operator =(optional&& other)
{
impl_t::operator=(etl::move(other));
return *this;
}
//***************************************************************************
/// Move assignment operator from optional.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional& operator =(optional&& other)
{
impl_t::operator=(etl::move(other));
return *this;
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional& operator =(const T& value_)
{
impl_t::operator=(value_);
return *this;
}
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional& operator =(const T& value_)
{
impl_t::operator=(value_);
return *this;
}
#else
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
optional& operator =(const T& value_)
{
impl_t::operator=(value_);
return *this;
}
#endif
#if ETL_USING_CPP11
//***************************************************************************
/// Move assignment operator from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
ETL_CONSTEXPR14
optional& operator =(T&& value_)
{
impl_t::operator=(etl::move(value_));
return *this;
}
//***************************************************************************
/// Move assignment operator from value type.
//***************************************************************************
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
ETL_CONSTEXPR20_STL
optional& operator =(T&& value_)
{
impl_t::operator=(etl::move(value_));
return *this;
}
#endif
};
#include "private/diagnostic_uninitialized_push.h"
//***************************************************************************
/// Equality operator. cppreference 1
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (lhs.has_value() != rhs.has_value())
{
return false;
}
else if (!lhs.has_value() && !rhs.has_value())
{
return true;
}
else
{
return lhs.value() == rhs.value();
}
}
//***************************************************************************
/// Equality operator. cppreference 1
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (lhs.has_value() != rhs.has_value())
{
return false;
}
else if (!lhs.has_value() && !rhs.has_value())
{
return true;
}
else
{
return lhs.value() == rhs.value();
}
}
//***************************************************************************
/// Inequality operator. cppreference 2
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Inequality operator. cppreference 2
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Less than operator. cppreference 3
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (!rhs.has_value())
{
return false;
}
else if (!lhs.has_value())
{
return true;
}
else
{
return lhs.value() < rhs.value();
}
}
//***************************************************************************
/// Less than operator. cppreference 3
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (!rhs.has_value())
{
return false;
}
else if (!lhs.has_value())
{
return true;
}
else
{
return lhs.value() < rhs.value();
}
}
//***************************************************************************
/// Less than equal operator. cppreference 4
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(rhs < lhs);
}
//***************************************************************************
/// Less than equal operator. cppreference 4
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(rhs < lhs);
}
//***************************************************************************
/// greater than operator. cppreference 5
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return (rhs < lhs);
}
//***************************************************************************
/// greater than operator. cppreference 5
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return (rhs < lhs);
}
//***************************************************************************
/// greater than equal operator. cppreference 6
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(lhs < rhs);
}
//***************************************************************************
/// greater than equal operator. cppreference 6
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(lhs < rhs);
}
//***************************************************************************
/// Equality operator. cppreference 7
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !lhs.has_value();
}
//***************************************************************************
/// Equality operator. cppreference 7
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !lhs.has_value();
}
//***************************************************************************
/// Equality operator. cppreference 8
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !rhs.has_value();
}
//***************************************************************************
/// Equality operator. cppreference 8
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !rhs.has_value();
}
//***************************************************************************
/// Inequality operator. cppreference 9
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !(lhs == etl::nullopt);
}
//***************************************************************************
/// Inequality operator. cppreference 9
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !(lhs == etl::nullopt);
}
//***************************************************************************
/// Inequality operator. cppreference 10
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(etl::nullopt_t , const etl::optional<T>& rhs)
{
return !(etl::nullopt == rhs);
}
//***************************************************************************
/// Inequality operator. cppreference 10
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !(etl::nullopt == rhs);
}
//***************************************************************************
/// Less than operator. cppreference 11
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>&, etl::nullopt_t)
{
return false;
}
//***************************************************************************
/// Less than operator. cppreference 11
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>&, etl::nullopt_t)
{
return false;
}
//***************************************************************************
/// Less than operator. cppreference 12
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(etl::nullopt_t, const etl::optional<T>& rhs)
{
return rhs.has_value();
}
//***************************************************************************
/// Less than operator. cppreference 12
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(etl::nullopt_t, const etl::optional<T>& rhs)
{
return rhs.has_value();
}
//***************************************************************************
/// Less than equal operator. cppreference 13
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !lhs.has_value();
}
//***************************************************************************
/// Less than equal operator. cppreference 13
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !lhs.has_value();
}
//***************************************************************************
/// Less than equal operator. cppreference 14
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(etl::nullopt_t, const etl::optional<T>&)
{
return true;
}
//***************************************************************************
/// Less than equal operator. cppreference 14
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(etl::nullopt_t, const etl::optional<T>&)
{
return true;
}
//***************************************************************************
/// Greater than operator. cppreference 15
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, etl::nullopt_t)
{
return lhs.has_value();
}
//***************************************************************************
/// Greater than operator. cppreference 15
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, etl::nullopt_t)
{
return lhs.has_value();
}
//***************************************************************************
/// Greater than operator. cppreference 16
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(etl::nullopt_t, const etl::optional<T>&)
{
return false;
}
//***************************************************************************
/// Greater than operator. cppreference 16
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(etl::nullopt_t, const etl::optional<T>&)
{
return false;
}
//***************************************************************************
/// Greater than equal operator. cppreference 17
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>&, etl::nullopt_t)
{
return true;
}
//***************************************************************************
/// Greater than equal operator. cppreference 17
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>&, etl::nullopt_t)
{
return true;
}
//***************************************************************************
/// Greater than equal operator. cppreference 18
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !rhs.has_value();
}
//***************************************************************************
/// Greater than equal operator. cppreference 18
//***************************************************************************
template <typename T>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !rhs.has_value();
}
//***************************************************************************
/// Equality operator. cppreference 19
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() == rhs : false;
}
//***************************************************************************
/// Equality operator. cppreference 19
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() == rhs : false;
}
//***************************************************************************
/// Inequality operator. cppreference 21
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const U& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Inequality operator. cppreference 21
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const U& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Equality operator. cppreference 20
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? rhs.value() == lhs : false;
}
//***************************************************************************
/// Equality operator. cppreference 20
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? rhs.value() == lhs : false;
}
//***************************************************************************
/// Inequality operator. cppreference 22
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const U& lhs, const etl::optional<T>& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Inequality operator. cppreference 22
//**************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const U& lhs, const etl::optional<T>& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Less than operator. cppreference 23
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() < rhs : true;
}
//***************************************************************************
/// Less than operator. cppreference 23
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() < rhs : true;
}
//***************************************************************************
/// Less than operator. cppreference 24
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs < rhs.value() : false;
}
//***************************************************************************
/// Less than operator. cppreference 24
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs < rhs.value() : false;
}
//***************************************************************************
/// Less than equal operator. cppreference 25
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() <= rhs : true;
}
//***************************************************************************
/// Less than equal operator. cppreference 25
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() <= rhs : true;
}
//***************************************************************************
/// Less than equal operator. cppreference 26
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs <= rhs.value() : false;
}
//***************************************************************************
/// Less than equal operator. cppreference 26
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs <= rhs.value() : false;
}
//***************************************************************************
/// Greater than operator. cppreference 27
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() > rhs : false;
}
//***************************************************************************
/// Greater than operator. cppreference 27
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() > rhs : false;
}
//***************************************************************************
/// Greater than operator. cppreference 28
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs > rhs.value() : true;
}
//***************************************************************************
/// Greater than operator. cppreference 28
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs > rhs.value() : true;
}
//***************************************************************************
/// Greater than equal operator. cppreference 29
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() >= rhs : false;
}
//***************************************************************************
/// Greater than equal operator. cppreference 29
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const U& rhs)
{
return lhs.has_value() ? lhs.value() >= rhs : false;
}
//***************************************************************************
/// Greater than equal operator. cppreference 30
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs >= rhs.value() : true;
}
//***************************************************************************
/// Greater than equal operator. cppreference 30
//***************************************************************************
template <typename T, typename U>
ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const U& lhs, const etl::optional<T>& rhs)
{
return rhs.has_value() ? lhs >= rhs.value() : true;
}
#include "private/diagnostic_pop.h"
//***************************************************************************
/// Make an optional.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR20_STL etl::optional<typename etl::decay<T>::type> make_optional(T& value)
{
return etl::optional<typename etl::decay<T>::type>(value);
}
//***************************************************************************
/// Template deduction guides.
//***************************************************************************
#if ETL_CPP17_SUPPORTED
template <typename T>
optional(T) -> optional<T>;
#endif
}
//*************************************************************************
/// Swaps the values.
//*************************************************************************
template <typename T>
ETL_CONSTEXPR20_STL void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
{
lhs.swap(rhs);
}
#undef ETL_OPTIONAL_ENABLE_CPP14
#undef ETL_OPTIONAL_ENABLE_CPP20_STL
#undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL
#undef ETL_OPTIONAL_ENABLE_COMSTEXPR_BOOL_RETURN_CPP20_STL
#endif