-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathv08_snippets.cpp
50 lines (46 loc) · 1.6 KB
/
v08_snippets.cpp
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
// Still use the old dispatch machinery. We just immediately deduce the type
// being requested.
template <typename Fn>
detail::TypeCase<detail::DeducedArgument<Fn>, Fn> typeCase_(Fn fn)
{
return detail::TypeCase<detail::DeducedArgument<Fn>, Fn>(fn);
}
// Decay turns const T& and T& into T
template <typename Fn>
using DeducedArgument = std::decay_t<FirstArgument<Fn>>;
template <typename Fn>
using FirstArgument = typename FirstArgumentImpl<Fn>::type;
// The base case is used if Fn is not a function. Assume it is a class
// with a call operator.
template <typename Fn>
struct FirstArgumentImpl
{
// Deduce the first argument of the call operator instead. This only works
// if there is only one call operator, and it's not a template. So this
// doesn't work with generic lambdas.
using type = typename FirstArgumentImpl<decltype(&Fn::operator())>::type;
};
// Deduce for function pointers, ...
template <typename R, typename Arg, typename... Args>
struct FirstArgumentImpl<R (*)(Arg, Args...)>
{
using type = Arg;
};
// ... raw function types, ...
template <typename R, typename Arg, typename... Args>
struct FirstArgumentImpl<R(Arg, Args...)>
{
using type = Arg;
};
// ... pointers to member functions, ...
template <typename R, typename C, typename Arg, typename... Args>
struct FirstArgumentImpl<R (C::*)(Arg, Args...)>
{
using type = Arg;
};
// ... and pointers to const member functions.
template <typename R, typename C, typename Arg, typename... Args>
struct FirstArgumentImpl<R (C::*)(Arg, Args...) const>
{
using type = Arg;
};