diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-07 14:31:49 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-07 15:56:19 +0200 |
commit | f8942411ac68245edb8086186ccb45b91874e56b (patch) | |
tree | 2df3cea62e11543b289fba50d2cd4c7c727ed578 | |
parent | e54cc055ac62bbb74986baca509511fffe3aa84e (diff) | |
download | serenity-f8942411ac68245edb8086186ccb45b91874e56b.zip |
AK: Add forward() overload that refuses to forward lvalue as rvalue
This matches what other forward() implementations do.
-rw-r--r-- | AK/StdLibExtras.h | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/AK/StdLibExtras.h b/AK/StdLibExtras.h index c68f3c93e2..e0fba83309 100644 --- a/AK/StdLibExtras.h +++ b/AK/StdLibExtras.h @@ -81,17 +81,6 @@ inline T&& move(T& arg) # pragma clang diagnostic pop #endif -template<typename T> -struct Identity { - typedef T Type; -}; - -template<class T> -inline constexpr T&& forward(typename Identity<T>::Type& param) -{ - return static_cast<T&&>(param); -} - template<typename T, typename U> inline T exchange(T& a, U&& b) { @@ -151,6 +140,14 @@ typedef IntegralConstant<bool, false> FalseType; typedef IntegralConstant<bool, true> TrueType; template<class T> +struct IsLvalueReference : FalseType { +}; + +template<class T> +struct IsLvalueReference<T&> : TrueType { +}; + +template<class T> struct __IsPointerHelper : FalseType { }; @@ -293,11 +290,37 @@ struct Conditional<false, TrueType, FalseType> { typedef FalseType Type; }; +template<typename T> +struct RemoveReference { + typedef T Type; +}; +template<class T> +struct RemoveReference<T&> { + typedef T Type; +}; +template<class T> +struct RemoveReference<T&&> { + typedef T Type; +}; + +template<class T> +inline constexpr T&& forward(typename RemoveReference<T>::Type& param) +{ + return static_cast<T&&>(param); +} + +template<class T> +inline constexpr T&& forward(typename RemoveReference<T>::Type&& param) noexcept +{ + static_assert(!IsLvalueReference<T>::value, "Can't forward an rvalue as an lvalue."); + return static_cast<T&&>(param); +} + } -using AK::Conditional; using AK::ceil_div; using AK::clamp; +using AK::Conditional; using AK::exchange; using AK::forward; using AK::IsSame; |