Commit 4f622004 authored by Xiao Shi's avatar Xiao Shi Committed by Facebook Github Bot

backport `std::make_from_tuple` from C++17

Summary:
`std::make_from_tuple` constructs an object of type T, using the elements of the
tuple t as the arguments to the constructor. Backport.

For the unit test, I referred to
https://github.com/phalpern/uses-allocator/blob/711f6071a1230272de28c022400d678e7e9f0228/make_from_tuple.t.cpp

Reviewed By: yfeldblum

Differential Revision: D6808665

fbshipit-source-id: 257f27110c01da39b5415b02415d74f0b6062051
parent ab97d44a
...@@ -160,5 +160,32 @@ auto uncurry(F&& f) ...@@ -160,5 +160,32 @@ auto uncurry(F&& f)
std::forward<F>(f)); std::forward<F>(f));
} }
#if __cpp_lib_make_from_tuple || _MSC_VER
/* using override */ using std::make_from_tuple;
#else
namespace detail {
namespace apply_tuple {
template <class T>
struct Construct {
template <class... Args>
constexpr T operator()(Args&&... args) {
return T(std::forward<Args>(args)...);
}
};
} // namespace apply_tuple
} // namespace detail
// mimic: std::make_from_tuple, C++17
template <class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t) {
return applyTuple(
detail::apply_tuple::Construct<T>(), std::forward<Tuple>(t));
}
#endif
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
} // namespace folly } // namespace folly
...@@ -371,3 +371,33 @@ TEST(ApplyTuple, UncurryStdFind) { ...@@ -371,3 +371,33 @@ TEST(ApplyTuple, UncurryStdFind) {
return b % a == 0; return b % a == 0;
}))); })));
} }
namespace {
struct S {
template <typename... Args>
explicit S(Args&&... args) : tuple_(std::forward<Args>(args)...) {}
std::tuple<int, double, std::string> tuple_;
};
} // namespace
TEST(MakeFromTupleTest, make_from_tuple) {
S expected{42, 1.0, "foobar"};
// const lvalue ref
auto s1 = folly::make_from_tuple<S>(expected.tuple_);
EXPECT_EQ(expected.tuple_, s1.tuple_);
// rvalue ref
S sCopy{expected.tuple_};
auto s2 = folly::make_from_tuple<S>(std::move(sCopy.tuple_));
EXPECT_EQ(expected.tuple_, s2.tuple_);
EXPECT_TRUE(std::get<2>(sCopy.tuple_).empty());
// forward
std::string str{"foobar"};
auto s3 =
folly::make_from_tuple<S>(std::forward_as_tuple(42, 1.0, std::move(str)));
EXPECT_EQ(expected.tuple_, s3.tuple_);
EXPECT_TRUE(str.empty());
}
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