PLaSK library
Loading...
Searching...
No Matches
metaprog.hpp
Go to the documentation of this file.
1
/*
2
* This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3
* Copyright (c) 2022 Lodz University of Technology
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, version 3.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*/
14
#ifndef PLASK__UTILS_METAPROG_H
15
#define PLASK__UTILS_METAPROG_H
16
21
#include <tuple>
22
#include <type_traits>
23
24
namespace
plask
{
25
36
template
<
int
nr
,
typename
...
types
>
37
struct
chooseType
{
38
typedef
typename
std::tuple_element<nr, std::tuple<
types
...>>
::type
type
;
39
};
40
41
//TODO better impl. but not compilable with GCC 4.6 (unimplemented)
42
/*template <int nr, typename firstType, typename... restTypes> struct chooseType {
44
typedef typename chooseType<nr-1, restTypes...>::type type;
45
};
46
47
template <typename firstType, typename... restTypes> struct chooseType<0, firstType, restTypes...> {
48
typedef firstType type;
49
};*/
50
51
52
//http://talesofcpp.fusionfenix.com/post-11/true-story-call-me-maybe
53
namespace
hyman {
54
template
<
typename
T>
55
using
always_void
=
void
;
56
57
template
<
typename
Expr, std::
size_t
Step = 0,
typename
Enable =
void
>
58
struct
is_callable_impl
59
:
is_callable_impl
<Expr, Step + 1>
60
{};
61
62
// (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T
63
// and t1 is an object of type T or a reference to an object of type T or a
64
// reference to an object of a type derived from T;
65
template
<
typename
F
,
typename
T,
typename
...Args>
66
struct
is_callable_impl
<
F
(T,
Args
...), 0,
67
always_void
<
decltype
(
68
(
std
::
declval
<T>().*std::declval<F>())(std::declval<Args>()...)
69
)>
70
> : std::true_type
71
{};
72
73
// ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T
74
// and t1 is not one of the types described in the previous item;
75
template
<
typename
F
,
typename
T,
typename
...Args>
76
struct
is_callable_impl
<
F
(T,
Args
...), 1,
77
always_void
<
decltype
(
78
((*std::declval<T>()).*std::declval<F>())(std::declval<Args>()...)
79
)>
80
> :
std
::true_type
81
{};
82
83
// t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an
84
// object of type T or a reference to an object of type T or a reference to an
85
// object of a type derived from T;
86
template
<
typename
F,
typename
T>
87
struct
is_callable_impl
<
F
(T), 2,
88
always_void
<
decltype
(
89
std
::
declval
<T>().*std::declval<F>()
90
)>
91
> : std::true_type
92
{};
93
94
// (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is
95
// not one of the types described in the previous item;
96
template
<
typename
F,
typename
T>
97
struct
is_callable_impl
<
F
(T), 3,
98
always_void
<
decltype
(
99
(*std::declval<T>()).*std::declval<F>()
100
)>
101
> :
std
::true_type
102
{};
103
104
// f(t1, t2, ..., tN) in all other cases.
105
template
<
typename
F
,
typename
...Args>
106
struct
is_callable_impl
<
F
(
Args
...), 4,
107
always_void
<
decltype
(
108
std
::
declval
<F>()(std::declval<Args>()...)
109
)>
110
> : std::true_type
111
{};
112
113
template
<
typename
Expr>
114
struct
is_callable_impl
<
Expr
, 5>
115
: std::false_type
116
{};
117
}
118
122
template
<
typename
Expr>
123
struct
is_callable
124
:
hyman::is_callable_impl
<Expr>
125
{};
126
127
128
}
// namespace plask
129
130
131
#endif
// PLASK__UTILS_METAPROG_H
plask
utils
metaprog.hpp
Generated by
1.9.8