-
Notifications
You must be signed in to change notification settings - Fork 188
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
Update finally to support value channel references #545
Changes from 1 commit
9feb969
472130c
2bb4f83
6a722c6
e2453cc
ab1811d
913eaf6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | |||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -24,7 +24,7 @@ | ||||||||||||||||||||||||||||||
namespace unifex { | |||||||||||||||||||||||||||||||
namespace _create { | |||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
template <typename Receiver, typename Fn, typename Context> | |||||||||||||||||||||||||||||||
template <typename Receiver, typename Fn, typename Context, typename... ValueTypes> | |||||||||||||||||||||||||||||||
struct _op { | |||||||||||||||||||||||||||||||
struct type { | |||||||||||||||||||||||||||||||
explicit type(Receiver rec, Fn fn, Context ctx) | |||||||||||||||||||||||||||||||
|
@@ -36,7 +36,7 @@ struct _op { | ||||||||||||||||||||||||||||||
template (typename... Ts) | |||||||||||||||||||||||||||||||
(requires receiver_of<Receiver, Ts...>) | |||||||||||||||||||||||||||||||
void set_value(Ts&&... ts) noexcept(is_nothrow_receiver_of_v<Receiver, Ts...>) { | |||||||||||||||||||||||||||||||
unifex::set_value((Receiver&&) rec_, (Ts&&) ts...); | |||||||||||||||||||||||||||||||
unifex::set_value((Receiver&&) rec_, (ValueTypes) ts...); | |||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The conversion from I think it's right for the function to take arbitrary forwarding references (rather than, say,
But, I worry that we'll copy or move more often than necessary if we get the details wrong. Maybe the solution is to factor the conversion into a functor that performs the operation that
The part of the above I'm most uncertain about is the type parameters given to
For For How do
and
For one thing Perhaps the second type argument to To get the unconditional move behaviour for So that leaves us with
Does my reasoning seem sound? If so, is Should this be
Suggested change
with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I had a similar concern. My original logic of I'm having a hard time understanding whether
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note, I added There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm currently leaning towards " If I think of I think there are two choices here with different trade-offs:
I think the danger of 1 is unintentional copy/move, which can be "fixed" by changing to I feel like the danger of 1 is less dangerous than the danger of 2 and the cost of safety isn't that high, but what do you think? Also, if we make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re: giving me co-authorship credit, that's kind of you. I feel like I'm playing the role of editor here, not co-author, so it feels a bit like undue credit, but I don't know what the open source conventions are around this kind of thing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, now I see - I think Re: credit - im not sure of the convention either. Not a big deal, and fair point about being "editor," so I rebased and removed it. |
|||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
template (typename Error) | |||||||||||||||||||||||||||||||
|
@@ -79,10 +79,10 @@ struct _op { | ||||||||||||||||||||||||||||||
}; | |||||||||||||||||||||||||||||||
}; | |||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
template <typename Receiver, typename Fn, typename Context> | |||||||||||||||||||||||||||||||
using _operation = typename _op<Receiver, Fn, Context>::type; | |||||||||||||||||||||||||||||||
template <typename Receiver, typename Fn, typename Context, typename... ValueTypes> | |||||||||||||||||||||||||||||||
using _operation = typename _op<Receiver, Fn, Context, ValueTypes...>::type; | |||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
template <typename Fn, typename Context> | |||||||||||||||||||||||||||||||
template <typename Fn, typename Context, typename... ValueTypes> | |||||||||||||||||||||||||||||||
struct _snd_base { | |||||||||||||||||||||||||||||||
struct type { | |||||||||||||||||||||||||||||||
template <template<typename...> class Variant> | |||||||||||||||||||||||||||||||
|
@@ -101,14 +101,14 @@ struct _snd_base { | ||||||||||||||||||||||||||||||
(requires derived_from<remove_cvref_t<Self>, type> AND | |||||||||||||||||||||||||||||||
constructible_from<Fn, member_t<Self, Fn>> AND | |||||||||||||||||||||||||||||||
constructible_from<Context, member_t<Self, Context>>) | |||||||||||||||||||||||||||||||
ccotter marked this conversation as resolved.
Show resolved
Hide resolved
|
|||||||||||||||||||||||||||||||
friend _operation<remove_cvref_t<Receiver>, Fn, Context> | |||||||||||||||||||||||||||||||
friend _operation<remove_cvref_t<Receiver>, Fn, Context, ValueTypes...> | |||||||||||||||||||||||||||||||
tag_invoke(tag_t<connect>, Self&& self, Receiver&& rec) | |||||||||||||||||||||||||||||||
noexcept(std::is_nothrow_constructible_v< | |||||||||||||||||||||||||||||||
_operation<Receiver, Fn, Context>, | |||||||||||||||||||||||||||||||
_operation<Receiver, Fn, Context, ValueTypes...>, | |||||||||||||||||||||||||||||||
Receiver, | |||||||||||||||||||||||||||||||
member_t<Self, Fn>, | |||||||||||||||||||||||||||||||
member_t<Self, Context>>) { | |||||||||||||||||||||||||||||||
return _operation<remove_cvref_t<Receiver>, Fn, Context>{ | |||||||||||||||||||||||||||||||
return _operation<remove_cvref_t<Receiver>, Fn, Context, ValueTypes...>{ | |||||||||||||||||||||||||||||||
(Receiver&&) rec, | |||||||||||||||||||||||||||||||
((Self&&) self).fn_, | |||||||||||||||||||||||||||||||
((Self&&) self).ctx_}; | |||||||||||||||||||||||||||||||
|
@@ -121,7 +121,7 @@ struct _snd_base { | ||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
template <typename Fn, typename Context, typename... ValueTypes> | |||||||||||||||||||||||||||||||
struct _snd { | |||||||||||||||||||||||||||||||
struct type : _snd_base<Fn, Context>::type { | |||||||||||||||||||||||||||||||
struct type : _snd_base<Fn, Context, ValueTypes...>::type { | |||||||||||||||||||||||||||||||
template <template<typename...> class Variant, template <typename...> class Tuple> | |||||||||||||||||||||||||||||||
using value_types = Variant<Tuple<ValueTypes...>>; | |||||||||||||||||||||||||||||||
}; | |||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few thoughts.
First, I think there's a chance that the conversion from
Ts&&
toValueTypes
might throw, right? If so, the currentnoexcept
declaration is incomplete.Second, I intend to change
set_value
benoexcept
(it simplifies many things, saves binary size, and brings us into better alignment with P2300) so I think, rather than refining thenoexcept
clause, it'd probably be better to just make itnoexcept
and forward exceptions toset_error
.Finally, we've been standardizing on an unstated coding style: use
std::move()
for moves andstatic_cast<Dest>(value)
to replacestd::forward
, and don't use C-style casts. As I understand it, the C-style casts are in the code to cut down on compile time by avoiding template instantiations. We've written a handful of bugs by following this style, though, so I'm not convinced the build-time speedups are worth the maintenance risk; we may yet migrate fromstatic_cast
tostd::forward
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, good catch.
Done. Makes sense. Once
set_value
is mandated to benoexcept
, we can do the same cosntexpr conditional to avoid the try/catch if the conversion is nonthrowing, but I have not made that change here.I made one step towards this within this PR, although I think I have at least one more place to update within my changes. Thanks for clarifying the standard within this project. I will note, clang-tidy has been adding CppCoreGuidelines checks for correct move/forward/universal parameter usage (e.g., F.18) and I think the checks work best (or in some cases, only work) when
move
andforward
are used rather than casts.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh. We should take advantage. I've filed issue #548.