33 lines
1.1 KiB
C
33 lines
1.1 KiB
C
|
#pragma once
|
||
|
|
||
|
namespace orange
|
||
|
{
|
||
|
struct FalseType { static constexpr bool Value = false; };
|
||
|
struct TrueType { static constexpr bool Value = true; };
|
||
|
|
||
|
template <typename T> struct IsLValueReference : FalseType {};
|
||
|
template <typename T> struct IsLValueReference<T&> : TrueType {};
|
||
|
|
||
|
template <typename T> struct RemoveReference_ { using Type = T; };
|
||
|
template <typename T> struct RemoveReference_<T&> { using Type = T; };
|
||
|
template <typename T> struct RemoveReference_<T&&> { using Type = T; };
|
||
|
|
||
|
template <typename T>
|
||
|
using RemoveReference = typename RemoveReference_<T>::Type;
|
||
|
|
||
|
template <typename T>
|
||
|
constexpr T&& Forward(RemoveReference<T>& t) { return static_cast<T&&>(t); }
|
||
|
|
||
|
template <typename T>
|
||
|
constexpr T&& Forward(RemoveReference<T>&& t)
|
||
|
{
|
||
|
static_assert(!IsLValueReference<T>::Value, "Can not forward an rvalue as an lvalue.");
|
||
|
return static_cast<T&&>(t);
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
constexpr RemoveReference<T>&& Move(T&& arg)
|
||
|
{
|
||
|
return static_cast<RemoveReference<T>&&>(arg);
|
||
|
}
|
||
|
}
|