Replace some usage of std::forward to static_cast.

For more details, See inline comment of include/boost/fusion/support/config.hpp .
This commit is contained in:
Kohei Takahashi
2014-11-25 22:23:55 +09:00
parent 687668c110
commit 9ab7774fd7
15 changed files with 61 additions and 32 deletions

View File

@ -43,7 +43,7 @@ namespace boost { namespace fusion
template <typename Arg>
BOOST_FUSION_GPU_ENABLED
back_extended_deque(Deque const& deque, Arg&& val)
: base(std::forward<Arg>(val), deque)
: base(BOOST_FUSION_FWD_ELEM(Arg, val), deque)
{}
#endif
};

View File

@ -139,7 +139,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
explicit deque(Head_&& head, Tail_&&... tail)
: base(detail::deque_keyed_values<Head, Tail...>
::forward_(std::forward<Head_>(head), std::forward<Tail_>(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<T>(rhs));
base::operator=(BOOST_FUSION_FWD_ELEM(T, rhs));
return *this;
}
#endif

View File

@ -136,7 +136,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
explicit deque(T0_&& t0
, typename enable_if<is_convertible<T0_, T0> >::type* /*dummy*/ = 0
)
: base(std::forward<T0_>(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<T>(rhs));
base::operator=(BOOST_FUSION_FWD_ELEM(T, rhs));
return *this;
}
#endif

View File

@ -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>(t##n)
#define FUSION_DEQUE_FORWARD_CTOR_FORWARD(z, n, _) BOOST_FUSION_FWD_ELEM(T_##n, t##n)
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>

View File

@ -20,7 +20,7 @@
#define FUSION_HASH #
#define FUSION_DEQUE_KEYED_VALUES_FORWARD(z, n, _) \
std::forward<BOOST_PP_CAT(T_, n)>(BOOST_PP_CAT(t, n))
BOOST_FUSION_FWD_ELEM(BOOST_PP_CAT(T_, n), BOOST_PP_CAT(t, n))
#define BOOST_PP_FILENAME_1 \
<boost/fusion/container/deque/detail/cpp03/deque_keyed_values_call.hpp>
@ -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<T_0>(t0),
return type(BOOST_FUSION_FWD_ELEM(T_0, t0),
deque_keyed_values_impl<
next_index
#if N > 1

View File

@ -45,9 +45,9 @@ namespace boost { namespace fusion { namespace detail
static type forward_(Head_&& head, Tail_&&... tail)
{
return type(
std::forward<Head_>(head)
BOOST_FUSION_FWD_ELEM(Head_, head)
, deque_keyed_values_impl<next_index, Tail_...>::
forward_(std::forward<Tail_>(tail)...)
forward_(BOOST_FUSION_FWD_ELEM(Tail_, tail)...)
);
}
};

View File

@ -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<Rest>(rhs.forward_base()))
, value_(std::forward<Value>(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<Rest>(*static_cast<Rest*>(this));
return BOOST_FUSION_FWD_ELEM(Rest, *static_cast<Rest*>(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>(rest))
, value_(std::forward<Value>(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<keyed_element>(rhs));
value_ = std::forward<Value>(rhs.value_);
value_ = BOOST_FUSION_FWD_ELEM(Value, rhs.value_);
return *this;
}
#endif

View File

@ -42,7 +42,7 @@ namespace boost { namespace fusion
template <typename Arg>
BOOST_FUSION_GPU_ENABLED
front_extended_deque(Deque const& deque, Arg&& val)
: base(std::forward<Arg>(val), deque)
: base(BOOST_FUSION_FWD_ELEM(Arg, val), deque)
{}
#endif
};

View File

@ -83,8 +83,8 @@ namespace boost { namespace fusion { namespace detail
BOOST_FUSION_GPU_ENABLED
map_impl(map_impl&& rhs)
: rest_type(std::forward<rest_type>(*static_cast<rest_type*>(&rhs)))
, element(std::forward<Pair>(rhs.element))
: rest_type(BOOST_FUSION_FWD_ELEM(rest_type, *static_cast<rest_type*>(&rhs)))
, element(BOOST_FUSION_FWD_ELEM(Pair, rhs.element))
{}
template <typename ...U>
@ -101,8 +101,8 @@ namespace boost { namespace fusion { namespace detail
BOOST_FUSION_GPU_ENABLED
map_impl(Pair&& element_, T&&... rest)
: rest_type(std::forward<T>(rest)...)
, element(std::forward<Pair>(element_))
: rest_type(BOOST_FUSION_FWD_ELEM(T, rest)...)
, element(BOOST_FUSION_FWD_ELEM(Pair, element_))
{}
template <typename Iterator>
@ -187,7 +187,7 @@ namespace boost { namespace fusion { namespace detail
map_impl& operator=(map_impl&& rhs)
{
rest_type::operator=(std::forward<map_impl>(rhs));
element = std::forward<Pair>(rhs.element);
element = BOOST_FUSION_FWD_ELEM(Pair, rhs.element);
return *this;
}

View File

@ -95,7 +95,7 @@ namespace boost { namespace fusion
template <typename First, typename ...T_>
BOOST_FUSION_GPU_ENABLED
map(First&& first, T_&&... rest)
: base_type(std::forward<First>(first), std::forward<T_>(rest)...)
: base_type(BOOST_FUSION_FWD_ELEM(First, first), BOOST_FUSION_FWD_ELEM(T_, rest)...)
{}
BOOST_FUSION_GPU_ENABLED

View File

@ -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<U##n>(_##n)
#define FUSION_FORWARD_CTOR_FORWARD(z, n, _) BOOST_FUSION_FWD_ELEM(U##n, _##n)
#define BOOST_PP_FILENAME_1 \
<boost/fusion/container/vector/detail/vector_forward_ctor.hpp>

View File

@ -19,16 +19,16 @@
m##n(other.m##n)
#define FUSION_VECTOR_CTOR_FORWARD(z, n, _) \
m##n(std::forward<T##n>(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<U##n>(_##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<U##n>(_##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<is_convertible<U0, T0> >::type* /*dummy*/ = 0
)
: base_type(std::forward<U0>(_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)) {}

View File

@ -174,7 +174,7 @@ FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
vector&
operator=(T&& rhs)
{
vec = std::forward<T>(rhs);
vec = BOOST_FUSION_FWD_ELEM(T, rhs);
return *this;
}
#endif

View File

@ -9,6 +9,7 @@
#define FUSION_SUPPORT_CONFIG_01092014_1718
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#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<long&&>(i) also fail.
//
// however, following one will work.
//
// int i;
// long &&l = static_cast<long &&>(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<type&&>(value)
#else
# define BOOST_FUSION_FWD_ELEM(type, value) std::forward<type>(value)
#endif
#endif

View File

@ -41,7 +41,7 @@ namespace boost { namespace fusion
BOOST_FUSION_GPU_ENABLED
pair(pair&& rhs)
: second(std::forward<Second>(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<is_lvalue_reference<Second2> >::type* /* dummy */ = 0
, typename boost::enable_if<is_convertible<Second2, Second> >::type* /*dummy*/ = 0
) : second(std::forward<Second>(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<Second>(rhs.second);
second = BOOST_FUSION_FWD_ELEM(Second, rhs.second);
return *this;
}
#endif