From 9ab7774fd7023031e60813bc76da859161c1396a Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Tue, 25 Nov 2014 22:23:55 +0900 Subject: [PATCH] Replace some usage of std::forward to static_cast. For more details, See inline comment of include/boost/fusion/support/config.hpp . --- .../container/deque/back_extended_deque.hpp | 2 +- .../boost/fusion/container/deque/deque.hpp | 4 +-- .../container/deque/detail/cpp03/deque.hpp | 4 +-- .../deque/detail/cpp03/deque_forward_ctor.hpp | 2 +- .../detail/cpp03/deque_keyed_values_call.hpp | 4 +-- .../deque/detail/deque_keyed_values.hpp | 4 +-- .../container/deque/detail/keyed_element.hpp | 12 ++++---- .../container/deque/front_extended_deque.hpp | 2 +- .../fusion/container/map/detail/map_impl.hpp | 10 +++---- include/boost/fusion/container/map/map.hpp | 2 +- .../vector/detail/vector_forward_ctor.hpp | 2 +- .../container/vector/detail/vector_n.hpp | 8 ++--- .../boost/fusion/container/vector/vector.hpp | 2 +- include/boost/fusion/support/config.hpp | 29 +++++++++++++++++++ include/boost/fusion/support/pair.hpp | 6 ++-- 15 files changed, 61 insertions(+), 32 deletions(-) diff --git a/include/boost/fusion/container/deque/back_extended_deque.hpp b/include/boost/fusion/container/deque/back_extended_deque.hpp index a99acc7a..206b9285 100644 --- a/include/boost/fusion/container/deque/back_extended_deque.hpp +++ b/include/boost/fusion/container/deque/back_extended_deque.hpp @@ -43,7 +43,7 @@ namespace boost { namespace fusion template BOOST_FUSION_GPU_ENABLED back_extended_deque(Deque const& deque, Arg&& val) - : base(std::forward(val), deque) + : base(BOOST_FUSION_FWD_ELEM(Arg, val), deque) {} #endif }; diff --git a/include/boost/fusion/container/deque/deque.hpp b/include/boost/fusion/container/deque/deque.hpp index d8692397..318cc96d 100644 --- a/include/boost/fusion/container/deque/deque.hpp +++ b/include/boost/fusion/container/deque/deque.hpp @@ -139,7 +139,7 @@ namespace boost { namespace fusion BOOST_FUSION_GPU_ENABLED explicit deque(Head_&& head, Tail_&&... tail) : base(detail::deque_keyed_values - ::forward_(std::forward(head), std::forward(tail)...)) + ::forward_(BOOST_FUSION_FWD_ELEM(Head_, head), BOOST_FUSION_FWD_ELEM(Tail_, tail)...)) {} #endif @@ -171,7 +171,7 @@ namespace boost { namespace fusion BOOST_FUSION_GPU_ENABLED deque& operator=(T&& rhs) { - base::operator=(std::forward(rhs)); + base::operator=(BOOST_FUSION_FWD_ELEM(T, rhs)); return *this; } #endif diff --git a/include/boost/fusion/container/deque/detail/cpp03/deque.hpp b/include/boost/fusion/container/deque/detail/cpp03/deque.hpp index 2dd7f638..3b9de662 100644 --- a/include/boost/fusion/container/deque/detail/cpp03/deque.hpp +++ b/include/boost/fusion/container/deque/detail/cpp03/deque.hpp @@ -136,7 +136,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) explicit deque(T0_&& t0 , typename enable_if >::type* /*dummy*/ = 0 ) - : base(std::forward(t0), detail::nil_keyed_element()) + : base(BOOST_FUSION_FWD_ELEM(T0_, t0), detail::nil_keyed_element()) {} BOOST_FUSION_GPU_ENABLED explicit deque(deque&& rhs) @@ -152,7 +152,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) deque& operator=(T&& rhs) { - base::operator=(std::forward(rhs)); + base::operator=(BOOST_FUSION_FWD_ELEM(T, rhs)); return *this; } #endif diff --git a/include/boost/fusion/container/deque/detail/cpp03/deque_forward_ctor.hpp b/include/boost/fusion/container/deque/detail/cpp03/deque_forward_ctor.hpp index 7b12d58c..b62d4760 100644 --- a/include/boost/fusion/container/deque/detail/cpp03/deque_forward_ctor.hpp +++ b/include/boost/fusion/container/deque/detail/cpp03/deque_forward_ctor.hpp @@ -13,7 +13,7 @@ #error "C++03 only! This file should not have been included" #endif -#define FUSION_DEQUE_FORWARD_CTOR_FORWARD(z, n, _) std::forward(t##n) +#define FUSION_DEQUE_FORWARD_CTOR_FORWARD(z, n, _) BOOST_FUSION_FWD_ELEM(T_##n, t##n) #include #include diff --git a/include/boost/fusion/container/deque/detail/cpp03/deque_keyed_values_call.hpp b/include/boost/fusion/container/deque/detail/cpp03/deque_keyed_values_call.hpp index dcd9257d..5fb1164a 100644 --- a/include/boost/fusion/container/deque/detail/cpp03/deque_keyed_values_call.hpp +++ b/include/boost/fusion/container/deque/detail/cpp03/deque_keyed_values_call.hpp @@ -20,7 +20,7 @@ #define FUSION_HASH # #define FUSION_DEQUE_KEYED_VALUES_FORWARD(z, n, _) \ - std::forward(BOOST_PP_CAT(t, n)) + BOOST_FUSION_FWD_ELEM(BOOST_PP_CAT(T_, n), BOOST_PP_CAT(t, n)) #define BOOST_PP_FILENAME_1 \ @@ -55,7 +55,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_FUSION_GPU_ENABLED static type forward_(BOOST_PP_ENUM_BINARY_PARAMS(N, T_, && t)) { - return type(std::forward(t0), + return type(BOOST_FUSION_FWD_ELEM(T_0, t0), deque_keyed_values_impl< next_index #if N > 1 diff --git a/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp b/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp index 9bcffeb2..0d3d3dea 100644 --- a/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp +++ b/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp @@ -45,9 +45,9 @@ namespace boost { namespace fusion { namespace detail static type forward_(Head_&& head, Tail_&&... tail) { return type( - std::forward(head) + BOOST_FUSION_FWD_ELEM(Head_, head) , deque_keyed_values_impl:: - forward_(std::forward(tail)...) + forward_(BOOST_FUSION_FWD_ELEM(Tail_, tail)...) ); } }; diff --git a/include/boost/fusion/container/deque/detail/keyed_element.hpp b/include/boost/fusion/container/deque/detail/keyed_element.hpp index 05258820..37aba9fd 100644 --- a/include/boost/fusion/container/deque/detail/keyed_element.hpp +++ b/include/boost/fusion/container/deque/detail/keyed_element.hpp @@ -59,8 +59,8 @@ namespace boost { namespace fusion { namespace detail #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_FUSION_GPU_ENABLED keyed_element(keyed_element&& rhs) - : Rest(std::forward(rhs.forward_base())) - , value_(std::forward(rhs.value_)) + : Rest(BOOST_FUSION_FWD_ELEM(Rest, rhs.forward_base())) + , value_(BOOST_FUSION_FWD_ELEM(Value, rhs.value_)) {} #endif @@ -89,7 +89,7 @@ namespace boost { namespace fusion { namespace detail BOOST_FUSION_GPU_ENABLED Rest&& forward_base() { - return std::forward(*static_cast(this)); + return BOOST_FUSION_FWD_ELEM(Rest, *static_cast(this)); } #endif @@ -115,8 +115,8 @@ namespace boost { namespace fusion { namespace detail #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_FUSION_GPU_ENABLED keyed_element(Value&& value, Rest&& rest) - : Rest(std::forward(rest)) - , value_(std::forward(value)) + : Rest(BOOST_FUSION_FWD_ELEM(Rest, rest)) + , value_(BOOST_FUSION_FWD_ELEM(Value, value)) {} #endif @@ -147,7 +147,7 @@ namespace boost { namespace fusion { namespace detail keyed_element& operator=(keyed_element&& rhs) { base::operator=(std::forward(rhs)); - value_ = std::forward(rhs.value_); + value_ = BOOST_FUSION_FWD_ELEM(Value, rhs.value_); return *this; } #endif diff --git a/include/boost/fusion/container/deque/front_extended_deque.hpp b/include/boost/fusion/container/deque/front_extended_deque.hpp index 31336f31..48f1574a 100644 --- a/include/boost/fusion/container/deque/front_extended_deque.hpp +++ b/include/boost/fusion/container/deque/front_extended_deque.hpp @@ -42,7 +42,7 @@ namespace boost { namespace fusion template BOOST_FUSION_GPU_ENABLED front_extended_deque(Deque const& deque, Arg&& val) - : base(std::forward(val), deque) + : base(BOOST_FUSION_FWD_ELEM(Arg, val), deque) {} #endif }; diff --git a/include/boost/fusion/container/map/detail/map_impl.hpp b/include/boost/fusion/container/map/detail/map_impl.hpp index 2e0f50cc..4b4baadb 100644 --- a/include/boost/fusion/container/map/detail/map_impl.hpp +++ b/include/boost/fusion/container/map/detail/map_impl.hpp @@ -83,8 +83,8 @@ namespace boost { namespace fusion { namespace detail BOOST_FUSION_GPU_ENABLED map_impl(map_impl&& rhs) - : rest_type(std::forward(*static_cast(&rhs))) - , element(std::forward(rhs.element)) + : rest_type(BOOST_FUSION_FWD_ELEM(rest_type, *static_cast(&rhs))) + , element(BOOST_FUSION_FWD_ELEM(Pair, rhs.element)) {} template @@ -101,8 +101,8 @@ namespace boost { namespace fusion { namespace detail BOOST_FUSION_GPU_ENABLED map_impl(Pair&& element_, T&&... rest) - : rest_type(std::forward(rest)...) - , element(std::forward(element_)) + : rest_type(BOOST_FUSION_FWD_ELEM(T, rest)...) + , element(BOOST_FUSION_FWD_ELEM(Pair, element_)) {} template @@ -187,7 +187,7 @@ namespace boost { namespace fusion { namespace detail map_impl& operator=(map_impl&& rhs) { rest_type::operator=(std::forward(rhs)); - element = std::forward(rhs.element); + element = BOOST_FUSION_FWD_ELEM(Pair, rhs.element); return *this; } diff --git a/include/boost/fusion/container/map/map.hpp b/include/boost/fusion/container/map/map.hpp index 80e53ee7..1d308e96 100644 --- a/include/boost/fusion/container/map/map.hpp +++ b/include/boost/fusion/container/map/map.hpp @@ -95,7 +95,7 @@ namespace boost { namespace fusion template BOOST_FUSION_GPU_ENABLED map(First&& first, T_&&... rest) - : base_type(std::forward(first), std::forward(rest)...) + : base_type(BOOST_FUSION_FWD_ELEM(First, first), BOOST_FUSION_FWD_ELEM(T_, rest)...) {} BOOST_FUSION_GPU_ENABLED diff --git a/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp b/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp index 1d2217de..ff8aaccd 100644 --- a/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp +++ b/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp @@ -8,7 +8,7 @@ #if !defined(FUSION_VECTOR_FORWARD_CTOR_07122005_1123) #define FUSION_VECTOR_FORWARD_CTOR_07122005_1123 -#define FUSION_FORWARD_CTOR_FORWARD(z, n, _) std::forward(_##n) +#define FUSION_FORWARD_CTOR_FORWARD(z, n, _) BOOST_FUSION_FWD_ELEM(U##n, _##n) #define BOOST_PP_FILENAME_1 \ diff --git a/include/boost/fusion/container/vector/detail/vector_n.hpp b/include/boost/fusion/container/vector/detail/vector_n.hpp index ce0a33f0..2196e7f2 100644 --- a/include/boost/fusion/container/vector/detail/vector_n.hpp +++ b/include/boost/fusion/container/vector/detail/vector_n.hpp @@ -19,16 +19,16 @@ m##n(other.m##n) #define FUSION_VECTOR_CTOR_FORWARD(z, n, _) \ - m##n(std::forward(other.m##n)) + m##n(BOOST_FUSION_FWD_ELEM(T##n, other.m##n)) #define FUSION_VECTOR_CTOR_ARG_FWD(z, n, _) \ - m##n(std::forward(_##n)) + m##n(BOOST_FUSION_FWD_ELEM(U##n, _##n)) #define FUSION_VECTOR_MEMBER_DECL(z, n, _) \ T##n m##n; #define FUSION_VECTOR_MEMBER_FORWARD(z, n, _) \ - std::forward(_##n) + BOOST_FUSION_FWD_ELEM(U##n, _##n) #define FUSION_VECTOR_MEMBER_ASSIGN(z, n, _) \ this->BOOST_PP_CAT(m, n) = vec.BOOST_PP_CAT(m, n); @@ -164,7 +164,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_PP_CAT(vector, N)(U0&& _0 , typename boost::enable_if >::type* /*dummy*/ = 0 ) - : base_type(std::forward(_0)) {} + : base_type(BOOST_FUSION_FWD_ELEM(U0, _0)) {} #else BOOST_PP_CAT(vector, N)(BOOST_PP_ENUM_BINARY_PARAMS(N, U, && arg)) : base_type(BOOST_PP_ENUM(N, FUSION_VECTOR_MEMBER_FORWARD, arg)) {} diff --git a/include/boost/fusion/container/vector/vector.hpp b/include/boost/fusion/container/vector/vector.hpp index 336998f4..2dd584b5 100644 --- a/include/boost/fusion/container/vector/vector.hpp +++ b/include/boost/fusion/container/vector/vector.hpp @@ -174,7 +174,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector& operator=(T&& rhs) { - vec = std::forward(rhs); + vec = BOOST_FUSION_FWD_ELEM(T, rhs); return *this; } #endif diff --git a/include/boost/fusion/support/config.hpp b/include/boost/fusion/support/config.hpp index 5bee7df8..15d4be6e 100644 --- a/include/boost/fusion/support/config.hpp +++ b/include/boost/fusion/support/config.hpp @@ -9,6 +9,7 @@ #define FUSION_SUPPORT_CONFIG_01092014_1718 #include +#include #ifndef BOOST_FUSION_GPU_ENABLED #define BOOST_FUSION_GPU_ENABLED BOOST_GPU_ENABLED @@ -39,4 +40,32 @@ namespace boost { namespace fusion { namespace detail #define BOOST_FUSION_BARRIER_BEGIN namespace barrier { #define BOOST_FUSION_BARRIER_END } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900)) +// All of rvalue-reference ready MSVC don't perform implicit conversion from +// fundamental type to rvalue-reference of another fundamental type [1]. +// +// Following example doesn't compile +// +// int i; +// long &&l = i; // sigh..., std::forward(i) also fail. +// +// however, following one will work. +// +// int i; +// long &&l = static_cast(i); +// +// OK, now can we replace all usage of std::forward to static_cast? -- I say NO! +// All of rvalue-reference ready Clang doesn't compile above static_cast usage [2], sigh... +// +// References: +// 1. https://connect.microsoft.com/VisualStudio/feedback/details/1037806/implicit-conversion-doesnt-perform-for-fund +// 2. http://llvm.org/bugs/show_bug.cgi?id=19917 +// +// Tentatively, we use static_cast to forward if run under MSVC. +# define BOOST_FUSION_FWD_ELEM(type, value) static_cast(value) +#else +# define BOOST_FUSION_FWD_ELEM(type, value) std::forward(value) +#endif + #endif diff --git a/include/boost/fusion/support/pair.hpp b/include/boost/fusion/support/pair.hpp index 965810de..b09c7b4b 100644 --- a/include/boost/fusion/support/pair.hpp +++ b/include/boost/fusion/support/pair.hpp @@ -41,7 +41,7 @@ namespace boost { namespace fusion BOOST_FUSION_GPU_ENABLED pair(pair&& rhs) - : second(std::forward(rhs.second)) {} + : second(BOOST_FUSION_FWD_ELEM(Second, rhs.second)) {} #endif @@ -56,7 +56,7 @@ namespace boost { namespace fusion pair(Second2&& val , typename boost::disable_if >::type* /* dummy */ = 0 , typename boost::enable_if >::type* /*dummy*/ = 0 - ) : second(std::forward(val)) {} + ) : second(BOOST_FUSION_FWD_ELEM(Second, val)) {} #endif @@ -84,7 +84,7 @@ namespace boost { namespace fusion BOOST_FUSION_GPU_ENABLED pair& operator=(pair&& rhs) { - second = std::forward(rhs.second); + second = BOOST_FUSION_FWD_ELEM(Second, rhs.second); return *this; } #endif