mirror of
https://gitlab.com/niansa/libasync.git
synced 2025-03-06 20:53:29 +01:00
59 lines
1.3 KiB
C++
59 lines
1.3 KiB
C++
#ifndef LIBASYNC_BASIC_HPP
|
|
#define LIBASYNC_BASIC_HPP
|
|
|
|
namespace async {
|
|
|
|
template<typename S>
|
|
struct callback;
|
|
|
|
template<typename R, typename... Args>
|
|
struct callback<R(Args...)> {
|
|
private:
|
|
using storage = std::aligned_storage_t<sizeof(void *), alignof(void *)>;
|
|
|
|
template<typename F>
|
|
static R invoke(storage object, Args... args) {
|
|
return (*reinterpret_cast<F *>(&object))(std::move(args)...);
|
|
}
|
|
|
|
public:
|
|
callback()
|
|
: _function(nullptr) { }
|
|
|
|
template<typename F, typename = std::enable_if_t<
|
|
sizeof(F) == sizeof(void *) && alignof(F) == alignof(void *)
|
|
&& std::is_trivially_copy_constructible<F>::value
|
|
&& std::is_trivially_destructible<F>::value>>
|
|
callback(F functor)
|
|
: _function(&invoke<F>) {
|
|
new (&_object) F{std::move(functor)};
|
|
}
|
|
|
|
explicit operator bool () {
|
|
return static_cast<bool>(_function);
|
|
}
|
|
|
|
R operator() (Args... args) {
|
|
return _function(_object, std::move(args)...);
|
|
}
|
|
|
|
private:
|
|
R (*_function)(storage, Args...);
|
|
std::aligned_storage_t<sizeof(void *), alignof(void *)> _object;
|
|
};
|
|
|
|
template<typename T>
|
|
struct awaitable {
|
|
virtual void then(callback<void(T)> awaiter) = 0;
|
|
virtual void detach() = 0;
|
|
};
|
|
|
|
template<>
|
|
struct awaitable<void> {
|
|
virtual void then(callback<void()> cb) = 0;
|
|
virtual void detach() = 0;
|
|
};
|
|
|
|
} // namespace async
|
|
|
|
#endif // LIBASYNC_BASIC_HPP
|