From f1fbb45134065deebe95249c616a967d4b66c809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 13 Mar 2023 13:32:29 +0100 Subject: [PATCH] Use [[msvc::intrinsic] attribute if available in move/forward in order to improve debug experience --- include/boost/move/detail/workaround.hpp | 14 ++++++++++++++ include/boost/move/utility.hpp | 4 ++-- include/boost/move/utility_core.hpp | 9 ++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/boost/move/detail/workaround.hpp b/include/boost/move/detail/workaround.hpp index 1ca5c1d..2fcd027 100644 --- a/include/boost/move/detail/workaround.hpp +++ b/include/boost/move/detail/workaround.hpp @@ -130,5 +130,19 @@ template struct static_assert_test {}; #endif +#if !defined(__has_cpp_attribute) || defined(__CUDACC__) +#define BOOST_MOVE_HAS_MSVC_ATTRIBUTE(ATTR) 0 +#else +#define BOOST_MOVE_HAS_MSVC_ATTRIBUTE(ATTR) __has_cpp_attribute(msvc::ATTR) +#endif + +// See https://devblogs.microsoft.com/cppblog/improving-the-state-of-debug-performance-in-c/ +// for details on how MSVC has improved debug experience, specifically for move/forward-like utilities +#if BOOST_MOVE_HAS_MSVC_ATTRIBUTE(intrinsic) +#define BOOST_MOVE_INTRINSIC_CAST [[msvc::intrinsic]] +#else +#define BOOST_MOVE_INTRINSIC_CAST BOOST_MOVE_FORCEINLINE +#endif + #endif //#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP diff --git a/include/boost/move/utility.hpp b/include/boost/move/utility.hpp index 28de793..9c94d77 100644 --- a/include/boost/move/utility.hpp +++ b/include/boost/move/utility.hpp @@ -126,13 +126,13 @@ #else //BOOST_MOVE_DOXYGEN_INVOKED template - BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + BOOST_MOVE_INTRINSIC_CAST typename ::boost::move_detail::enable_if_c < ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable::value, T&&>::type move_if_noexcept(T& x) BOOST_NOEXCEPT { return ::boost::move(x); } template - BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + BOOST_MOVE_INTRINSIC_CAST typename ::boost::move_detail::enable_if_c < !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable::value, const T&>::type move_if_noexcept(T& x) BOOST_NOEXCEPT { return x; } diff --git a/include/boost/move/utility_core.hpp b/include/boost/move/utility_core.hpp index 814ba08..907b764 100644 --- a/include/boost/move/utility_core.hpp +++ b/include/boost/move/utility_core.hpp @@ -208,7 +208,8 @@ #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES template - BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::remove_reference::type && move(T&& t) BOOST_NOEXCEPT + BOOST_MOVE_INTRINSIC_CAST + typename ::boost::move_detail::remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return static_cast::type &&>(t); } #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES @@ -244,11 +245,13 @@ #else //Old move template - BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT + BOOST_MOVE_INTRINSIC_CAST + T&& forward(typename ::boost::move_detail::remove_reference::type& t) BOOST_NOEXCEPT { return static_cast(t); } template - BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT + BOOST_MOVE_INTRINSIC_CAST + T&& forward(typename ::boost::move_detail::remove_reference::type&& t) BOOST_NOEXCEPT { //"boost::forward error: 'T' is a lvalue reference, can't forward as rvalue."; BOOST_MOVE_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference::value);