Added etl::npos

Added specialisation of etl::optional for POD
This commit is contained in:
John Wellbelove 2022-09-24 13:12:18 +01:00
parent fe6e0095b3
commit b3deaa6761
2 changed files with 360 additions and 34 deletions

View File

@ -215,6 +215,8 @@ namespace etl
static ETL_CONSTANT int bits = CHAR_BIT * (sizeof(unsigned long long) / sizeof(char));
static ETL_CONSTANT bool is_signed = etl::is_signed<unsigned long long>::value;
};
static ETL_CONSTANT size_t npos = etl::integral_limits<size_t>::max;
}
#include "private/minmax_pop.h"

View File

@ -103,8 +103,14 @@ namespace etl
///\tparam The type to store.
///\ingroup utilities
//*****************************************************************************
template <typename T, bool is_pod = etl::is_pod<T>::value>
class optional;
//*****************************************************************************
/// For non POD types.
//*****************************************************************************
template <typename T>
class optional
class optional<T, false>
{
public:
@ -359,7 +365,6 @@ namespace etl
return valid;
}
//***************************************************************************
/// Get a reference to the value.
//***************************************************************************
@ -507,11 +512,322 @@ namespace etl
bool valid;
};
//*****************************************************************************
/// For POD types.
//*****************************************************************************
template <typename T>
class optional<T, true>
{
public:
//***************************************************************************
/// Constructor.
//***************************************************************************
ETL_CONSTEXPR14 optional()
: storage()
, valid(false)
{
}
//***************************************************************************
/// Constructor with nullopt.
//***************************************************************************
ETL_CONSTEXPR14 optional(etl::nullopt_t)
: storage()
, valid(false)
{
}
//***************************************************************************
/// Copy constructor.
//***************************************************************************
ETL_CONSTEXPR14 optional(const optional& other)
: valid(bool(other))
, storage(other.storage)
{
}
#if ETL_USING_CPP11
//***************************************************************************
/// Move constructor.
//***************************************************************************
ETL_CONSTEXPR14 optional(optional&& other)
: valid(bool(other))
, storage(etl::move(other.storage))
{
}
#endif
//***************************************************************************
/// Constructor from value type.
//***************************************************************************
ETL_CONSTEXPR14 optional(const T& value_)
: storage(value_)
, valid(true)
{
}
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor from value type.
//***************************************************************************
ETL_CONSTEXPR14 optional(T&& value_)
: storage(etl::move(value_))
, valid(true)
{
}
#endif
//***************************************************************************
/// Assignment operator from nullopt.
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(etl::nullopt_t)
{
return *this;
}
//***************************************************************************
/// Assignment operator from optional.
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(const optional& other)
{
if (this != &other)
{
storage = other.storage;
valid = other.valid;
}
return *this;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from optional.
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(optional&& other)
{
if (this != &other)
{
storage = etl::move(other.storage);
valid = true;
}
return *this;
}
#endif
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(const T& value_)
{
storage = value_;
valid = true;
return *this;
}
#if ETL_USING_CPP11
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(T&& value_)
{
storage = etl::move(value_);
valid = true;
return *this;
}
#endif
//***************************************************************************
/// Pointer operator.
//***************************************************************************
ETL_CONSTEXPR14 T* operator ->()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return &storage;
}
//***************************************************************************
/// Pointer operator.
//***************************************************************************
ETL_CONSTEXPR14 const T* operator ->() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return &storage;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR14 T& operator *()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return storage;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_CONSTEXPR14 const T& operator *() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return storage;
}
//***************************************************************************
/// Bool conversion operator.
//***************************************************************************
ETL_CONSTEXPR14 operator bool() const
{
return valid;
}
//***************************************************************************
// Check whether optional contains value
//***************************************************************************
ETL_CONSTEXPR14 bool has_value() const ETL_NOEXCEPT
{
return valid;
}
//***************************************************************************
/// Get a reference to the value.
//***************************************************************************
ETL_CONSTEXPR14 T& value()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return storage;
}
//***************************************************************************
/// Get a const reference to the value.
//***************************************************************************
ETL_CONSTEXPR14 const T& value() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return storage;
}
//***************************************************************************
/// Gets the value or a default if no valid.
//***************************************************************************
ETL_CONSTEXPR14 T value_or(T default_value) const
{
return valid ? value() : default_value;
}
//***************************************************************************
/// Swaps this value with another.
//***************************************************************************
ETL_CONSTEXPR14 void swap(optional& other)
{
optional temp(*this);
*this = other;
other = temp;
}
//***************************************************************************
/// Reset back to invalid.
//***************************************************************************
ETL_CONSTEXPR14 void reset()
{
valid = false;
}
#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 ... Args>
ETL_CONSTEXPR14 void emplace(Args && ... args)
{
if (valid)
{
// Destroy the old one.
storage.template get_reference<T>().~T();
}
storage = T(ETL_OR_STD::forward<Args>(args)...);
valid = true;
}
#else
//*************************************************************************
/// Emplaces a value.
/// 1 parameter.
//*************************************************************************
template <typename T1>
void emplace(const T1& value1)
{
storage = value1;
valid = true;
}
//*************************************************************************
/// Emplaces a value.
/// 2 parameters.
//*************************************************************************
template <typename T1, typename T2>
void emplace(const T1& value1, const T2& value2)
{
storage = T(value1, value2);
valid = true;
}
//*************************************************************************
/// Emplaces a value.
/// 3 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace(const T1& value1, const T2& value2, const T3& value3)
{
storage = T(value1, value2, value3);
valid = true;
}
//*************************************************************************
/// Emplaces a value.
/// 4 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
storage = T(value1, value2, value3, value4);
valid = true;
}
#endif
private:
T storage;
bool valid;
};
//***************************************************************************
/// Equality operator. cppreference 1
//***************************************************************************
template <typename T>
bool operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (bool(lhs) != bool(rhs))
{
@ -531,7 +847,7 @@ namespace etl
/// Equality operator. cppreference 2
//***************************************************************************
template <typename T>
bool operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
return !(lhs == rhs);
}
@ -540,7 +856,7 @@ namespace etl
/// Less than operator. cppreference 3
//***************************************************************************
template <typename T>
bool operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (!bool(rhs))
{
@ -560,7 +876,7 @@ namespace etl
/// Less than equal operator. cppreference 4
//***************************************************************************
template <typename T>
bool operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (!bool(lhs))
{
@ -580,7 +896,7 @@ namespace etl
/// greater than operator. cppreference 5
//***************************************************************************
template <typename T>
bool operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (!bool(lhs))
{
@ -600,7 +916,7 @@ namespace etl
/// greater than equal operator. cppreference 6
//***************************************************************************
template <typename T>
bool operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
{
if (!bool(rhs))
{
@ -620,7 +936,7 @@ namespace etl
/// Equality operator. cppreference 7
//***************************************************************************
template <typename T>
bool operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
ETL_CONSTEXPR14 bool operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !bool(lhs);
}
@ -629,7 +945,7 @@ namespace etl
/// Equality operator. cppreference 8
//***************************************************************************
template <typename T>
bool operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !bool(rhs);
}
@ -638,7 +954,7 @@ namespace etl
/// Inequality operator. cppreference 9
//***************************************************************************
template <typename T>
bool operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
ETL_CONSTEXPR14 bool operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !(lhs == etl::nullopt);
}
@ -647,7 +963,7 @@ namespace etl
/// Inequality operator. cppreference 10
//***************************************************************************
template <typename T>
bool operator !=(etl::nullopt_t , const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator !=(etl::nullopt_t , const etl::optional<T>& rhs)
{
return !(etl::nullopt == rhs);
}
@ -656,7 +972,7 @@ namespace etl
/// Less than operator. cppreference 11
//***************************************************************************
template <typename T>
bool operator <(const etl::optional<T>&, etl::nullopt_t)
ETL_CONSTEXPR14 bool operator <(const etl::optional<T>&, etl::nullopt_t)
{
return false;
}
@ -665,7 +981,7 @@ namespace etl
/// Less than operator. cppreference 12
//***************************************************************************
template <typename T>
bool operator <(etl::nullopt_t, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator <(etl::nullopt_t, const etl::optional<T>& rhs)
{
return bool(rhs);
}
@ -674,7 +990,7 @@ namespace etl
/// Less than equal operator. cppreference 13
//***************************************************************************
template <typename T>
bool operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
ETL_CONSTEXPR14 bool operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
{
return !bool(lhs);
}
@ -683,7 +999,7 @@ namespace etl
/// Less than equal operator. cppreference 14
//***************************************************************************
template <typename T>
bool operator <=(etl::nullopt_t, const etl::optional<T>&)
ETL_CONSTEXPR14 bool operator <=(etl::nullopt_t, const etl::optional<T>&)
{
return true;
}
@ -692,7 +1008,7 @@ namespace etl
/// Greater than operator. cppreference 15
//***************************************************************************
template <typename T>
bool operator >(const etl::optional<T>& lhs, etl::nullopt_t)
ETL_CONSTEXPR14 bool operator >(const etl::optional<T>& lhs, etl::nullopt_t)
{
return bool(lhs);
}
@ -701,7 +1017,7 @@ namespace etl
/// Greater than operator. cppreference 16
//***************************************************************************
template <typename T>
bool operator >(etl::nullopt_t, const etl::optional<T>&)
ETL_CONSTEXPR14 bool operator >(etl::nullopt_t, const etl::optional<T>&)
{
return false;
}
@ -710,7 +1026,7 @@ namespace etl
/// Greater than equal operator. cppreference 17
//***************************************************************************
template <typename T>
bool operator >=(const etl::optional<T>&, etl::nullopt_t)
ETL_CONSTEXPR14 bool operator >=(const etl::optional<T>&, etl::nullopt_t)
{
return true;
}
@ -719,7 +1035,7 @@ namespace etl
/// Greater than equal operator. cppreference 18
//***************************************************************************
template <typename T>
bool operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
{
return !bool(rhs);
}
@ -728,7 +1044,7 @@ namespace etl
/// Equality operator. cppreference 19
//**************************************************************************
template <typename T, typename U>
bool operator ==(const etl::optional<T>& lhs, const U& rhs)
ETL_CONSTEXPR14 bool operator ==(const etl::optional<T>& lhs, const U& rhs)
{
return bool(lhs) ? lhs.value() == rhs : false;
}
@ -737,7 +1053,7 @@ namespace etl
/// Inequality operator. cppreference 21
//**************************************************************************
template <typename T, typename U>
bool operator !=(const etl::optional<T>& lhs, const U& rhs)
ETL_CONSTEXPR14 bool operator !=(const etl::optional<T>& lhs, const U& rhs)
{
return !(lhs == rhs);
}
@ -746,7 +1062,7 @@ namespace etl
/// Equality operator. cppreference 20
//**************************************************************************
template <typename T, typename U>
bool operator ==(const U& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator ==(const U& lhs, const etl::optional<T>& rhs)
{
return bool(rhs) ? rhs.value() == lhs : false;
}
@ -755,7 +1071,7 @@ namespace etl
/// Inequality operator. cppreference 22
//**************************************************************************
template <typename T, typename U>
bool operator !=(const U& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator !=(const U& lhs, const etl::optional<T>& rhs)
{
return !(lhs == rhs);
}
@ -764,7 +1080,7 @@ namespace etl
/// Less than operator. cppreference 23
//***************************************************************************
template <typename T, typename U>
bool operator <(const etl::optional<T>& lhs, const U& rhs)
ETL_CONSTEXPR14 bool operator <(const etl::optional<T>& lhs, const U& rhs)
{
return bool(lhs) ? lhs.value() < rhs : true;
}
@ -773,7 +1089,7 @@ namespace etl
/// Less than operator. cppreference 24
//***************************************************************************
template <typename T, typename U>
bool operator <(const U& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator <(const U& lhs, const etl::optional<T>& rhs)
{
return bool(rhs) ? lhs < rhs.value() : false;
}
@ -782,7 +1098,7 @@ namespace etl
/// Less than equal operator. cppreference 25
//***************************************************************************
template <typename T, typename U>
bool operator <=(const etl::optional<T>& lhs, const U& rhs)
ETL_CONSTEXPR14 bool operator <=(const etl::optional<T>& lhs, const U& rhs)
{
return bool(lhs) ? lhs.value() <= rhs : true;
}
@ -791,7 +1107,7 @@ namespace etl
/// Less than equal operator. cppreference 26
//***************************************************************************
template <typename T, typename U>
bool operator <=(const U& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator <=(const U& lhs, const etl::optional<T>& rhs)
{
return bool(rhs) ? lhs <= rhs.value() : false;
}
@ -800,7 +1116,7 @@ namespace etl
/// Greater than operator. cppreference 27
//***************************************************************************
template <typename T, typename U>
bool operator >(const etl::optional<T>& lhs, const U& rhs)
ETL_CONSTEXPR14 bool operator >(const etl::optional<T>& lhs, const U& rhs)
{
return bool(lhs) ? lhs.value() > rhs : false;
}
@ -809,7 +1125,7 @@ namespace etl
/// Greater than operator. cppreference 28
//***************************************************************************
template <typename T, typename U>
bool operator >(const U& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator >(const U& lhs, const etl::optional<T>& rhs)
{
return bool(rhs) ? lhs > rhs.value() : true;
}
@ -818,7 +1134,7 @@ namespace etl
/// Greater than equal operator. cppreference 29
//***************************************************************************
template <typename T, typename U>
bool operator >=(const etl::optional<T>& lhs, const U& rhs)
ETL_CONSTEXPR14 bool operator >=(const etl::optional<T>& lhs, const U& rhs)
{
return bool(lhs) ? lhs.value() >= rhs : false;
}
@ -827,7 +1143,7 @@ namespace etl
/// Greater than equal operator. cppreference 30
//***************************************************************************
template <typename T, typename U>
bool operator >=(const U& lhs, const etl::optional<T>& rhs)
ETL_CONSTEXPR14 bool operator >=(const U& lhs, const etl::optional<T>& rhs)
{
return bool(rhs) ? lhs >= rhs.value() : true;
}
@ -836,17 +1152,25 @@ namespace etl
/// Make an optional.
//***************************************************************************
template <typename T>
etl::optional<typename etl::decay<T>::type> make_optional(T& value)
ETL_CONSTEXPR14 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>
etl::optional(T) -> etl::optional<T>;
#endif
}
//*************************************************************************
/// Swaps the values.
//*************************************************************************
template <typename T>
void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
ETL_CONSTEXPR14 void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
{
lhs.swap(rhs);
}