15#include <QFutureInterface>
16#include <QFutureWatcher>
24 template<
typename R,
typename F,
typename...
Args>
29 constexpr bool isVoid = std::is_same_v<R, void>;
30 if constexpr (!
isVoid && !std::is_invocable_v<std::decay_t<F>,
Args...>)
32 static_assert (std::is_constructible_v<R, F>);
33 static_assert (
sizeof... (
Args) == 0,
34 "Extra args when a value is passed. Perhaps you wanted to pass in a function?");
36 const R result { std::forward<F> (f) };
39 else if constexpr (!
isVoid)
41 const auto result = std::invoke (std::forward<F> (f), std::forward<Args> (
args)...);
45 std::invoke (std::forward<F> (f), std::forward<Args> (
args)...);
47 catch (
const QtException_t&
e)
51 catch (
const std::exception&
e)
56 iface.reportFinished ();
90 template<
typename Future>
123 &QFutureWatcherBase::finished,
125 &QObject::deleteLater);
149 template<
typename RetT,
typename ArgT>
156 throw std::runtime_error { std::string {
"invalid type in " } +
Q_FUNC_INFO };
167 last->deleteLater ();
196 template<
typename ArgT>
203 throw std::runtime_error { std::string {
"invalid type in " } +
Q_FUNC_INFO };
218 void Then (
const std::function<
void ()>&
action)
224 throw std::runtime_error { std::string {
"invalid type in " } +
Q_FUNC_INFO };
236 template<
typename Handler>
244 <<
"multiple results handler should be chained directly to the source";
245 throw std::runtime_error {
"invalid multiple results handler chaining" };
249 &QFutureWatcherBase::resultReadyAt,
299 template<
typename Ret,
typename Future,
typename DestructionTag>
302 template<
typename,
typename,
typename>
320 template<
typename F1,
typename Ret1>
323 template<
typename F,
typename...
Args>
363 throw std::runtime_error {
"SequenceProxy::Then(): cannot chain more after being converted to a QFuture" };
371 else if constexpr (std::is_same<IsDetected_t<struct Dummy, ReturnsVoidDetector_t, F, Ret>,
void> {})
373 else if constexpr (std::is_same<void, Ret>::value &&
374 std::is_same<IsDetected_t<struct Dummy, ReturnsVoidDetector_t, F>,
void> {})
375 Seq_->Then (std::function<
void ()> {
f });
377 static_assert (std::is_same<F, struct Dummy> {},
"Invalid functor passed to SequenceProxy::Then()");
383 return Then (std::forward<F> (f));
389 static_assert (std::is_same<DestructionTag, EmptyDestructionTag>::value,
390 "Destruction handling function has been already set.");
398 Seq_->MultipleResults (std::forward<F> (f));
401 template<
typename F,
typename Finish>
404 Seq_->MultipleResults (std::forward<F> (f),
405 std::forward<Finish> (
finish));
408 template<
typename F,
typename Finish,
typename Start>
411 Seq_->MultipleResults (std::forward<F> (f),
412 std::forward<Finish> (
finish),
413 std::forward<Start> (
start));
418 constexpr bool isEmptyDestr = std::is_same<DestructionTag, EmptyDestructionTag>::value;
419 static_assert (std::is_same<DestructionTag, Ret>::value ||
isEmptyDestr,
420 "Destruction handler's return type doesn't match expected future type.");
426 iface.reportStarted ();
435 if (
iface.isFinished ())
527 detail::SequenceProxy<
528 detail::SequencerRetType_t<QFuture<T>>,
530 detail::EmptyDestructionTag
532 Sequence (QObject *parent,
const QFuture<T>& future)
534 return {
new detail::Sequencer<QFuture<T>> { future, parent } };
552 iface.reportStarted ();
553 iface.reportFinished (&t);
554 return iface.future ();
const QDBusArgument & operator>>(const QDBusArgument &in, IconFrame &frame)
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Container< T > Filter(const Container< T > &c, F f)
std::tuple_element_t< 0, detail::CallTypeGetter_t< F > > RetType_t
Util::ConcurrentException< Util::NewType< std::exception, struct StdException > > ConcurrentStdException