Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup: Remove AUTORET macro and clean up PassField overrides #64

Merged
merged 5 commits into from
Dec 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 45 additions & 41 deletions include/mp/proxy-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,14 @@ struct StructField
Struct& m_struct;

// clang-format off
template<typename A = Accessor> auto get() const -> AUTO_RETURN(A::get(this->m_struct))
template<typename A = Accessor> auto get() const -> decltype(A::get(this->m_struct)) { return A::get(this->m_struct); }
template<typename A = Accessor> auto has() const -> typename std::enable_if<A::optional, bool>::type { return A::getHas(m_struct); }
template<typename A = Accessor> auto has() const -> typename std::enable_if<!A::optional && A::boxed, bool>::type { return A::has(m_struct); }
template<typename A = Accessor> auto has() const -> typename std::enable_if<!A::optional && !A::boxed, bool>::type { return true; }
template<typename A = Accessor> auto want() const -> typename std::enable_if<A::requested, bool>::type { return A::getWant(m_struct); }
template<typename A = Accessor> auto want() const -> typename std::enable_if<!A::requested, bool>::type { return true; }

template<typename A = Accessor, typename... Args> auto set(Args&&... args) const -> AUTO_RETURN(A::set(this->m_struct, std::forward<Args>(args)...))
template<typename A = Accessor, typename... Args> auto init(Args&&... args) const -> AUTO_RETURN(A::init(this->m_struct, std::forward<Args>(args)...))
template<typename A = Accessor, typename... Args> decltype(auto) set(Args&&... args) const { return A::set(this->m_struct, std::forward<Args>(args)...); }
template<typename A = Accessor, typename... Args> decltype(auto) init(Args&&... args) const { return A::init(this->m_struct, std::forward<Args>(args)...); }
template<typename A = Accessor> auto setHas() const -> typename std::enable_if<A::optional>::type { return A::setHas(m_struct); }
template<typename A = Accessor> auto setHas() const -> typename std::enable_if<!A::optional>::type { }
template<typename A = Accessor> auto setWant() const -> typename std::enable_if<A::requested>::type { return A::setWant(m_struct); }
Expand All @@ -59,7 +58,7 @@ void CustomBuildField(TypeList<>,
Priority<1>,
ClientInvokeContext& invoke_context,
Output&& output,
typename std::enable_if<std::is_same<decltype(output.init()), Context::Builder>::value>::type* enable = nullptr)
typename std::enable_if<std::is_same<decltype(output.get()), Context::Builder>::value>::type* enable = nullptr)
{
auto& connection = invoke_context.connection;
auto& thread_context = invoke_context.thread_context;
Expand Down Expand Up @@ -106,8 +105,10 @@ kj::Promise<U> JoinPromises(kj::Promise<T>&& prom1, kj::Promise<U>&& prom2)
return prom1.then(kj::mvCapture(prom2, [](kj::Promise<U> prom2) { return prom2; }));
}

//! PassField override for mp.Context arguments. Return asynchronously and call
//! function on other thread found in context.
template <typename Accessor, typename ServerContext, typename Fn, typename... Args>
auto PassField(TypeList<>, ServerContext& server_context, const Fn& fn, const Args&... args) ->
auto PassField(Priority<1>, TypeList<>, ServerContext& server_context, const Fn& fn, Args&&... args) ->
typename std::enable_if<
std::is_same<decltype(Accessor::get(server_context.call_context.getParams())), Context::Reader>::value,
kj::Promise<typename ServerContext::CallContext>>::type
Expand Down Expand Up @@ -521,7 +522,7 @@ struct ProxyCallFn
InvokeContext m_proxy;

template <typename... CallParams>
auto operator()(CallParams&&... params) -> AUTO_RETURN(this->m_proxy->call(std::forward<CallParams>(params)...))
decltype(auto) operator()(CallParams&&... params) { return this->m_proxy->call(std::forward<CallParams>(params)...); }
};

template <typename FnR, typename... FnParams, typename Input, typename ReadDest>
Expand Down Expand Up @@ -762,10 +763,10 @@ struct ListOutput<::capnp::List<T, kind>>
size_t m_index;

