Commit 91a18af1 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

invoke-qual macros

Summary: For invoking things given possible-qualified names. Differs from invoke-free as the latter accepts an optional list of namespaces scope to include in name lookup but does not permit qualified names and does not admit a lambda variation.

Reviewed By: Gownta

Differential Revision: D32670267

fbshipit-source-id: f9b9e33bd1e3cfa1c191eb8c91b3f50bb0e9734e
parent a97e36d6
......@@ -397,6 +397,46 @@ struct invoke_traits : detail::invoke_traits_base<I> {
FOLLY_CREATE_FREE_INVOKER(funcname##_fn, funcname, __VA_ARGS__); \
FOLLY_MAYBE_UNUSED FOLLY_INLINE_VARIABLE constexpr funcname##_fn funcname {}
/***
* FOLLY_CREATE_QUAL_INVOKER
*
* Used to create an invoker type bound to a specific free-invocable qualified
* name. It is permitted that the qualification be empty and that the name be
* unqualified in practice. This differs from FOLLY_CREATE_FREE_INVOKER in that
* it is required that the name be in scope and that it is not possible to
* provide a list of namespaces in which to look up the name..
*/
#define FOLLY_CREATE_QUAL_INVOKER(classname, funcpath) \
struct classname { \
template <typename... A> \
FOLLY_MAYBE_UNUSED FOLLY_ERASE_HACK_GCC constexpr auto operator()( \
A&&... a) const \
FOLLY_DETAIL_FORWARD_BODY(funcpath(static_cast<A&&>(a)...)) \
}
/***
* FOLLY_CREATE_QUAL_INVOKER_SUITE
*
* Used to create an invoker type and associated variable bound to a specific
* free-invocable qualified name.
*
* See FOLLY_CREATE_QUAL_INVOKER.
*/
#define FOLLY_CREATE_QUAL_INVOKER_SUITE(name, funcpath) \
FOLLY_CREATE_QUAL_INVOKER(name##_fn, funcpath); \
FOLLY_MAYBE_UNUSED FOLLY_INLINE_VARIABLE constexpr name##_fn name {}
/***
* FOLLY_INVOKE_QUAL
*
* An invoker expression resulting in an invocable which, when invoked, invokes
* the free-invocable qualified name with the given arguments.
*/
#define FOLLY_INVOKE_QUAL(funcpath) \
[](auto&&... __folly_param_a) \
FOLLY_LAMBDA_CONSTEXPR FOLLY_DETAIL_FORWARD_BODY( \
funcpath(FOLLY_DETAIL_FORWARD_REF(__folly_param_a)...))
/***
* FOLLY_CREATE_MEMBER_INVOKER
*
......
......@@ -87,6 +87,7 @@ namespace invoker {
FOLLY_CREATE_FREE_INVOKER_SUITE(go);
FOLLY_CREATE_FREE_INVOKER_SUITE(swap, std, unswappable);
FOLLY_CREATE_FREE_INVOKER_SUITE(no_such_thing);
FOLLY_CREATE_QUAL_INVOKER_SUITE(std_swap, ::std::swap);
} // namespace invoker
......@@ -221,6 +222,40 @@ TEST_F(InvokeTest, free_invoke_swap) {
traits::is_invocable_r_v<AltSwappableRet, AltSwappable&, AltSwappable&>));
}
TEST_F(InvokeTest, qual_invoke_swap) {
using traits = folly::invoke_traits<decltype(invoker::std_swap)>;
int a = 3;
int b = 4;
traits::invoke(a, b);
EXPECT_EQ(4, a);
EXPECT_EQ(3, b);
swappable::Obj x{3};
swappable::Obj y{4};
traits::invoke(x, y);
EXPECT_EQ(4, x.x_);
EXPECT_EQ(3, y.x_);
std::swap(x, y);
EXPECT_EQ(3, x.x_);
EXPECT_EQ(4, y.x_);
}
TEST_F(InvokeTest, invoke_qual) {
auto go = FOLLY_INVOKE_QUAL(::std::swap);
int a = 3;
int b = 4;
EXPECT_TRUE(noexcept(go(a, b)));
go(a, b);
EXPECT_EQ(4, a);
EXPECT_EQ(3, b);
}
TEST_F(InvokeTest, member_invoke) {
using traits = folly::invoke_traits<decltype(invoker::test)>;
......
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