From 687668c11024976877fc798f446533266c8e9d3b Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Mon, 24 Nov 2014 03:07:16 +0900 Subject: [PATCH 1/3] Fix sprious compile error on VS2015 Preview. MSVC 2015 Preview will treat unary-ctor call as a variable declaration even if member call follows, which member has the same name with any other class (i.e. there are no relations between the member and such class). This issue already reported at [1]. 1. https://connect.microsoft.com/VisualStudio/feedback/details/1037783/unary-ctor-call-v-s-variable-decl struct foo { foo(int) {} void set() {} }; struct set; int main() { int i; foo(i).set(); // VS2015 try to decl `i` here and conflict with above. } --- include/boost/fusion/sequence/io/detail/manip.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/fusion/sequence/io/detail/manip.hpp b/include/boost/fusion/sequence/io/detail/manip.hpp index 8d8c296d..ec8ce304 100644 --- a/include/boost/fusion/sequence/io/detail/manip.hpp +++ b/include/boost/fusion/sequence/io/detail/manip.hpp @@ -235,14 +235,16 @@ namespace boost { namespace fusion template \ Stream& operator>>(Stream& s, const name##_type& m) \ { \ - string_ios_manip(s).set(m.data); \ + string_ios_manip manip(s); \ + manip.set(m.data); \ return s; \ } \ \ template \ Stream& operator<<(Stream& s, const name##_type& m) \ { \ - string_ios_manip(s).set(m.data); \ + string_ios_manip manip(s); \ + manip.set(m.data); \ return s; \ } \ } \ From 9ab7774fd7023031e60813bc76da859161c1396a Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Tue, 25 Nov 2014 22:23:55 +0900 Subject: [PATCH 2/3] 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 From fbbfc16d2da9f27ae4198b81aed5fc1e2b56731c Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Wed, 26 Nov 2014 01:49:07 +0900 Subject: [PATCH 3/3] Workaround for MSVC8.0 I'm not sure why it doesn't compile... --- include/boost/fusion/support/is_sequence.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/fusion/support/is_sequence.hpp b/include/boost/fusion/support/is_sequence.hpp index 8b582104..6b9b2118 100644 --- a/include/boost/fusion/support/is_sequence.hpp +++ b/include/boost/fusion/support/is_sequence.hpp @@ -32,7 +32,7 @@ namespace boost { namespace fusion { template struct apply - : is_convertible + : is_convertible {}; }; @@ -69,7 +69,7 @@ namespace boost { namespace fusion template struct is_native_fusion_sequence - : is_convertible + : is_convertible {}; } }}