@@ -25,26 +25,28 @@ namespace meevax
25
25
{
26
26
inline namespace kernel
27
27
{
28
- struct callable
28
+ struct primitive_procedure
29
29
{
30
+ using signature = auto (*)(object &) -> object;
31
+
30
32
std::string const name;
31
33
32
- explicit callable (std::string const & name)
34
+ explicit primitive_procedure (std::string const & name)
33
35
: name { name }
34
36
{}
35
37
36
38
virtual auto operator ()(object & = unit) const -> object = 0;
37
39
};
38
40
39
- auto operator <<(std::ostream &, callable const &) -> std::ostream &;
41
+ auto operator <<(std::ostream &, primitive_procedure const &) -> std::ostream &;
40
42
41
43
template <typename F>
42
- struct generic_procedure : public callable
44
+ struct generic_procedure : public primitive_procedure
43
45
{
44
46
std::enable_if_t <std::is_invocable_v<F> or std::is_invocable_v<F, object &>, F> invocable;
45
47
46
48
explicit generic_procedure (std::string const & name, F f)
47
- : callable { name }
49
+ : primitive_procedure { name }
48
50
, invocable { f }
49
51
{}
50
52
@@ -95,67 +97,68 @@ inline namespace kernel
95
97
into function pointer types to reduce the number of template
96
98
instantiations.
97
99
*/
98
- template <typename , typename F, typename = void >
99
- struct procedure
100
+ template <typename F, typename = void >
101
+ struct procedure_traits
100
102
{
101
103
using type = generic_procedure<F>;
102
104
};
103
105
104
106
/*
105
107
Thunk
106
108
*/
107
- template <typename T, typename F>
108
- struct procedure <T, F, std::enable_if_t <std::is_convertible_v<F, auto (*)() -> object>>>
109
+ template <typename F>
110
+ struct procedure_traits < F, std::enable_if_t <std::is_convertible_v<F, auto (*)() -> object>>>
109
111
{
110
112
using type = generic_procedure<auto (*)() -> object>;
111
113
};
112
114
113
115
/*
114
116
Procedure
115
117
*/
116
- template <typename T, typename F>
117
- struct procedure <T, F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object const &) -> object>>>
118
+ template <typename F>
119
+ struct procedure_traits < F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object const &) -> object>>>
118
120
{
119
121
using type = generic_procedure<auto (*)(object const &) -> object>;
120
122
};
121
123
122
124
/*
123
125
Linear update procedure
124
126
*/
125
- template <typename T, typename F>
126
- struct procedure <T, F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object &) -> object>>>
127
+ template <typename F>
128
+ struct procedure_traits < F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object &) -> object>>>
127
129
{
128
130
using type = generic_procedure<auto (*)(object &) -> object>;
129
131
};
130
132
131
133
/*
132
134
Predicate
133
135
*/
134
- template <typename T, typename F>
135
- struct procedure <T, F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object const &) -> bool >>>
136
+ template <typename F>
137
+ struct procedure_traits < F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object const &) -> bool >>>
136
138
{
137
139
using type = generic_procedure<auto (*)(object const &) -> bool >;
138
140
};
139
141
140
142
/*
141
143
Command
142
144
*/
143
- template <typename T, typename F>
144
- struct procedure <T, F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object const &) -> void >>>
145
+ template <typename F>
146
+ struct procedure_traits < F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object const &) -> void >>>
145
147
{
146
148
using type = generic_procedure<auto (*)(object const &) -> void >;
147
149
};
148
150
149
151
/*
150
152
Mutation
151
153
*/
152
- template <typename T, typename F>
153
- struct procedure <T, F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object &) -> void >>>
154
+ template <typename F>
155
+ struct procedure_traits < F, std::enable_if_t <std::is_convertible_v<F, auto (*)(object &) -> void >>>
154
156
{
155
157
using type = generic_procedure<auto (*)(object &) -> void >;
156
158
};
157
159
158
- using procedure_pointer = auto (*)(object &) -> object;
160
+ template <typename T, typename ... Ts>
161
+ using procedure = std::enable_if_t <std::is_convertible_v<T, std::string>, procedure_traits<Ts...>>;
159
162
} // namespace kernel
160
163
} // namespace meevax
161
164
0 commit comments