208 lines
3.6 KiB
C++
Executable File
208 lines
3.6 KiB
C++
Executable File
// License: Modified MIT (NON-AI)
|
|
// See the LICENSE file in the root directory for license information.
|
|
// Copyright 2026 Timothy Prepscius
|
|
|
|
#pragma once
|
|
|
|
#include "Future.h"
|
|
#include "./custom/Future.hpp"
|
|
#include <tjp/core/algorithm/copy_of.hpp>
|
|
|
|
namespace tjp {
|
|
namespace core {
|
|
|
|
template<typename R, typename F>
|
|
Promise<R> &promise_of(Promise<R> &p, F &&f)
|
|
{
|
|
p.consume(f);
|
|
return p;
|
|
}
|
|
|
|
template<typename F>
|
|
auto future_of(F &&f)
|
|
{
|
|
using R_Ref = decltype(f());
|
|
using R = std::remove_reference_t<R_Ref>;
|
|
|
|
Promise<R> promise;
|
|
promise.consume(f);
|
|
return promise.get_future();
|
|
}
|
|
|
|
template<typename F, typename ... Args>
|
|
auto future_of(F &&f, Args && ... args)
|
|
{
|
|
using R_Ref = decltype(f(std::forward<Args>(args)...));
|
|
using R = std::remove_reference_t<R_Ref>;
|
|
|
|
Promise<R> promise;
|
|
promise.consume(f, std::forward<Args>(args)...);
|
|
return promise.get_future();
|
|
}
|
|
|
|
template<typename T>
|
|
auto future_of_value(T &&t)
|
|
{
|
|
using T_ = std::remove_reference_t<T>;
|
|
Promise<T_> promise;
|
|
|
|
promise.set_value(std::forward<T>(t));
|
|
return promise.get_future();
|
|
}
|
|
|
|
template<typename T>
|
|
Future<T> future_of_value(const T &t)
|
|
{
|
|
Promise<T> promise;
|
|
promise.set_value(t);
|
|
return promise.get_future();
|
|
}
|
|
|
|
inline
|
|
Future<void> future_of_value()
|
|
{
|
|
Promise<void> promise;
|
|
promise.set_value();
|
|
return promise.get_future();
|
|
}
|
|
|
|
template<typename T, typename E>
|
|
Future<T> future_of_exception(E &&e)
|
|
{
|
|
Promise<T> promise;
|
|
promise.set_exception(std::forward<E>(e));
|
|
return promise.get_future();
|
|
}
|
|
|
|
template<typename T, typename E>
|
|
Future<T> future_of_exception(const E &e)
|
|
{
|
|
return future_of_exception<T, E>(E(e));
|
|
}
|
|
|
|
template<typename F>
|
|
auto future_with(F &&f)
|
|
{
|
|
using R_Ref = decltype(f());
|
|
using R = std::remove_reference_t<R_Ref>;
|
|
|
|
if constexpr (is_future<R>::value)
|
|
{
|
|
using RV = typename R::value_type;
|
|
|
|
try
|
|
{
|
|
return f();
|
|
}
|
|
CORE_FUTURE_CATCH_BEGIN(e)
|
|
{
|
|
return future_of_exception<RV>(e);
|
|
}
|
|
CORE_FUTURE_CATCH_END
|
|
}
|
|
else
|
|
{
|
|
return future_of(f);
|
|
}
|
|
}
|
|
|
|
template<typename F, typename ... Args>
|
|
auto future_with(F &&f, Args && ...args)
|
|
{
|
|
using R_Ref = decltype(f(std::forward<Args>(args)...));
|
|
using R = std::remove_reference_t<R_Ref>;
|
|
|
|
if constexpr (is_future<R>::value)
|
|
{
|
|
using RV = typename R::value_type;
|
|
|
|
try
|
|
{
|
|
return f(std::forward<Args>(args)...);
|
|
}
|
|
CORE_FUTURE_CATCH_BEGIN(e)
|
|
{
|
|
return future_of_exception<RV>(e);
|
|
}
|
|
CORE_FUTURE_CATCH_END
|
|
}
|
|
else
|
|
{
|
|
return future_of(f, std::forward<Args>(args)...);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
struct AsFuture_
|
|
{
|
|
T v;
|
|
|
|
template<typename U>
|
|
operator Future<U>()
|
|
{
|
|
return future_of_value<U>(std::move(v));
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct AsFuture_<void>
|
|
{
|
|
template<typename U>
|
|
operator Future<U>()
|
|
{
|
|
return future_of_value();
|
|
}
|
|
} ;
|
|
|
|
template<typename T>
|
|
AsFuture_<T> as_future(T &&t)
|
|
{
|
|
return AsFuture_<std::remove_reference_t<T>> { std::forward<T>(t) };
|
|
}
|
|
|
|
inline
|
|
AsFuture_<void> as_future()
|
|
{
|
|
return AsFuture_<void> { };
|
|
}
|
|
|
|
template<typename T>
|
|
struct AsFutureException_
|
|
{
|
|
T v;
|
|
|
|
template<typename U>
|
|
operator Future<U>()
|
|
{
|
|
return future_of_exception<U>(std::move(v));
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
AsFutureException_<T> as_future_exception(T &&t)
|
|
{
|
|
return AsFutureException_<std::remove_reference_t<T>> { std::forward<T>(t) };
|
|
}
|
|
|
|
|
|
//template<typename F>
|
|
//auto future_with(F f) -> decltype(f()) {
|
|
// using R = typename decltype(f())::value_type;
|
|
// try {
|
|
// return f();
|
|
// }
|
|
// catch (Exception &e) {
|
|
// return future_of_exception<R>(copy_of(e));
|
|
// }
|
|
//}
|
|
|
|
|
|
//template<typename R, typename ...T, typename std::enable_if<!is_future<R>::value, R>::type*>
|
|
//auto with(std::function<R(T&&...)> &&f) {
|
|
// return f;
|
|
//}
|
|
//
|
|
|
|
} // namespace
|
|
} // namespace
|