Files
core_future/tjp/core/future/Future.hpp
2026-03-06 09:28:09 -05:00

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