flatten 20260225
This commit is contained in:
205
tjp/core/future/Future.hpp
Executable file
205
tjp/core/future/Future.hpp
Executable file
@@ -0,0 +1,205 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user