Skip to content

Commit

Permalink
Refactored etl::forward_like for C++11 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
jwellbelove committed Jul 15, 2023
1 parent 73c96a4 commit 85ec267
Showing 1 changed file with 44 additions and 32 deletions.
76 changes: 44 additions & 32 deletions include/etl/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,45 +76,57 @@ namespace etl
/// If etl::remove_reference_t<T> is const then returns a const reference if U is an lvalue, otherwise a const rvalue reference.
/// If etl::remove_reference_t<T> is not const then returns a reference if U is an lvalue, otherwise an rvalue reference.
//******************************************************************************
//***********************************
/// T is const & lvalue.
//***********************************
template <typename T, typename U>
ETL_NODISCARD
ETL_CONSTEXPR14
auto&& forward_like(U&& u) ETL_NOEXCEPT
ETL_CONSTEXPR
etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, const etl::remove_reference_t<U>&>
forward_like(U&& u) ETL_NOEXCEPT
{
using TType = etl::remove_reference_t<T>;
using UType = etl::remove_reference_t<U>;
return static_cast<const etl::remove_reference_t<U>&>(u);
}

if ETL_IF_CONSTEXPR (etl::is_const<TType>::value)
{
// For const TType
if ETL_IF_CONSTEXPR (etl::is_lvalue_reference<T>::value)
{
// const lvalue
return static_cast<const UType&>(u);
}
else
{
// const rvalue
return static_cast<const UType&&>(u);
}
}
else
{
// For non-const TType
if ETL_IF_CONSTEXPR (etl::is_lvalue_reference<T>::value)
{
// lvalue
return static_cast<UType&>(u);
}
else
{
// rvalue
return static_cast<UType&&>(u);
}
}
//***********************************
/// T is const & rvalue.
//***********************************
template <typename T, typename U>
ETL_NODISCARD
ETL_CONSTEXPR
etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, const etl::remove_reference_t<U>&&>
forward_like(U&& u) ETL_NOEXCEPT
{
return static_cast<const etl::remove_reference_t<U>&&>(u);
}

//***********************************
/// T is not const & lvalue.
//***********************************
template <typename T, typename U>
ETL_NODISCARD
ETL_CONSTEXPR
etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&>
forward_like(U&& u) ETL_NOEXCEPT
{
return static_cast<etl::remove_reference_t<U>&>(u);
}

//***********************************
/// T is not const & rvalue.
//***********************************
template <typename T, typename U>
ETL_NODISCARD
ETL_CONSTEXPR
etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&&>
forward_like(U&& u) ETL_NOEXCEPT
{
return static_cast<etl::remove_reference_t<U>&&>(u);
}

//***********************************
// Defines the type that forward_like would cast to.
//***********************************
template <typename T, typename U>
using forward_like_t = decltype(etl::forward_like<T>(etl::declval<U&>()));
#endif
Expand Down

0 comments on commit 85ec267

Please sign in to comment.