// clang-format off
auto get() const -> AUTO_RETURN(this->m_builder[this->m_index])
auto init() const -> AUTO_RETURN(this->m_builder[this->m_index])
template<typename B = Builder, typename Arg> auto set(Arg&& arg) const -> AUTO_RETURN(static_cast<B&>(this->m_builder).set(m_index, std::forward<Arg>(arg)))
template<typename B = Builder, typename Arg> auto init(Arg&& arg) const -> AUTO_RETURN(static_cast<B&>(this->m_builder).init(m_index, std::forward<Arg>(arg)))
decltype(auto) get() const { return this->m_builder[this->m_index]; }
decltype(auto) init() const { return this->m_builder[this->m_index]; }
template<typename B = Builder, typename Arg> decltype(auto) set(Arg&& arg) const { return static_cast<B&>(this->m_builder).set(m_index, std::forward<Arg>(arg)); }
template<typename B = Builder, typename Arg> decltype(auto) init(Arg&& arg) const { return static_cast<B&>(this->m_builder).init(m_index, std::forward<Arg>(arg)); }
// clang-format on
};

Expand Down Expand Up @@ -978,8 +979,9 @@ void CustomBuildField(TypeList<LocalType> local_type,
BuildOne<0>(local_type, invoke_context, output.init(), value);
}

//! PassField override for C++ pointer arguments.
template <typename Accessor, typename LocalType, typename ServerContext, typename Fn, typename... Args>
void PassField(TypeList<LocalType*>, ServerContext& server_context, const Fn& fn, Args&&... args)
void PassField(Priority<1>, TypeList<LocalType*>, ServerContext& server_context, const Fn& fn, Args&&... args)
{
const auto& params = server_context.call_context.getParams();
const auto& input = Make<StructField, Accessor>(params);
Expand All @@ -1002,8 +1004,9 @@ void PassField(TypeList<LocalType*>, ServerContext& server_context, const Fn& fn
Make<StructField, Accessor>(results), param);
}

