Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions include/stdexec/__detail/__affine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,14 @@ namespace STDEXEC
}
}

template <__forwarding_query _Tag, class... _Args>
requires(!__completion_query<_Tag>)
&& __queryable_with<env_of_t<_Sender>, _Tag, _Args const &...>
constexpr auto query(_Tag, _Args const &...) const noexcept
-> __query_result_t<env_of_t<_Sender>, _Tag, _Args const &...>
template <__forwarding_query _Query, class... _Args>
requires(!__completion_query<_Query>)
&& __queryable_with<env_of_t<_Sender>, _Query, _Args...>
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
constexpr auto query(_Query, _Args &&...__args) const
noexcept(__nothrow_queryable_with<env_of_t<_Sender>, _Query, _Args...>) -> decltype(auto)
{
return __query_result_t<env_of_t<_Sender>, _Tag, _Args const &...>{};
return STDEXEC::get_env(__sndr_).query(_Query(), static_cast<_Args &&>(__args)...);
}

_Sender const &__sndr_;
Expand Down
6 changes: 2 additions & 4 deletions include/stdexec/__detail/__continues_on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ namespace STDEXEC
&& __queryable_with<env_of_t<_Sender>, _Query, _Args...>
[[nodiscard]]
constexpr auto query(_Query, _Args&&... __args) const
noexcept(__nothrow_queryable_with<env_of_t<_Sender>, _Query, _Args...>)
-> __query_result_t<env_of_t<_Sender>, _Query, _Args...>
noexcept(__nothrow_queryable_with<env_of_t<_Sender>, _Query, _Args...>) -> decltype(auto)
{
return __attrs_.query(_Query(), static_cast<_Args&&>(__args)...);
}
Expand Down Expand Up @@ -360,8 +359,7 @@ namespace STDEXEC
}
STDEXEC_CATCH_ALL
{
STDEXEC::set_error(static_cast<_State&&>(__state).__rcvr_, std::current_exception());
return;
__state.__data_.__emplace_from(__mktuple, set_error, std::current_exception());
}
}

Expand Down
7 changes: 3 additions & 4 deletions include/stdexec/__detail/__on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ namespace STDEXEC
requires(!__completion_query<_Query>)
&& __queryable_with<env_of_t<_Child>, _Query, _Args...>
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
constexpr auto query(_Query __query, _Args&&... __args) const
noexcept(__nothrow_queryable_with<env_of_t<_Child>, _Query, _Args...>)
-> __query_result_t<env_of_t<_Child>, _Query, _Args...>
constexpr auto query(_Query, _Args&&... __args) const
noexcept(__nothrow_queryable_with<env_of_t<_Child>, _Query, _Args...>) -> decltype(auto)
{
return __query(STDEXEC::get_env(__child_), static_cast<_Args&&>(__args)...);
return STDEXEC::get_env(__child_).query(_Query(), static_cast<_Args&&>(__args)...);
}

_Child const & __child_;
Expand Down
6 changes: 2 additions & 4 deletions include/stdexec/__detail/__sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ namespace STDEXEC
requires __queryable_with<_env_t, _Query, _Args...>
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
constexpr auto query(_Query, _Args &&...__args) const
noexcept(__nothrow_queryable_with<_env_t, _Query, _Args...>)
-> __query_result_t<_env_t, _Query, _Args...>
noexcept(__nothrow_queryable_with<_env_t, _Query, _Args...>) -> decltype(auto)
{
return STDEXEC::get_env(__sndr_).query(_Query(), static_cast<_Args &&>(__args)...);
}
Expand Down Expand Up @@ -174,8 +173,7 @@ namespace STDEXEC
requires(!__completion_query<_Query>) && __queryable_with<__joined_t, _Query, _Args...>
[[nodiscard]]
constexpr auto operator()(_Query, _Args &&...__args) const
noexcept(__nothrow_queryable_with<__joined_t, _Query, _Args...>)
-> __query_result_t<__joined_t, _Query, _Args...>
noexcept(__nothrow_queryable_with<__joined_t, _Query, _Args...>) -> decltype(auto)
{
return __joined_t{STDEXEC::get_env(__sndr2_), STDEXEC::get_env(__sndr1_)}
.query(_Query(), static_cast<_Args &&>(__args)...);
Expand Down
10 changes: 10 additions & 0 deletions include/stdexec/__detail/__starts_on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ namespace STDEXEC
{
return {};
}

template <__forwarding_query _Query, class... _Args>
requires(!__completion_query<_Query>)
&& __queryable_with<env_of_t<_Child>, _Query, _Args...>
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
constexpr auto query(_Query, _Args&&... __args) const
noexcept(__nothrow_queryable_with<env_of_t<_Child>, _Query, _Args...>) -> decltype(auto)
{
return __attr_.query(_Query(), static_cast<_Args&&>(__args)...);
}
};
} // namespace __starts_on

