Comments (2)
The reason we do this, generally, is to restrict the set of types/namespaces that are looked up when performing argument-dependent-lookup name-resolution - typically for finding tag_invoke()
overloads.
Normally, when you make an ADL-call on a type it looks for an overload in the associated namespaces of the arguments to that call.
The associated namespaces include:
- the namespace in which the type was declared
- the associated namespaces of any of the base-classes
- the associated namespaces of any of the template arguments (if the type is a specialisiation of a class-template)
Generally we want to limit the set of overloads of tag_invoke
the compiler needs to consider during overload resolution for compile-time reasons.
Declaring our types (operation-states, senders, receivers) as non-template classes nested within template classes means that those types are no longer specialisations of templates - but the types are still dependent on the template arguments. And so this means that the compiler doesn't consider the associated namespaces of the template arguments.
For example:
// The normal way
template<typename S, typename R>
class op { ... };
// The ADL-isolation way
template<typename S, typename R>
struct _op {
class type { ... };
};
template<typename S, typename R>
using op = typename _op<S, R>::type;
If we write:
op<some_sender, some_receiver> o;
unifex::start(o);
then this dispatches to the ADL-call tag_invoke(tag_t<unifex::start>, o)
and so will look for tag_invoke()
in the associated namespaces of unifex::start
CPO and of op<some_sender, some_receiver>
.
If we use the straight-forward approach for templates then this will not only look for hidden-friends inside op
but also for hidden-friends inside some_sender
and some_receiver
and all of their associated namespaces. As many senders/receivers used in generic algorithms are themselves templates which are templated on other senders/receivers, this can lead to quite a large number of associated types/namespaces that the compiler needs to search when looking for overloads of tag_invoke
.
As these types are also likely to have declared tag_invoke
overloads for other CPOs (e.g. set_value
, connect
, get_stop_token
, etc.) this can lead to the compiler creating very large overload-sets to consider whenever it resolves a tag_invoke
overload.
By using the ADL-isolation way, we are actually passing a non-template class as an argument that is still dependent on those same template arguments. But since it is a non-template class, the compiler no longer uses the rule that it needs to consider associated namespaces of template arguments and so we eliminate a large number of potential tag_invoke
overloads and thus greatly improve compile times.
I hope that makes sense.
from libunifex.
Thanks a lot for the detailed reply.
from libunifex.
Related Issues (20)
- update `.clang-format` and re-format everything
- Differences between libunifex and stdexec
- improve `fused_stop_source`
- Arithmetic exception in example io_epoll_test HOT 1
- rm `std::terminate` branch from `stop_when`
- Templatize range_stream HOT 1
- detail/types.hpp has what looks like a bad merge
- Clean up when_all.hpp
- Get rid of `config.hpp.in`
- There is different storage class about unifex::schedule. HOT 1
- implement `next_adapt_stream` / `cleanup_adapt_stream` in terms of `adapt_stream`
- Clean up TODO's in scheduler affinity revamp
- flat combining for async_mutex
- Cleanup `io_uring_context`
- at_coroutine_exit can probably break scheduler affinity
- Adopt stdexec's concept of environments and queries
- Lifetime issues in `type_erased_stream`
- Look into using clang-tidy HOT 8
- MSVC warning C4459: declaration of 'cleanup' hides global declaration HOT 2
- blocking_kind customization does not compile HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libunifex.