AimRT/install_x64/include/unifex/let_value_with.hpp
2025-01-12 19:51:34 +08:00

149 lines
5.0 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* 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://llvm.org/LICENSE.txt
*
* 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 <unifex/config.hpp>
#include <unifex/just.hpp>
#include <unifex/let_value.hpp>
#include <unifex/receiver_concepts.hpp>
#include <unifex/sender_concepts.hpp>
#include <unifex/execution_policy.hpp>
#include <unifex/type_list.hpp>
#include <unifex/detail/prologue.hpp>
namespace unifex {
namespace _let_v_w {
template<typename StateFactory, typename InnerOp, typename Receiver>
struct _operation {
struct type;
};
template <typename StateFactory, typename InnerOp, typename Receiver>
using operation = typename _operation<
StateFactory, InnerOp, Receiver>::type;
template<typename StateFactory, typename SuccessorFactory>
struct _sender {
class type;
};
template<typename StateFactory, typename SuccessorFactory>
using let_with_sender = typename _sender<StateFactory, SuccessorFactory>::type;
template<typename StateFactory, typename SuccessorFactory>
class _sender<StateFactory, SuccessorFactory>::type {
public:
using InnerOp = std::invoke_result_t<SuccessorFactory, callable_result_t<StateFactory>&>;
template<template<typename...> class Variant, template<typename...> class Tuple>
using value_types = sender_value_types_t<InnerOp, Variant, Tuple>;
template<template<typename...> class Variant>
using error_types = sender_error_types_t<InnerOp, Variant>;
static constexpr bool sends_done = sender_traits<InnerOp>::sends_done;
template<typename StateFactory2, typename SuccessorFactory2>
explicit type(StateFactory2&& stateFactory, SuccessorFactory2&& func) :
stateFactory_((StateFactory2&&)stateFactory),
func_((SuccessorFactory2&&)func)
{}
template(typename Self, typename Receiver)
(requires same_as<remove_cvref_t<Self>, type> AND receiver<Receiver>)
friend auto tag_invoke(tag_t<unifex::connect>, Self&& self, Receiver&& r)
noexcept(
is_nothrow_callable_v<member_t<Self, StateFactory>> &&
std::is_nothrow_invocable_v<
member_t<Self, SuccessorFactory>,
callable_result_t<member_t<Self, StateFactory>>&> &&
is_nothrow_connectable_v<
callable_result_t<
member_t<Self, SuccessorFactory>,
callable_result_t<member_t<Self, StateFactory>>&>,
remove_cvref_t<Receiver>>) {
return operation<StateFactory, SuccessorFactory, Receiver>(
static_cast<Self&&>(self).stateFactory_,
static_cast<Self&&>(self).func_,
static_cast<Receiver&&>(r));
}
private:
UNIFEX_NO_UNIQUE_ADDRESS StateFactory stateFactory_;
UNIFEX_NO_UNIQUE_ADDRESS SuccessorFactory func_;
};
template<typename StateFactory, typename SuccessorFactory, typename Receiver>
struct _operation<StateFactory, SuccessorFactory, Receiver>::type {
type(StateFactory&& stateFactory, SuccessorFactory&& func, Receiver&& r) :
stateFactory_(static_cast<StateFactory&&>(stateFactory)),
func_(static_cast<SuccessorFactory&&>(func)),
state_(static_cast<StateFactory&&>(stateFactory_)()),
innerOp_(
unifex::connect(
static_cast<SuccessorFactory&&>(func_)(state_),
static_cast<Receiver&&>(r))) {
}
void start() & noexcept {
unifex::start(innerOp_);
}
StateFactory stateFactory_;
SuccessorFactory func_;
callable_result_t<StateFactory> state_;
connect_result_t<
callable_result_t<SuccessorFactory, callable_result_t<StateFactory>&>,
remove_cvref_t<Receiver>>
innerOp_;
};
namespace _cpo {
struct _fn {
template (typename StateFactory, typename SuccessorFactory)
(requires
callable<std::decay_t<StateFactory>> AND
callable<
std::decay_t<SuccessorFactory>,
callable_result_t<std::decay_t<StateFactory>>&> AND
sender<
callable_result_t<
std::decay_t<SuccessorFactory>,
callable_result_t<std::decay_t<StateFactory>>&>>)
auto operator()(StateFactory&& stateFactory, SuccessorFactory&& successor_factory) const
noexcept(std::is_nothrow_constructible_v<std::decay_t<SuccessorFactory>, SuccessorFactory> &&
std::is_nothrow_constructible_v<std::decay_t<StateFactory>, StateFactory>)
-> _let_v_w::let_with_sender<
std::decay_t<StateFactory>, std::decay_t<SuccessorFactory>> {
return _let_v_w::let_with_sender<
std::decay_t<StateFactory>, std::decay_t<SuccessorFactory>>{
(StateFactory&&)stateFactory, (SuccessorFactory&&)successor_factory};
}
};
} // namespace _cpo
} // namespace _let_v_w
inline constexpr _let_v_w::_cpo::_fn let_value_with{};
} // namespace unifex
#include <unifex/detail/epilogue.hpp>