template typename Tuple struct Invoker template typename _Functor type

 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
template<typename Tuple>
struct Invoker
{
template<typename _Functor, typename... _ArgTypes>
struct invoke_result
: public std::result_of<_Functor( _ArgTypes...)>
{ };
template<typename>
struct result;
template<typename _Fn, typename... _Args>
struct result<std::tuple<_Fn, _Args...>>
: invoke_result<_Fn, _Args...>
{ };
typename result<Tuple>::type
operator()()
{
return _M_invoke( make_index_sequence<std::tuple_size<Tuple>::value>());
}
Tuple _M_t;
private:
template<size_t... _Ind>
typename result<Tuple>::type
_M_invoke(index_sequence<_Ind...>)
{
return nonstd::invoke(std::get<_Ind>(std::move(_M_t))...);
}
};
template<typename... _Tp>
using decayed_tuple = std::tuple<typename std::decay<_Tp>::type...>;
template<typename _Callable, typename... _Args>
static Invoker<decayed_tuple<_Callable, _Args...>>
make_invoker(_Callable&& __callable, _Args&&... __args) {
return { decayed_tuple<_Callable, _Args...> {
std::forward<_Callable>(__callable), std::forward<_Args>(__args)...
}
};
}
template <typename _Callable, typename ..._Args>
std::thread make_esthread(_Callable&& __f, _Args && ...__args) {
using InvokerT = decltype(make_invoker(std::forward<_Callable>(__f), std::forward<_Args>(__args)...));
auto _esthread_helper = [](InvokerT &&invoker) {
try {
invoker();
} catch (std::exception &e) {
report_exception(e);
} catch (...) {
report_current_exception();
throw; // that should be cancellation request, it will kill the current thread only.
// Otherwise that's something that should've never left thread body.
}
};
return std::thread(_esthread_helper, make_invoker(std::forward<_Callable>(__f), std::forward<_Args>(__args)...));
}