Commit 02fb0302 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Erase the invokers

Summary: [Folly] Erase the invokers. A catchy title, but forcibly inline the invoker call operators.

Reviewed By: vitaut

Differential Revision: D18035184

fbshipit-source-id: 5cf57d785523904a5260f7ed24c9ed34148370eb
parent 1bb7c1fb
...@@ -196,6 +196,20 @@ ...@@ -196,6 +196,20 @@
// Semantically includes the inline specifier. // Semantically includes the inline specifier.
#define FOLLY_ERASE FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN #define FOLLY_ERASE FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN
// FOLLY_ERASE_HACK_GCC
//
// Equivalent to FOLLY_ERASE, but without hiding under gcc. Useful when applied
// to a function which may sometimes be hidden separately, for example by being
// declared in an anonymous namespace, since in such cases with -Wattributes
// enabled, gcc would emit: 'visibility' attribute ignored.
//
// Semantically includes the inline specifier.
#if defined(__GNUC__) && !defined(__clang__)
#define FOLLY_ERASE_HACK_GCC FOLLY_ALWAYS_INLINE
#else
#define FOLLY_ERASE_HACK_GCC FOLLY_ERASE
#endif
// FOLLY_ERASE_TRYCATCH // FOLLY_ERASE_TRYCATCH
// //
// Equivalent to FOLLY_ERASE, but for code which might contain explicit // Equivalent to FOLLY_ERASE, but for code which might contain explicit
......
...@@ -57,13 +57,13 @@ namespace folly { ...@@ -57,13 +57,13 @@ namespace folly {
// mimic: std::invoke, C++17 // mimic: std::invoke, C++17
template <typename F, typename... Args> template <typename F, typename... Args>
constexpr auto invoke(F&& f, Args&&... args) noexcept( FOLLY_ERASE constexpr auto invoke(F&& f, Args&&... args) noexcept(
noexcept(static_cast<F&&>(f)(static_cast<Args&&>(args)...))) noexcept(static_cast<F&&>(f)(static_cast<Args&&>(args)...)))
-> decltype(static_cast<F&&>(f)(static_cast<Args&&>(args)...)) { -> decltype(static_cast<F&&>(f)(static_cast<Args&&>(args)...)) {
return static_cast<F&&>(f)(static_cast<Args&&>(args)...); return static_cast<F&&>(f)(static_cast<Args&&>(args)...);
} }
template <typename M, typename C, typename... Args> template <typename M, typename C, typename... Args>
constexpr auto invoke(M(C::*d), Args&&... args) FOLLY_ERASE constexpr auto invoke(M(C::*d), Args&&... args)
-> decltype(std::mem_fn(d)(static_cast<Args&&>(args)...)) { -> decltype(std::mem_fn(d)(static_cast<Args&&>(args)...)) {
return std::mem_fn(d)(static_cast<Args&&>(args)...); return std::mem_fn(d)(static_cast<Args&&>(args)...);
} }
...@@ -363,7 +363,7 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> { ...@@ -363,7 +363,7 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> {
FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING(_, funcname, __VA_ARGS__) \ FOLLY_DETAIL_CREATE_FREE_INVOKE_TRAITS_USING(_, funcname, __VA_ARGS__) \
struct __folly_detail_invoke_obj { \ struct __folly_detail_invoke_obj { \
template <typename... Args> \ template <typename... Args> \
constexpr auto operator()(Args&&... args) const \ FOLLY_ERASE_HACK_GCC constexpr auto operator()(Args&&... args) const \
noexcept(noexcept(funcname(static_cast<Args&&>(args)...))) \ noexcept(noexcept(funcname(static_cast<Args&&>(args)...))) \
-> decltype(funcname(static_cast<Args&&>(args)...)) { \ -> decltype(funcname(static_cast<Args&&>(args)...)) { \
return funcname(static_cast<Args&&>(args)...); \ return funcname(static_cast<Args&&>(args)...); \
...@@ -416,10 +416,11 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> { ...@@ -416,10 +416,11 @@ struct invoke_traits : detail::invoke_traits_base<Invoke> {
#define FOLLY_CREATE_MEMBER_INVOKER(classname, membername) \ #define FOLLY_CREATE_MEMBER_INVOKER(classname, membername) \
struct classname { \ struct classname { \
template <typename O, typename... Args> \ template <typename O, typename... Args> \
constexpr auto operator()(O&& o, Args&&... args) const noexcept(noexcept( \ FOLLY_ERASE_HACK_GCC constexpr auto operator()(O&& o, Args&&... args) \
const noexcept(noexcept( \
static_cast<O&&>(o).membername(static_cast<Args&&>(args)...))) \ static_cast<O&&>(o).membername(static_cast<Args&&>(args)...))) \
-> decltype( \ -> decltype(static_cast<O&&>(o).membername( \
static_cast<O&&>(o).membername(static_cast<Args&&>(args)...)) { \ static_cast<Args&&>(args)...)) { \
return static_cast<O&&>(o).membername(static_cast<Args&&>(args)...); \ return static_cast<O&&>(o).membername(static_cast<Args&&>(args)...); \
} \ } \
} }
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