-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtask.hpp
More file actions
90 lines (76 loc) · 1.99 KB
/
task.hpp
File metadata and controls
90 lines (76 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*!
* \file task.hpp
* \author Stefano Lusardi
*/
#pragma once
#include <memory>
#include <algorithm>
#include <type_traits>
namespace ssts
{
/*! \class task
* \brief Move-only callable object.
*
* This class represents a callable object. Can be initialized with any invocable type that supports operator().
* Internally the class implements a type-erasure idiom to accept any callable signature without exposing it to the outside.
*/
class task
{
private:
struct task_base
{
virtual ~task_base() { }
virtual void invoke() = 0;
};
template<typename FunctionType>
struct task_impl : task_base
{
explicit task_impl(FunctionType&& f)
: _func{ std::move(f) }
{
static_assert(std::is_invocable_v<decltype(f)>);
}
void invoke() override { _func(); }
FunctionType _func;
};
public:
/*!
* \brief Default constructor.
* \param f Callable parameterless object wrapped within this task instance.
*
* Creates a task instance with the given callable object.
* The callable object can be e.g. a lambda function, a functor, a free function or a class method bound to an object.
*/
template<typename FunctionType>
explicit task(FunctionType&& f)
: _impl{ std::make_unique<task_impl<FunctionType>>(std::move(f)) }
{ }
task(task&) = delete;
task(const task&) = delete;
task& operator=(const task&) = delete;
/*!
* \brief Move constructor.
* \param other task object.
*
* Move constructs a task instance to this.
*/
task(task&& other) noexcept
: _impl{ std::move(other._impl) }
{ }
/*!
* \brief operator().
*
* Invokes a task.
*/
void operator()() { _impl->invoke(); }
/*!
* \brief invoke().
*
* Invokes a task.
* Explicit overload of operator().
*/
void invoke() { _impl->invoke(); }
private:
std::unique_ptr<task_base> _impl;
};
}