Expand Down
7 changes: 7 additions & 0 deletions test/stdexec/algos/adaptors/test_continues_on.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <exec/sender_for.hpp>
#include <exec/start_detached.hpp>
#include <exec/static_thread_pool.hpp>
#include <test_common/non_completion_query.hpp>
#include <test_common/receivers.hpp>
#include <test_common/schedulers.hpp>
#include <test_common/type_helpers.hpp>
Expand Down Expand Up @@ -80,6 +81,12 @@ namespace
(void) snd;
}

TEST_CASE("continues_on forwards non-completion queries", "[adaptors][continues_on]")
{
auto snd = ex::continues_on(test_common::non_completion_query_sender{}, inline_scheduler{});
CHECK(test_common::non_completion_query(ex::get_env(snd), 41) == 42);
}

TEST_CASE("continues_on with environment returns a sender", "[adaptors][continues_on]")
{
auto snd = ex::continues_on(ex::just(13), inline_scheduler{});
Expand Down
7 changes: 7 additions & 0 deletions test/stdexec/algos/adaptors/test_on.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stdexec/execution.hpp>

#include <exec/static_thread_pool.hpp>
#include <test_common/non_completion_query.hpp>
#include <test_common/receivers.hpp>
#include <test_common/schedulers.hpp>

Expand Down Expand Up @@ -47,6 +48,12 @@ namespace
(void) snd;
}

TEST_CASE("STDEXEC::on forwards non-completion queries", "[adaptors][on]")
{
auto snd = ex::on(inline_scheduler{}, test_common::non_completion_query_sender{});
CHECK(test_common::non_completion_query(ex::get_env(snd), 41) == 42);
}

TEST_CASE("STDEXEC::on with environment returns a sender", "[adaptors][on]")
{
auto snd = ex::on(inline_scheduler{}, ex::just(13));
Expand Down
7 changes: 7 additions & 0 deletions test/stdexec/algos/adaptors/test_starts_on.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <exec/sender_for.hpp>
#include <exec/start_detached.hpp>
#include <exec/static_thread_pool.hpp>
#include <test_common/non_completion_query.hpp>
#include <test_common/receivers.hpp>
#include <test_common/schedulers.hpp>
#include <test_common/type_helpers.hpp>
Expand Down Expand Up @@ -48,6 +49,12 @@ namespace
(void) snd;
}

TEST_CASE("starts_on forwards non-completion queries", "[adaptors][starts_on]")
{
auto snd = ex::starts_on(inline_scheduler{}, test_common::non_completion_query_sender{});
CHECK(test_common::non_completion_query(ex::get_env(snd), 41) == 42);
}

TEST_CASE("starts_on with environment returns a sender", "[adaptors][starts_on]")
{
auto snd = ex::starts_on(inline_scheduler{}, ex::just(13));
Expand Down
70 changes: 70 additions & 0 deletions test/test_common/non_completion_query.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2026 NVIDIA Corporation
*
* Licensed under the Apache License, Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include <stdexec/execution.hpp>

namespace test_common
{
namespace ex = STDEXEC;

struct non_completion_query_t
: ex::__query<non_completion_query_t>
, ex::forwarding_query_t
{
using ex::__query<non_completion_query_t>::operator();
};

inline constexpr non_completion_query_t non_completion_query{};

struct non_completion_query_env
{
constexpr auto query(non_completion_query_t, int value) const noexcept -> int
{
return value + 1;
}
};

struct non_completion_query_sender
{
using sender_concept = ex::sender_tag;
using completion_signatures = ex::completion_signatures<ex::set_value_t()>;

template <ex::receiver Receiver>
struct operation
{
using operation_state_concept = ex::operation_state_tag;

void start() & noexcept
{
ex::set_value(static_cast<Receiver&&>(receiver));
}

Receiver receiver;
};

template <ex::receiver Receiver>
auto connect(Receiver&& receiver) const -> operation<std::remove_cvref_t<Receiver>>
{
return {static_cast<Receiver&&>(receiver)};
}

auto get_env() const noexcept -> non_completion_query_env
{
return {};
}
};
} // namespace test_common
Loading