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

Turn class templates into a member classes of class templates to further narrow scope of ADL #83

Merged
merged 56 commits into from Mar 13, 2020

Conversation

ericniebler
Copy link
Collaborator

No description provided.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 6, 2020
@ericniebler
Copy link
Collaborator Author

Not quite done yet, but getting there.

template<>
struct _fn::_impl<false> {
template <typename Sender>
auto operator()(Sender&& predecessor) const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We seem to be inconsistent with the naming of the input sender.
We use 'sender', 'source' and 'predecessor' in various places.
Ideally we'd be consistent. Any preferences?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong feelings.

include/unifex/allocate.hpp Show resolved Hide resolved
include/unifex/awaitable_sender.hpp Show resolved Hide resolved
include/unifex/dematerialize.hpp Outdated Show resolved Hide resolved
include/unifex/finally.hpp Show resolved Hide resolved
include/unifex/when_all.hpp Outdated Show resolved Hide resolved
include/unifex/when_all.hpp Show resolved Hide resolved
include/unifex/when_all.hpp Outdated Show resolved Hide resolved
include/unifex/scheduler_concepts.hpp Show resolved Hide resolved
callback_.destruct();
if constexpr (is_stop_never_possible_v<
stop_token_type_t<Receiver&>>) {
unifex::set_value(std::move(receiver_));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that this call to set_value() could potentially be throwing (since we don't require that set_value() customisations are noexcept any more).

We probably need to do a pass through libunifex to pick up calls to set_value() and wrap them in try/catch if they are not noexcept.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave it for now.

Lewis Baker added 4 commits March 9, 2020 22:54
…uence().

Make CPO and sender/receiver arguments deduced and
then constrain to SFINAE out if the types don't match exactly.

Also modify handling of sequence() overload for 3 or more
parameters to avoid infinite recursion of function instantiation
under msvc by adding an explicit third argument so that the
overload would not be considered for the recrusive call to
sequence() with two argments.
…nsform().

Make CPO and sender/receiver arguments deduced and
then constrain to SFINAE out if the types don't match exactly.
…n_all().

Make CPO and sender/receiver arguments deduced and
then constrain to SFINAE out if the types don't match exactly.
Lewis Baker and others added 14 commits March 9, 2020 23:51
…, Args...> on finally(), sequence() and when_all().

This allows examples/async_trace.cpp to build under msvc.
MSVC was too eagerly istantiating tag_invoke() overloads where there were
non-deduced paramters (like a CPO or receiver parameter). Now make these
deduced parameters and explicitly exclude these overloads using enable_if
so that the examples/materialize builds under msvc.
…late function instantiation.

Added UNIFEX_[DECLARE/USE]_NON_DEDUCED_TYPE(NAME, TYPE).
On MSVC this lowers to enable_if-based SFINAE.
On other compilers this lowers to a non-template argument.

Updated the materialize/dematerialize algorithms to use these macros where
appropriate.
struct type {
private:
template <typename T>
static void* get_object_address(T&& t) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be noexcept?

};
template <typename Receiver>
using operation = typename _op<std::decay_t<Receiver>>::type;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are inconsistent with use of decay_t vs remove_cvref_t when decaying the Receiver types.
Should always just use remove_cvref_t?

Comment on lines +46 to +52
template <bool>
struct _impl {
template <typename Sender>
constexpr blocking_kind operator()(const Sender&) noexcept {
return blocking_kind::maybe;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be private: ?

include/unifex/config.hpp.in Outdated Show resolved Hide resolved
Comment on lines 149 to 151
typename Func,
UNIFEX_DECLARE_NON_DEDUCED_TYPE(CPO, tag_t<visit_continuations>),
UNIFEX_DECLARE_NON_DEDUCED_TYPE(R, receiver),
typename Func>
UNIFEX_DECLARE_NON_DEDUCED_TYPE(R, receiver)>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the change to put Func first needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because clang was not allowing a non-defaulted template parameter to follow ones that had defaults.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be the case for classes, but I didn't think it was the case for functions where template parameters can be deduced.
eg. see https://godbolt.org/z/oQmQ_d which has leading defaulted templated args followed by non-defaulted-but-deduced template args.

Comment on lines 161 to 163
auto operator co_await(Sender&& sender) {
return sender_awaiter<Sender, Result>{(Sender&&)sender};
return _coroutine::sender_awaiter<Sender, Result>{(Sender&&)sender};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if moving the existing sender types out of the unifex namespace and into child namespaces will mean that this operator co_await() overload is not found for some operations...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably so, but that was always going to be the case. We expect others to define sender types in their namespace. It's one of the reasons why sender_base exists in the P0443 design.

inline constexpr struct _fn {
template <typename Sender>
auto operator()(Sender&& sender) const {
return _single::stream<std::remove_cvref_t<Sender>>{(Sender&&)sender};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are double-applying the std::remove_cvref_t both here and in the _single::stream alias.

@@ -37,5 +37,8 @@ class single_thread_context {
return loop_.get_scheduler();
}
};
} // namespace _single_thread

using single_thread_context = _single_thread::context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to ADL-isolate this class as it doesn't customise any ADL-calls?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not strictly necessary given the other ADL mitigations we have in place, but defining types in ADL-blocking namespaces is a good habit, and I would rather we are consistent about it.

template callback_type<cancel_next_callback>>
stopCallback_;

using ST = stop_token_type_t<Receiver&>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this type-alias further up so it can be used in the declaration of the stopCallback_ member?

Comment on lines 448 to 450
template<typename SourceStream, typename... Values>
using stop_immediately_stream =
_stop_immediately::stream<SourceStream, Values...>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes you've been putting the aliases for the stream classes inside the impl namespace (e.g. see single.hpp) and sometimes in the public unifex namespace (like here).

We should be consistent about whether the sender/stream types are public types or not (my preference is to keep them private for now)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some places, the class name is the API (like never_stream). We could change this to be consistent and make never_stream a CPO that returns a _never::stream, but I think this diff is big enough.

EDIT: ... or never_stream could be an inline constexpr object of type _never::stream.

@lewissbaker
Copy link
Contributor

We also need to update the io_uring_context and io_epoll_context types to apply ADL-isolation techniques to them as well.

Lewis Baker and others added 5 commits March 13, 2020 15:26
Copy link
Contributor

@lewissbaker lewissbaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - we can address the remaining bits in future PRs.

@ericniebler ericniebler merged commit dcc9f62 into master Mar 13, 2020
@ericniebler ericniebler deleted the adl_isolation branch March 13, 2020 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants