diff --git a/stl/inc/type_traits b/stl/inc/type_traits index d7179bc9d..c346f2523 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1423,26 +1423,25 @@ template class _Template> struct _Is_specialization : bool_constant<_Is_specialization_v<_Type, _Template>> {}; _EXPORT_STD template -_NODISCARD constexpr _Ty&& forward( - remove_reference_t<_Ty>& _Arg) noexcept { // forward an lvalue as either an lvalue or an rvalue +_NODISCARD _MSVC_INTRINSIC constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept { return static_cast<_Ty&&>(_Arg); } _EXPORT_STD template -_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept { // forward an rvalue as an rvalue +_NODISCARD _MSVC_INTRINSIC constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept { static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call"); return static_cast<_Ty&&>(_Arg); } _EXPORT_STD template -_NODISCARD constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept { // forward _Arg as movable +_NODISCARD _MSVC_INTRINSIC constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept { return static_cast&&>(_Arg); } _EXPORT_STD template -_NODISCARD constexpr conditional_t && is_copy_constructible_v<_Ty>, const _Ty&, - _Ty&&> - move_if_noexcept(_Ty& _Arg) noexcept { // forward _Arg as movable, sometimes +_NODISCARD _MSVC_INTRINSIC constexpr // + conditional_t && is_copy_constructible_v<_Ty>, const _Ty&, _Ty&&> + move_if_noexcept(_Ty& _Arg) noexcept { return _STD move(_Arg); } diff --git a/stl/inc/utility b/stl/inc/utility index 3e79e1d44..9ddd014d8 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -820,7 +820,7 @@ _EXPORT_STD [[noreturn]] __forceinline void unreachable() noexcept /* strengthen } _EXPORT_STD template -_NODISCARD constexpr auto&& forward_like(_Uty&& _Ux) noexcept { +_NODISCARD _MSVC_INTRINSIC constexpr auto&& forward_like(_Uty&& _Ux) noexcept { static_assert(_Can_reference<_Ty>, "std::forward_like's first template argument must be a referenceable type."); using _UnrefT = remove_reference_t<_Ty>; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 8d394c227..19b3c83e6 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -622,9 +622,11 @@ #pragma push_macro("msvc") #pragma push_macro("known_semantics") #pragma push_macro("noop_dtor") +#pragma push_macro("intrinsic") #undef msvc #undef known_semantics #undef noop_dtor +#undef intrinsic #ifndef __has_cpp_attribute #define _HAS_MSVC_ATTRIBUTE(x) 0 @@ -650,7 +652,16 @@ #define _MSVC_NOOP_DTOR #endif +// Should we use [[msvc::intrinsic]] allowing the compiler to implement the +// behavior of certain trivial functions? +#if _HAS_MSVC_ATTRIBUTE(intrinsic) +#define _MSVC_INTRINSIC [[msvc::intrinsic]] +#else +#define _MSVC_INTRINSIC +#endif + #undef _HAS_MSVC_ATTRIBUTE +#pragma pop_macro("intrinsic") #pragma pop_macro("noop_dtor") #pragma pop_macro("known_semantics") #pragma pop_macro("msvc")