/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see .
*/
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace std
{
enum class future_errc
{
broken_promise = 0,
future_already_retrieved = 1,
promise_already_satisfied = 2,
no_state = 3
};
enum class launch : std::uint_least8_t
{
async = 0,
deferred = 1,
};
enum class future_status
{
ready,
timeout,
deferred
};
template <>
struct is_error_code_enum : public true_type
{
};
error_condition make_error_condition(future_errc e) noexcept;
const error_category &future_category() noexcept
{
static const error_category cat;
return cat;
}
inline std::error_code make_error_code(future_errc e) noexcept
{
return std::error_code(static_cast(e), future_category());
}
class future_error;
template
class promise;
template
class promise;
template <>
class promise;
template
void swap(promise &x, promise &y) noexcept;
template
struct uses_allocator, Alloc>;
template
class future;
template
class future;
template <>
class future;
template
class shared_future;
template
class shared_future;
template <>
class shared_future;
template
class packaged_task; // not defined
template
class packaged_task;
template
void swap(packaged_task &, packaged_task &) noexcept;
template
future::type> async(launch policy, Fn &&fn, Args &&...args)
{
using ReturnType = std::invoke_result_t, std::decay_t...>;
if (policy == std::launch::async)
{
auto task = std::make_shared>(
std::bind(std::forward(fn), std::forward(args)...));
std::future future = task->get_future();
std::thread([task]()
{ (*task)(); })
.detach();
return future;
}
else if (policy == std::launch::deferred)
{
return std::async(std::launch::deferred, std::forward(fn), std::forward(args)...);
}
else
{
throw std::invalid_argument("Invalid launch policy");
}
}
template
future::type> async(Fn &&fn, Args &&...args)
{
return async(std::launch::async /* | std::launch::deferred*/, std::forward(fn), std::forward(args)...);
}
class future_error : public logic_error
{
private:
error_code ec_;
public:
future_error(const future_error &other) noexcept;
explicit future_error(std::future_errc ec);
future_error &operator=(const future_error &other) noexcept;
const std::error_code &code() const noexcept;
virtual const char *what() const noexcept;
};
template
class promise
{
public:
promise();
template
promise(allocator_arg_t, const Allocator &a);
promise(promise &&rhs) noexcept;
promise(const promise &) = delete;
~promise();
promise &operator=(promise &&rhs) noexcept;
promise &operator=(const promise &) = delete;
void swap(promise &other) noexcept;
future get_future();
void set_value(const R &value);
void set_value(R &&value);
void set_value(R &value);
void set_value();
void set_exception(exception_ptr p);
void set_value_at_thread_exit(/* see description */);
void set_exception_at_thread_exit(exception_ptr p);
};
template
void swap(promise &x, promise &y) noexcept;
template
struct uses_allocator, Alloc>;
template
class future
{
public:
future() noexcept;
future(future &&) noexcept;
future(const future &) = delete;
~future();
future &operator=(const future &) = delete;
future &operator=(future &&) noexcept;
shared_future share() noexcept;
R get();
// R &get();
// void get();
bool valid() const noexcept;
void wait() const;
template
future_status wait_for(const chrono::duration &rel_time) const;
template
future_status wait_until(const chrono::time_point &abs_time) const;
};
template
class shared_future
{
public:
shared_future() noexcept;
shared_future(const shared_future &rhs) noexcept;
shared_future(future &&) noexcept;
shared_future(shared_future &&rhs) noexcept;
~shared_future();
shared_future &operator=(const shared_future &rhs) noexcept;
shared_future &operator=(shared_future &&rhs) noexcept;
const R &get() const;
// R &get() const;
// void get() const;
bool valid() const noexcept;
void wait() const;
template
future_status wait_for(const chrono::duration &rel_time) const;
template
future_status wait_until(const chrono::time_point &abs_time) const;
};
template
class packaged_task;
template
class packaged_task
{
public:
packaged_task() noexcept;
template
explicit packaged_task(F &&f);
~packaged_task();
packaged_task(const packaged_task &) = delete;
packaged_task &operator=(const packaged_task &) = delete;
packaged_task(packaged_task &&rhs) noexcept;
packaged_task &operator=(packaged_task &&rhs) noexcept;
void swap(packaged_task &other) noexcept;
bool valid() const noexcept;
future get_future();
void operator()(ArgTypes...);
void make_ready_at_thread_exit(ArgTypes...);
void reset();
};
template
packaged_task(R (*)(ArgTypes...)) -> packaged_task;
// template
// packaged_task(F) -> packaged_task??>;
template
void swap(packaged_task &x, packaged_task &y) noexcept;
}