Commit 05490a16 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Permit multiple primary namespaces for free-invoke traits

Summary: [Folly] Permit multiple primary namespaces for free-invoke traits instead of just 0 or 1 primary namespace.

Reviewed By: vitaut

Differential Revision: D18113151

fbshipit-source-id: 57f7b76a89e6dbd88cc2584d72079fa7fd94fe53
parent 8718c37f
...@@ -19,6 +19,12 @@ ...@@ -19,6 +19,12 @@
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/facilities/is_empty_variadic.hpp>
#include <boost/preprocessor/list/for_each.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/tuple/to_list.hpp>
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/Preprocessor.h> #include <folly/Preprocessor.h>
#include <folly/Traits.h> #include <folly/Traits.h>
...@@ -239,6 +245,17 @@ struct free_invoke_proxy { ...@@ -239,6 +245,17 @@ struct free_invoke_proxy {
} // namespace detail } // namespace detail
} // namespace folly } // namespace folly
#define FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING_1(_, funcname, ns) \
using ns::funcname;
#define FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING(_, funcname, ...) \
BOOST_PP_EXPR_IIF( \
BOOST_PP_NOT(BOOST_PP_IS_EMPTY(__VA_ARGS__)), \
BOOST_PP_LIST_FOR_EACH( \
FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING_1, \
funcname, \
BOOST_PP_TUPLE_TO_LIST((__VA_ARGS__))))
/*** /***
* FOLLY_CREATE_FREE_INVOKE_TRAITS * FOLLY_CREATE_FREE_INVOKE_TRAITS
* *
...@@ -305,9 +322,9 @@ struct free_invoke_proxy { ...@@ -305,9 +322,9 @@ struct free_invoke_proxy {
* traits::is_nothrow_invocable_v<int, CanFoo, Car&&> // true * traits::is_nothrow_invocable_v<int, CanFoo, Car&&> // true
* traits::is_nothrow_invocable_v<char*, CanFoo, Car&&> // false * traits::is_nothrow_invocable_v<char*, CanFoo, Car&&> // false
* *
* When a name has a primary definition in a fixed namespace and alternate * When a name has one or more primary definition in a fixed set of namespaces
* definitions in the namespaces of its arguments, the primary definition may * and alternate definitions in the namespaces of its arguments, the primary
* automatically be found as follows: * definitions may automatically be found as follows:
* *
* FOLLY_CREATE_FREE_INVOKE_TRAITS(swap_invoke_traits, swap, std); * FOLLY_CREATE_FREE_INVOKE_TRAITS(swap_invoke_traits, swap, std);
* *
...@@ -327,13 +344,9 @@ struct free_invoke_proxy { ...@@ -327,13 +344,9 @@ struct free_invoke_proxy {
*/ */
#define FOLLY_CREATE_FREE_INVOKE_TRAITS(classname, funcname, ...) \ #define FOLLY_CREATE_FREE_INVOKE_TRAITS(classname, funcname, ...) \
namespace classname##__folly_detail_invoke_ns { \ namespace classname##__folly_detail_invoke_ns { \
namespace __folly_detail_invoke_base { \
FOLLY_MAYBE_UNUSED void funcname( \ FOLLY_MAYBE_UNUSED void funcname( \
::folly::detail::invoke_private_overload&); \ ::folly::detail::invoke_private_overload&); \
} \ FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING(_, funcname, __VA_ARGS__) \
using FB_ARG_2_OR_1( \
__folly_detail_invoke_base FOLLY_PP_DETAIL_APPEND_VA_ARG( \
__VA_ARGS__))::funcname; \
struct __folly_detail_invoke_obj { \ struct __folly_detail_invoke_obj { \
template <typename... Args> \ template <typename... Args> \
constexpr auto operator()(Args&&... args) const \ constexpr auto operator()(Args&&... args) const \
......
...@@ -84,8 +84,14 @@ struct Obj { ...@@ -84,8 +84,14 @@ struct Obj {
void swap(Obj&, Obj&) noexcept {} // no-op void swap(Obj&, Obj&) noexcept {} // no-op
} // namespace swappable } // namespace swappable
struct AltSwappable;
struct AltSwappableRet {};
namespace unswappable {
FOLLY_MAYBE_UNUSED AltSwappableRet swap(AltSwappable&, AltSwappable&);
} // namespace unswappable
FOLLY_CREATE_FREE_INVOKE_TRAITS(go_invoke_traits, go); FOLLY_CREATE_FREE_INVOKE_TRAITS(go_invoke_traits, go);
FOLLY_CREATE_FREE_INVOKE_TRAITS(swap_invoke_traits, swap, std); FOLLY_CREATE_FREE_INVOKE_TRAITS(swap_invoke_traits, swap, std, unswappable);
FOLLY_CREATE_FREE_INVOKE_TRAITS(unused_invoke_traits, definitely_unused_name_); FOLLY_CREATE_FREE_INVOKE_TRAITS(unused_invoke_traits, definitely_unused_name_);
} // namespace } // namespace
...@@ -214,6 +220,9 @@ TEST_F(InvokeTest, free_invoke_swap) { ...@@ -214,6 +220,9 @@ TEST_F(InvokeTest, free_invoke_swap) {
std::swap(x, y); std::swap(x, y);
EXPECT_EQ(4, x.x_); EXPECT_EQ(4, x.x_);
EXPECT_EQ(3, y.x_); EXPECT_EQ(3, y.x_);
EXPECT_TRUE((
traits::is_invocable_r_v<AltSwappableRet, AltSwappable&, AltSwappable&>));
} }
TEST_F(InvokeTest, member_invoke) { TEST_F(InvokeTest, member_invoke) {
......
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