//! PassField override for callable interface reference arguments.
template <typename Accessor, typename LocalType, typename ServerContext, typename Fn, typename... Args>
auto PassField(TypeList<LocalType&>, ServerContext& server_context, Fn&& fn, Args&&... args)
auto PassField(Priority<1>, TypeList<LocalType&>, ServerContext& server_context, Fn&& fn, Args&&... args)
-> Require<typename decltype(Accessor::get(server_context.call_context.getParams()))::Calls>
{
// Just create a temporary ProxyClient if argument is a reference to an
Expand Down Expand Up @@ -1051,8 +1054,9 @@ void MaybeSetWant(LocalTypes, Priority<0>, Args&&...)
{
}

//! Default PassField implementation calling MaybeReadField/MaybeBuildField.
template <typename Accessor, typename LocalType, typename ServerContext, typename Fn, typename... Args>
void DefaultPassField(TypeList<LocalType>, ServerContext& server_context, Fn&& fn, Args&&... args)
void PassField(Priority<0>, TypeList<LocalType>, ServerContext& server_context, Fn&& fn, Args&&... args)
{
InvokeContext& invoke_context = server_context;
using ArgType = RemoveCvRef<LocalType>;
Expand All @@ -1074,6 +1078,18 @@ void DefaultPassField(TypeList<LocalType>, ServerContext& server_context, Fn&& f
Make<StructField, Accessor>(results), *param);
}

//! Default PassField implementation for count(0) arguments, calling ReadField/BuildField
template <typename Accessor, typename ServerContext, typename Fn, typename... Args>
void PassField(Priority<0>, TypeList<>, ServerContext& server_context, const Fn& fn, Args&&... args)
{
const auto& params = server_context.call_context.getParams();
const auto& input = Make<StructField, Accessor>(params);
ReadField(TypeList<>(), server_context, input);
fn.invoke(server_context, std::forward<Args>(args)...);
auto&& results = server_context.call_context.getResults();
BuildField(TypeList<>(), server_context, Make<StructField, Accessor>(results));
}

template <>
struct ProxyServer<ThreadMap> final : public virtual ThreadMap::Server
{
Expand Down Expand Up @@ -1103,18 +1119,6 @@ decltype(auto) CustomReadField(TypeList<>,
invoke_context.connection.m_thread_map = input.get();
}

template <typename Accessor, typename ServerContext, typename Fn, typename... Args>
auto PassField(TypeList<>, ServerContext& server_context, const Fn& fn, Args&&... args) -> typename std::enable_if<
std::is_same<decltype(Accessor::get(server_context.call_context.getParams())), ThreadMap::Client>::value>::type
{
const auto& params = server_context.call_context.getParams();
const auto& input = Make<StructField, Accessor>(params);
ReadField(TypeList<>(), server_context, input);
fn.invoke(server_context, std::forward<Args>(args)...);
auto&& results = server_context.call_context.getResults();
BuildField(TypeList<>(), server_context, Make<StructField, Accessor>(results));
}

template <typename Derived, size_t N = 0>
struct IterateFieldsHelper
{
Expand Down Expand Up @@ -1248,10 +1252,12 @@ struct ServerCall
{
// FIXME: maybe call call_context.releaseParams()
template <typename ServerContext, typename... Args>
auto invoke(ServerContext& server_context, TypeList<>, Args&&... args) const -> AUTO_RETURN(
ProxyServerMethodTraits<typename decltype(server_context.call_context.getParams())::Reads>::invoke(
decltype(auto) invoke(ServerContext& server_context, TypeList<>, Args&&... args) const
{
return ProxyServerMethodTraits<typename decltype(server_context.call_context.getParams())::Reads>::invoke(
server_context,
std::forward<Args>(args)...))
std::forward<Args>(args)...);
}
};

struct ServerDestroy
Expand Down Expand Up @@ -1299,16 +1305,12 @@ struct ServerExcept : Parent
template <class Accessor>
void CustomPassField();

// clang-format off
//! PassField override calling CustomPassField function, if it exists.
template <typename Accessor, typename... Args>
auto CallPassField(Priority<2>, Args&&... args) -> AUTO_RETURN(CustomPassField<Accessor>(std::forward<Args>(args)...));

template <typename Accessor, typename... Args>
auto CallPassField(Priority<1>, Args&&... args) -> AUTO_RETURN(PassField<Accessor>(std::forward<Args>(args)...));

template <typename Accessor, typename... Args>
auto CallPassField(Priority<0>, Args&&... args) -> AUTO_RETURN(DefaultPassField<Accessor>(std::forward<Args>(args)...));
// clang-format on
auto PassField(Priority<2>, Args&&... args) -> decltype(CustomPassField<Accessor>(std::forward<Args>(args)...))
{
return CustomPassField<Accessor>(std::forward<Args>(args)...);
};

template <int argc, typename Accessor, typename Parent>
struct ServerField : Parent
Expand All @@ -1318,13 +1320,15 @@ struct ServerField : Parent
const Parent& parent() const { return *this; }

template <typename ServerContext, typename ArgTypes, typename... Args>
auto invoke(ServerContext& server_context, ArgTypes, Args&&... args) const
-> AUTO_RETURN(CallPassField<Accessor>(Priority<2>(),
decltype(auto) invoke(ServerContext& server_context, ArgTypes, Args&&... args) const
{
return PassField<Accessor>(Priority<2>(),
typename Split<argc, ArgTypes>::First(),
server_context,
this->parent(),
typename Split<argc, ArgTypes>::Second(),
std::forward<Args>(args)...))
std::forward<Args>(args)...);
}
};

template <int argc, typename Accessor, typename Parent>
Expand Down
6 changes: 4 additions & 2 deletions include/mp/proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,10 @@ struct ProxyMethodTraits<MethodParams, Require<decltype(ProxyMethod<MethodParams
: public FunctionTraits<decltype(ProxyMethod<MethodParams>::impl)>
{
template <typename ServerContext, typename... Args>
static auto invoke(ServerContext& server_context, Args&&... args) -> AUTO_RETURN(
(server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...))
static decltype(auto) invoke(ServerContext& server_context, Args&&... args)
{
return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
}
};

//! Customizable (through template specialization) traits class used in generated ProxyClient implementations from
Expand Down
23 changes: 7 additions & 16 deletions include/mp/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,6 @@ namespace mp {
//! }
//! };

// C++11 workaround for C++14 auto return functions
// (http://en.cppreference.com/w/cpp/language/template_argument_deduction#auto-returning_functions)
#define AUTO_DO_RETURN(pre, x) \
decltype(x) \
{ \
pre; \
return x; \
}

#define AUTO_RETURN(x) AUTO_DO_RETURN(, x)

//! Type holding a list of types.
//!
//! Example:
Expand Down Expand Up @@ -102,7 +91,7 @@ struct ComposeFn
Fn2&& fn2;

template <typename... Args>
auto operator()(Args&&... args) -> AUTO_RETURN(this->fn1(this->fn2(std::forward<Args>(args)...)))
decltype(auto) operator()(Args&&... args) { return this->fn1(this->fn2(std::forward<Args>(args)...)); }
};

//! Bound function. See Bind() below.
Expand All @@ -116,8 +105,10 @@ struct BoundFn<Fn, TypeList<>, TypeList<BoundArgs...>>
Fn&& m_fn;

template <typename... FreeArgs>
auto operator()(BoundArgs&... bound_args, FreeArgs&&... free_args)
-> AUTO_RETURN(this->m_fn(bound_args..., std::forward<FreeArgs>(free_args)...))
decltype(auto) operator()(BoundArgs&... bound_args, FreeArgs&&... free_args)
{
return this->m_fn(bound_args..., std::forward<FreeArgs>(free_args)...);
}
};

//! Specialization of above for recursive case.
Expand All @@ -130,7 +121,7 @@ struct BoundFn<Fn, TypeList<BindArg, BindArgs...>, TypeList<BoundArgs...>>

BoundFn(Fn& fn, BindArg& bind_arg, BindArgs&... bind_args) : Base{fn, bind_args...}, m_bind_arg(bind_arg) {}

// Use std::result_of instead of AUTO_RETURN to work around gcc bug
// Use std::result_of instead of decltype return to work around gcc bug
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83249
template <typename... FreeArgs>
auto operator()(BoundArgs&... bound_args, FreeArgs&&... free_args) ->
Expand Down Expand Up @@ -167,7 +158,7 @@ struct BoundTupleFn
{
Fn& m_fn;
template <typename... Params>
auto operator()(Params&&... params) -> AUTO_RETURN(this->m_fn(std::forward_as_tuple(params...)))
decltype(auto) operator()(Params&&... params) { return this->m_fn(std::forward_as_tuple(params...)); }
};

//! Bind tuple argument to function. Arguments passed to the returned function
Expand Down
10 changes: 5 additions & 5 deletions src/mp/gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,12 @@ void Generate(kj::StringPtr src_prefix,
std::string cap = Cap(name);
accessors << "struct " << cap << "\n";
accessors << "{\n";
accessors << " template<typename S> static auto get(S&& s) -> AUTO_RETURN(s.get" << cap << "())\n";
accessors << " template<typename S> static auto get(S&& s) -> decltype(s.get" << cap << "()) { return s.get" << cap << "(); }\n";
accessors << " template<typename S> static bool has(S&& s) { return s.has" << cap << "(); }\n";
accessors << " template<typename S, typename A> static void set(S&& s, A&& a) { s.set" << cap
<< "(std::forward<A>(a)); }\n";
accessors << " template<typename S, typename... A> static auto init(S&& s, A&&... a) -> AUTO_RETURN(s.init"
<< cap << "(std::forward<A>(a)...))\n";
accessors << " template<typename S, typename... A> static decltype(auto) init(S&& s, A&&... a) { return s.init"
<< cap << "(std::forward<A>(a)...); }\n";
accessors << " template<typename S> static bool getWant(S&& s) { return s.getWant" << cap << "(); }\n";
accessors << " template<typename S> static void setWant(S&& s) { s.setWant" << cap << "(true); }\n";
accessors << " template<typename S> static bool getHas(S&& s) { return s.getHas" << cap << "(); }\n";
Expand Down Expand Up @@ -317,8 +317,8 @@ void Generate(kj::StringPtr src_prefix,
auto field_name = field.getProto().getName();
auto member_name = field_name;
GetAnnotationText(field.getProto(), NAME_ANNOTATION_ID, &member_name);
inl << " static auto get(std::integral_constant<size_t, " << i << ">) -> AUTO_RETURN("
<< "&" << proxied_class_type << "::" << member_name << ")\n";
inl << " static decltype(auto) get(std::integral_constant<size_t, " << i << ">) { return "
<< "&" << proxied_class_type << "::" << member_name << "; }\n";
++i;
}
inl << " static constexpr size_t fields = " << i << ";\n";
Expand Down