File forward_like.h
File List > module > utility > src > scl > utility > type_traits > forward_like.h
Go to the documentation of this file
#pragma once
#include <type_traits>
namespace scl::detail
{
// Add const from From onto To if From is const (ignoring reference)
template <typename From, typename To>
using add_const_from_t =
::std::conditional_t<::std::is_const_v<::std::remove_reference_t<From>>, ::std::add_const_t<To>, To>;
// Add volatile from From onto To if From is volatile (ignoring reference)
template <typename From, typename To>
using add_volatile_from_t =
::std::conditional_t<::std::is_volatile_v<::std::remove_reference_t<From>>, ::std::add_volatile_t<To>, To>;
// Add both const and volatile from From to To (ignoring reference)
template <typename From, typename To>
using add_cv_from_t = add_const_from_t<From, add_volatile_from_t<From, To>>;
// Copy ref from From onto To: if From is &, add &, if && add &&, else no reference.
//s Don't add reference to void.
template <typename From, typename To>
using add_reference_like_t = ::std::conditional_t<::std::is_lvalue_reference_v<From>,
::std::conditional_t<::std::is_void_v<To>, To, ::std::add_lvalue_reference_t<To>>,
::std::conditional_t<::std::is_rvalue_reference_v<From>,
::std::conditional_t<::std::is_void_v<To>, To, ::std::add_rvalue_reference_t<To>>,
To>>;
} // namespace scl::detail
namespace scl
{
template <typename Base, typename Type>
using forward_like_t = ::scl::detail::add_reference_like_t<Base,
::scl::detail::add_cv_from_t<Base, ::std::remove_reference_t<Type>>>;
template <typename Base, typename T>
constexpr decltype(auto) forward_like(T && t) noexcept // NOLINT(cppcoreguidelines-missing-std-forward)
{
return static_cast<forward_like_t<Base, T &&>>(t);
}
} // namespace scl