C++ Logo

std-proposals

Advanced search

[std-proposals] Proposal add std::execution::nullopt_as_stopped, std::execution::unexpected_as_error etc.

From: Johannes Kalmbach <johannes.kalmbach_at_[hidden]>
Date: Fri, 30 Oct 2026 20:04:37 +0100
Hi,

std::optional and std::expected have monadic operations `transform` and
`and_then` which
basically short-circuit as soon as the unhappy case (nullopt/unexpected) is
reached.

My proposal is to add sender adapters with comparable semantics in the
async std::execution world (all names of course being preliminary):

* std::execution::nullopt_as_stopped turns a set_value of nullopt (either
via nullopt_t, or any optional<T> type into `set_stopped`.

* std::execution::unexepected_as_error turns set_value(std::unexpected(t))
into set_error(t)

* optional, std::execution::nullopt_as_error(specifyableErrorValue)
(Semantics should be clear from the name, analogous to the above).

* std::execution::unexpected_as_stopped is possibly a bad idea, as it
encourages to silently drop errors, but would complete this set.

Motivation: Make it easier to put chains of optional/expected function into
the async world, e.g.

int x = ...
auto s = ex:just(x)
   | ex:then([](int x) {return x > 3 ? std::nullopt : std::optional{x *
2};})
   | ex::nullopt_as_stopped
   | ...

I anticipate a typical way of using will be to implement a shortcut for `
then(f) | nullopt_as_stopped` etc. for convience when many such operations
are chained. Whether it is beneficial to implement these as dedicated
adapters for performance reasons is yet to be explored.


Note: To my understanding, only the " inverse" operations are currently
standardized (stopped_as_optional, stopped_as_error, other custom
transformations from stopped/error channel can be implemented using
upon_stopped and upon_error), but the direction I am proposing is not yet
part of the standard nor of a paper I could find.

I am looking forward to your feedback, thanks for your time.
Best regards
Johannes

Received on 2026-10-30 19:04:54