### Sender concepts

##### sender and sender_to

    template<class S>
      concept sender =
        move_constructible<remove_cvref_t<S>> &&
        !requires {
          typename sender_traits<remove_cvref_t<S>>::__unspecialized; // exposition only
        };

    template<class S, class R>
      concept sender_to =
        sender<S> &&
        receiver<R> &&
        requires (S&& s, R&& r) {
          execution::connect((S&&) s, (R&&) r);
        };

None of these operations shall introduce data races as a result of concurrent invocations of those functions from different threads.

A sender type's destructor shall not block pending completion of the submitted function objects.

[Note: The ability to wait for completion of submitted function objects may be provided by the associated execution context. —end note]

##### typed_sender

A sender is typed if it declares what types it sends through a receiver's channels. The `typed_sender` concept is defined as:

    template<template<template<class...> class Tuple, template<class...> class Variant> class>
      struct has-value-types; // exposition only

    template<template<class...> class Variant>
      struct has-error-types; // exposition only

    template<class S>
      concept has-sender-types = // exposition only
        requires {
          typename has-value-types<S::template value_types>;
          typename has-error-types<S::template error_types>;
          typename bool_constant<S::sends_done>;
        };

    template<class S>
      concept typed_sender =
        sender<S> &&
        has-sender-types<sender_traits<remove_cvref_t<S>>>;