@@ -37,20 +37,45 @@ struct StructField
37
37
}
38
38
Struct& m_struct;
39
39
40
- // clang-format off
41
- template <typename A = Accessor> auto get () const -> decltype(A::get(this ->m_struct)) { return A::get (this ->m_struct ); }
42
- template <typename A = Accessor> auto has () const -> std::enable_if_t<A::optional, bool> { return A::getHas (m_struct); }
43
- template <typename A = Accessor> auto has () const -> std::enable_if_t<!A::optional && A::boxed, bool> { return A::has (m_struct); }
44
- template <typename A = Accessor> auto has () const -> std::enable_if_t<!A::optional && !A::boxed, bool> { return true ; }
45
- template <typename A = Accessor> auto want () const -> std::enable_if_t<A::requested, bool> { return A::getWant (m_struct); }
46
- template <typename A = Accessor> auto want () const -> std::enable_if_t<!A::requested, bool> { return true ; }
47
- template <typename A = Accessor, typename ... Args> decltype (auto ) set(Args&&... args) const { return A::set (this ->m_struct , std::forward<Args>(args)...); }
48
- template <typename A = Accessor, typename ... Args> decltype (auto ) init(Args&&... args) const { return A::init (this ->m_struct , std::forward<Args>(args)...); }
49
- template <typename A = Accessor> auto setHas () const -> std::enable_if_t<A::optional> { return A::setHas (m_struct); }
50
- template <typename A = Accessor> auto setHas () const -> std::enable_if_t<!A::optional> { }
51
- template <typename A = Accessor> auto setWant () const -> std::enable_if_t<A::requested> { return A::setWant (m_struct); }
52
- template <typename A = Accessor> auto setWant () const -> std::enable_if_t<!A::requested> { }
53
- // clang-format on
40
+ decltype (auto ) get() const { return Accessor::get (this ->m_struct ); }
41
+
42
+ bool has () const {
43
+ if constexpr (Accessor::optional) {
44
+ return Accessor::getHas (m_struct);
45
+ } else if constexpr (Accessor::boxed) {
46
+ return Accessor::has (m_struct);
47
+ } else {
48
+ return true ;
49
+ }
50
+ }
51
+
52
+ bool want () const {
53
+ if constexpr (Accessor::requested) {
54
+ return Accessor::getWant (m_struct);
55
+ } else {
56
+ return true ;
57
+ }
58
+ }
59
+
60
+ template <typename ... Args> decltype (auto ) set(Args &&...args) const {
61
+ return Accessor::set (this ->m_struct , std::forward<Args>(args)...);
62
+ }
63
+
64
+ template <typename ... Args> decltype (auto ) init(Args &&...args) const {
65
+ return Accessor::init (this ->m_struct , std::forward<Args>(args)...);
66
+ }
67
+
68
+ void setHas () const {
69
+ if constexpr (Accessor::optional) {
70
+ Accessor::setHas (m_struct);
71
+ }
72
+ }
73
+
74
+ void setWant () const {
75
+ if constexpr (Accessor::requested) {
76
+ Accessor::setWant (m_struct);
77
+ }
78
+ }
54
79
};
55
80
56
81
@@ -360,34 +385,28 @@ struct ClientException
360
385
template <typename Accessor, typename ... Types>
361
386
struct ClientParam
362
387
{
363
- ClientParam (Types&&... values) : m_values(values...) {}
388
+ ClientParam (Types&&... values) : m_values{std::forward<Types> (values) ...} {}
364
389
365
390
struct BuildParams : IterateFieldsHelper<BuildParams, sizeof ...(Types)>
366
391
{
367
- template <typename ... Args>
368
- void handleField (Args&&... args)
369
- {
370
- callBuild<0 >(std::forward<Args>(args)...);
371
- }
372
-
373
- // TODO Possible optimization to speed up compile time:
374
- // https://stackoverflow.com/a/7858971 Using enable_if below to check
375
- // position when unpacking tuple might be slower than pattern matching
376
- // approach in the stack overflow solution
377
- template <size_t I, typename ... Args>
378
- auto callBuild (Args&&... args) -> std::enable_if_t<(I < sizeof ...(Types))>
379
- {
380
- callBuild<I + 1 >(std::forward<Args>(args)..., std::get<I>(m_client_param->m_values ));
381
- }
382
-
383
- template <size_t I, typename Params, typename ParamList, typename ... Values>
384
- auto callBuild (ClientInvokeContext& invoke_context, Params& params, ParamList, Values&&... values) ->
385
- std::enable_if_t<(I == sizeof ...(Types))>
392
+ template <typename Params, typename ParamList>
393
+ void handleField (ClientInvokeContext& invoke_context, Params& params, ParamList)
386
394
{
387
- MaybeBuildField (std::integral_constant<bool , Accessor::in>(), ParamList (), invoke_context,
388
- Make<StructField, Accessor>(params), std::forward<Values>(values)...);
389
- MaybeSetWant (
390
- ParamList (), Priority<1 >(), std::forward<Values>(values)..., Make<StructField, Accessor>(params));
395
+ auto const fun = [&]<typename ... Values>(Values&&... values) {
396
+ MaybeBuildField (std::integral_constant<bool , Accessor::in>(), ParamList (), invoke_context,
397
+ Make<StructField, Accessor>(params), std::forward<Values>(values)...);
398
+ MaybeSetWant (
399
+ ParamList (), Priority<1 >(), std::forward<Values>(values)..., Make<StructField, Accessor>(params));
400
+ };
401
+
402
+ // Note: The m_values tuple just consists of lvalue and rvalue
403
+ // references, so calling std::move doesn't change the tuple, it
404
+ // just causes std::apply to call the std::get overload that returns
405
+ // && instead of &, so rvalue references are preserved and not
406
+ // turned into lvalue references. This allows the BuildField call to
407
+ // move from the argument if it is an rvalue reference or was passed
408
+ // by value.
409
+ std::apply (fun, std::move (m_client_param->m_values ));
391
410
}
392
411
393
412
BuildParams (ClientParam* client_param) : m_client_param(client_param) {}
@@ -396,24 +415,15 @@ struct ClientParam
396
415
397
416
struct ReadResults : IterateFieldsHelper<ReadResults, sizeof ...(Types)>
398
417
{
399
- template <typename ... Args >
400
- void handleField (Args&& ... args )
418
+ template <typename Results, typename ... Params >
419
+ void handleField (ClientInvokeContext& invoke_context, Results& results, TypeList<Params ...> )
401
420
{
402
- callRead<0 >(std::forward<Args>(args)...);
403
- }
421
+ auto const fun = [&]<typename ... Values>(Values&&... values) {
422
+ MaybeReadField (std::integral_constant<bool , Accessor::out>(), TypeList<Decay<Params>...>(), invoke_context,
423
+ Make<StructField, Accessor>(results), ReadDestUpdate (values)...);
424
+ };
404
425
405
- template <int I, typename ... Args>
406
- auto callRead (Args&&... args) -> std::enable_if_t<(I < sizeof ...(Types))>
407
- {
408
- callRead<I + 1 >(std::forward<Args>(args)..., std::get<I>(m_client_param->m_values ));
409
- }
410
-
411
- template <int I, typename Results, typename ... Params, typename ... Values>
412
- auto callRead (ClientInvokeContext& invoke_context, Results& results, TypeList<Params...>, Values&&... values)
413
- -> std::enable_if_t<I == sizeof...(Types)>
414
- {
415
- MaybeReadField (std::integral_constant<bool , Accessor::out>(), TypeList<Decay<Params>...>(), invoke_context,
416
- Make<StructField, Accessor>(results), ReadDestUpdate (values)...);
426
+ std::apply (fun, m_client_param->m_values );
417
427
}
418
428
419
429
ReadResults (ClientParam* client_param) : m_client_param(client_param) {}
@@ -574,7 +584,7 @@ void serverDestroy(Server& server)
574
584
// !
575
585
// ! ProxyClient<ClassName>::M0::Result ProxyClient<ClassName>::methodName(M0::Param<0> arg0, M0::Param<1> arg1) {
576
586
// ! typename M0::Result result;
577
- // ! clientInvoke(*this, &InterfaceName::Client::methodNameRequest, MakeClientParam<...>(arg0), MakeClientParam<...>(arg1), MakeClientParam<...>(result));
587
+ // ! clientInvoke(*this, &InterfaceName::Client::methodNameRequest, MakeClientParam<...>(M0::Fwd<0>( arg0)) , MakeClientParam<...>(M0::Fwd<1>( arg1) ), MakeClientParam<...>(result));
578
588
// ! return result;
579
589
// ! }
580
590
// !
@@ -650,19 +660,14 @@ void clientInvoke(ProxyClient& proxy_client, const GetRequest& get_request, Fiel
650
660
// ! return value with value of `ret()`. This is useful for avoiding code
651
661
// ! duplication and branching in generic code that forwards calls to functions.
652
662
template <typename Fn, typename Ret>
653
- auto ReplaceVoid (Fn&& fn, Ret&& ret) ->
654
- std::enable_if_t<std::is_same_v<void, decltype(fn())>, decltype(ret())>
663
+ auto ReplaceVoid (Fn&& fn, Ret&& ret)
655
664
{
656
- fn ();
657
- return ret ();
658
- }
659
-
660
- // ! Overload of above for non-void `fn()` case.
661
- template <typename Fn, typename Ret>
662
- auto ReplaceVoid (Fn&& fn, Ret&& ret) ->
663
- std::enable_if_t<!std::is_same_v<void, decltype(fn())>, decltype(fn())>
664
- {
665
- return fn ();
665
+ if constexpr (std::is_same_v<decltype (fn ()), void >) {
666
+ fn ();
667
+ return ret ();
668
+ } else {
669
+ return fn ();
670
+ }
666
671
}
667
672
668
673
extern std::atomic<int > server_reqs;
0 commit comments