Commit 4aeeb1f6 authored by Aaryaman Sagar's avatar Aaryaman Sagar Committed by Facebook Github Bot

forward_tuple

Summary:
Given a tuple, return a tuple of references whose value categories are derived
from the value category of the input tuple

Given this, revert to the exact behavior `MQTTChannel` had prior to D8248199.

Reviewed By: mzlee

Differential Revision: D8698755

fbshipit-source-id: c9b68a3f344c6bae25f612a38f5c22be9b7f87bc
parent 5cf47168
......@@ -39,6 +39,7 @@ namespace detail {
namespace apply_tuple {
namespace adl {
using std::get;
struct ApplyInvoke {
template <typename T>
using seq = index_sequence_for_tuple<std::remove_reference_t<T>>;
......@@ -50,6 +51,15 @@ struct ApplyInvoke {
return invoke(static_cast<F&&>(f), get<I>(static_cast<T&&>(t))...);
}
};
template <
typename Tuple,
std::size_t... Indices,
typename ReturnTuple =
std::tuple<decltype(get<Indices>(std::declval<Tuple>()))...>>
auto forward_tuple(Tuple&& tuple, index_sequence<Indices...>) -> ReturnTuple {
return ReturnTuple{get<Indices>(std::forward<Tuple>(tuple))...};
}
} // namespace adl
} // namespace apply_tuple
} // namespace detail
......@@ -80,6 +90,33 @@ constexpr decltype(auto) apply(F&& func, Tuple&& tuple) {
#endif // __cpp_lib_apply >= 201603
/**
* Get a tuple of references from the passed tuple, forwarding will be applied
* on the individual types of the tuple based on the value category of the
* passed tuple
*
* For example
*
* forward_tuple(std::make_tuple(1, 2))
*
* Returns a std::tuple<int&&, int&&>,
*
* auto tuple = std::make_tuple(1, 2);
* forward_tuple(tuple)
*
* Returns a std::tuple<int&, int&>
*/
template <typename Tuple>
auto forward_tuple(Tuple&& tuple) noexcept
-> decltype(detail::apply_tuple::adl::forward_tuple(
std::declval<Tuple>(),
std::declval<
index_sequence_for_tuple<std::remove_reference_t<Tuple>>>())) {
return detail::apply_tuple::adl::forward_tuple(
std::forward<Tuple>(tuple),
index_sequence_for_tuple<std::remove_reference_t<Tuple>>{});
}
/**
* Mimic the invoke suite of traits for tuple based apply invocation
*/
......
......@@ -551,3 +551,44 @@ TEST(IsNothrowApplicableR, Basic) {
std::tuple<int, double>>::value));
}
}
TEST(ForwardTuple, Basic) {
auto tuple = std::make_tuple(1, 2.0);
EXPECT_TRUE((std::is_same<
decltype(folly::forward_tuple(tuple)),
std::tuple<int&, double&>>::value));
EXPECT_EQ(folly::forward_tuple(tuple), tuple);
EXPECT_TRUE((std::is_same<
decltype(folly::forward_tuple(folly::as_const(tuple))),
std::tuple<const int&, const double&>>::value));
EXPECT_EQ(folly::forward_tuple(folly::as_const(tuple)), tuple);
EXPECT_TRUE((std::is_same<
decltype(folly::forward_tuple(std::move(tuple))),
std::tuple<int&&, double&&>>::value));
EXPECT_EQ(folly::forward_tuple(std::move(tuple)), tuple);
EXPECT_TRUE(
(std::is_same<
decltype(folly::forward_tuple(std::move(folly::as_const(tuple)))),
std::tuple<const int&, const double&>>::value));
EXPECT_EQ(folly::forward_tuple(std::move(folly::as_const(tuple))), tuple);
auto integer = 1;
auto floating_point = 2.0;
auto ref_tuple = std::forward_as_tuple(integer, std::move(floating_point));
EXPECT_TRUE((std::is_same<
decltype(folly::forward_tuple(ref_tuple)),
std::tuple<int&, double&>>::value));
EXPECT_TRUE((std::is_same<
decltype(folly::forward_tuple(std::move(ref_tuple))),
std::tuple<int&, double&&>>::value));
EXPECT_TRUE((std::is_same<
decltype(std::tuple_cat(
folly::forward_tuple(tuple),
folly::forward_tuple(std::move(tuple)))),
std::tuple<int&, double&, int&&, double&&>>::value));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment