File: macros.h

package info (click to toggle)
polymake 4.14-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 35,888 kB
  • sloc: cpp: 168,933; perl: 43,407; javascript: 31,575; ansic: 3,007; java: 2,654; python: 632; sh: 268; xml: 117; makefile: 61
file content (314 lines) | stat: -rw-r--r-- 18,421 bytes parent folder | download | duplicates (2)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/* Copyright (c) 1997-2024
   Ewgenij Gawrilow, Michael Joswig, and the polymake team
   Technische Universität Berlin, Germany
   https://polymake.org

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
--------------------------------------------------------------------------------
*/

#pragma once

/* Most of the following macros are designed solely for the automatically generated wrapper files.
   If you use them in a manually written code, you are doing it at your own risk!

   The changes in syntax and contents must be concerted with the corresponding routines
   in the package Polymake::Core::CPlusPlus
*/

#define MacroTokenAsString(arg) #arg

#define RegistratorInstance4perl(...) \
   template<> __VA_ARGS__ __VA_ARGS__::r

#define ClassInstance4perl(pkg, file, inst_num, ...) \
   RegistratorInstance4perl( QueueingRegistrator4perl<polymake::perl_bindings::Class<__VA_ARGS__>, inst_num> ) \
   (pkg, file, inst_num)

#define Class4perl(inst_num, pkg, ...) ClassInstance4perl(#pkg, POLYMAKE_CPPERL_FILE, inst_num, __VA_ARGS__)

#define Builtin4perl(inst_num, pkg, ...) \
   RegistratorInstance4perl( QueueingRegistrator4perl<pm::perl::Builtin<__VA_ARGS__>, inst_num> ) \
   (#pkg, POLYMAKE_CPPERL_FILE, inst_num)

#define ClassTemplate4perl(inst_num, pkg) \
   RegistratorInstance4perl( StaticRegistrator4perl<pm::perl::ClassTemplate, inst_num> ) \
   (#pkg)

#define FunctionCallerTagsClass4perl Function__caller_tags_4perl
#define FunctionCallerBodyClass4perl Function__caller_body_4perl

#define FunctionCallerStart4perl \
template <typename CallerTag, pm::perl::FunctionCaller::FuncKind Kind> \
struct FunctionCallerBodyClass4perl; \
struct FunctionCallerTagsClass4perl

#define FunctionCallerName4perl(name, kind) \
FunctionCallerBodyClass4perl<FunctionCallerTagsClass4perl::name, pm::perl::FunctionCaller::FuncKind::kind>

#define FunctionCallerBody4perl(name, kind) \
template <>                                 \
struct FunctionCallerName4perl(name, kind)

// Certain amount of code duplication in the following call adapters is caused by two circumstances:
// - a void function can't be placed within another function call, even if that does not take any arguments,
//   therefore every adapter has a variant without consumer
// - consumer must be called before any temporary object created during argument retrieval is destroyed,
//   therefore the variants with consumers can't reuse variants without

// free function
#define FunctionCallerBody_free_4perl(name)                             \
FunctionCallerBody4perl(name, free)                                     \
   : public pm::perl::FunctionCaller {                                  \
   template <size_t... I_, typename... T_>                              \
   decltype(auto) operator()(const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<>, mlist<T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      return name(args_.template get<I_, T_>()...);                     \
   }                                                                    \
   template <typename Consumer_, size_t... I_, typename... T_>          \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<>, mlist<T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      return consumer_(name(args_.template get<I_, T_>()...), args_);   \
   }                                                                    \
}

// free function template requiring explicit type parameters
#define FunctionCallerBody_free_t_4perl(name)                           \
FunctionCallerBody4perl(name, free_t)                                   \
   : public pm::perl::FunctionCaller {                                  \
   template <size_t... I_, typename... E_, typename... T_>              \
   decltype(auto) operator()(const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<E_...>, mlist<T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      return name<E_...>(args_.template get<I_, T_>()...);              \
   }                                                                    \
   template <typename Consumer_, size_t... I_, typename... E_, typename... T_> \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<E_...>, mlist<T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      return consumer_(name<E_...>(args_.template get<I_, T_>()...), args_); \
   }                                                                    \
}

// class instance method
#define FunctionCallerBody_meth_4perl(name)                             \
FunctionCallerBody4perl(name, meth)                                     \
   : public pm::perl::FunctionCaller {                                  \
   template <size_t... I_, typename T0_, typename... T_>                \
   decltype(auto) operator()(const pm::perl::ArgValues<sizeof...(T_)+1>& args_, \
                             mlist<>, mlist<T0_, T_...>, std::index_sequence<0, I_...>) const \
   {                                                                    \
      return args_.template get<0, T0_>().name(args_.template get<I_, T_>()...); \
   }                                                                    \
   template <typename Consumer_, size_t... I_, typename T0_, typename... T_> \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<sizeof...(T_)+1>& args_, \
                             mlist<>, mlist<T0_, T_...>, std::index_sequence<0, I_...>) const \
   {                                                                    \
      return consumer_(args_.template get<0, T0_>().name(args_.template get<I_, T_>()...), args_); \
   }                                                                    \
}

// class instance method template requiring explicit type parameters
#define FunctionCallerBody_meth_t_4perl(name)                           \
FunctionCallerBody4perl(name, meth_t)                                   \
   : public pm::perl::FunctionCaller {                                  \
   template <size_t... I_, typename... E_, typename T0_, typename... T_> \
   decltype(auto) operator()(const pm::perl::ArgValues<sizeof...(T_)+1>& args_, \
                             mlist<E_...>, mlist<T0_, T_...>, std::index_sequence<0, I_...>) const \
   {                                                                    \
      return args_.template get<0, T0_>().template name<E_...>(args_.template get<I_, T_>()...); \
   }                                                                    \
   template <typename Consumer_, size_t... I_, typename... E_, typename T0_, typename... T_> \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<sizeof...(T_)+1>& args_, \
                             mlist<E_...>, mlist<T0_, T_...>, std::index_sequence<0, I_...>) const \
   {                                                                    \
      return consumer_(args_.template get<0, T0_>().template name<E_...>(args_.template get<I_, T_>()...), args_); \
   }                                                                    \
}

// class static method
#define FunctionCallerBody_stat_4perl(name)                             \
FunctionCallerBody4perl(name, stat)                                     \
   : public pm::perl::StaticFunctionCaller {                            \
   template <size_t... I_, typename T0_, typename... T_>                \
   decltype(auto) operator()(const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<>, mlist<T0_, T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      using class_t_ = pm::perl::static_class_t<T0_>;                   \
      return class_t_::name(args_.template get<I_, T_>()...);           \
   }                                                                    \
   template <typename Consumer_, size_t... I_, typename T0_, typename... T_> \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<>, mlist<T0_, T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      using class_t_ = pm::perl::static_class_t<T0_>;                   \
      return consumer_(class_t_::name(args_.template get<I_, T_>()...), args_); \
   }                                                                    \
}

// class static method template requiring explicit type parameters
#define FunctionCallerBody_stat_t_4perl(name)                           \
FunctionCallerBody4perl(name, stat_t)                                   \
   : public pm::perl::StaticFunctionCaller {                            \
   template <size_t... I_, typename... E_, typename T0_, typename... T_> \
   decltype(auto) operator()(const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<E_...>, mlist<T0_, T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      using class_t_ = pm::perl::static_class_t<T0_>;                   \
      return class_t_::template name<E_...>(args_.template get<I_, T_>()...); \
   }                                                                    \
   template <typename Consumer_, size_t... I_, typename... E_, typename T0_, typename... T_> \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<sizeof...(T_)>& args_, \
                             mlist<E_...>, mlist<T0_, T_...>, std::index_sequence<I_...>) const \
   {                                                                    \
      using class_t_ = pm::perl::static_class_t<T0_>;                   \
      return consumer_(class_t_::template name<E_...>(args_.template get<I_, T_>()...), args_); \
   }                                                                    \
}

#define FunctionCallerBodyImpl4perl(kind) FunctionCallerBody_##kind##_4perl
#define FunctionCaller4perl(name, kind) FunctionCallerBodyImpl4perl(kind)(name)

#define OperatorCallerName4perl(name) Operator_##name##__caller_4perl

#define UnaryOperatorCallerBody4perl(sign, name)                        \
struct OperatorCallerName4perl(name)                                    \
   : public pm::perl::FunctionCaller {                                  \
   template <typename T_>                                               \
   decltype(auto) operator()(const pm::perl::ArgValues<1>& args_,       \
                             mlist<>, mlist<T_>, std::index_sequence<0>) const \
   {                                                                    \
      return sign(args_.template get<0, T_>());                         \
   }                                                                    \
   template <typename Consumer_, typename T_>                           \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<1>& args_,       \
                             mlist<>, mlist<T_>, std::index_sequence<0>) const \
   {                                                                    \
      return consumer_(sign(args_.template get<0, T_>()), args_);       \
   }                                                                    \
}

#define BinaryOperatorCallerBody4perl(sign, name)                       \
struct OperatorCallerName4perl(name) : pm::perl::FunctionCaller {       \
   template <typename T0_, typename T1_>                                \
   decltype(auto) operator()(const pm::perl::ArgValues<2>& args_,       \
                             mlist<>, mlist<T0_, T1_>, std::index_sequence<0, 1>) const \
   {                                                                    \
      return args_.template get<0, T0_>() sign args_.template get<1, T1_>(); \
   }                                                                    \
   template <typename Consumer_, typename T0_, typename T1_>            \
   decltype(auto) operator()(const Consumer_ consumer_,                 \
                             const pm::perl::ArgValues<2>& args_,       \
                             mlist<>, mlist<T0_, T1_>, std::index_sequence<0, 1>) const \
   {                                                                    \
      return consumer_(args_.template get<0, T0_>() sign args_.template get<1, T1_>(), args_); \
   }                                                                    \
}

#define SubstTypeList4perl TypeList4perl
#define TypeList4perl(...) mlist<__VA_ARGS__>

#define FunctionTemplateInstance4perl(inst_num, name, kind, uniq_name, flags, n_explicit, arg_types, ...) \
   RegistratorInstance4perl( QueueingRegistrator4perl<pm::perl::FunctionWrapper<FunctionCallerName4perl(name, kind), \
                             flags, n_explicit, SubstTypeList4perl arg_types>, inst_num> ) \
   (#uniq_name, POLYMAKE_CPPERL_FILE, inst_num, ##__VA_ARGS__)

#define OperatorTemplateInstance4perl(inst_num, name, uniq_name, flags, arg_types, ...) \
   RegistratorInstance4perl( QueueingRegistrator4perl<pm::perl::FunctionWrapper<pm::perl::OperatorCallerName4perl(name), \
                             flags, 0, SubstTypeList4perl arg_types>, inst_num> ) \
   (#uniq_name, POLYMAKE_CPPERL_FILE, inst_num, ##__VA_ARGS__)


#define FunctionInstance4perl(f_class, ...) ERROR obsolete wrapper - please delete and regenerate
#define OperatorInstance4perl(op_class, ...) ERROR obsolete wrapper - please delete and regenerate
#define FunctionCrossAppInstance4perl(f_class, app_list, ...) ERROR obsolete wrapper - please delete and regenerate
#define OperatorCrossAppInstance4perl(op_class, app_list, ...) ERROR obsolete wrapper - please delete and regenerate

#define FunctionInterface4perl(name, ...) ERROR obsolete wrapper - please delete and regenerate

#define FunctionWrapper4perl(...) ERROR obsolete wrapper - please delete and regenerate

#define FunctionWrapperInstance4perl(...) ERROR obsolete wrapper - please delete and regenerate

// ---

#define FindDefinitionSource4perl2(dir,name) MacroTokenAsString(dir/name)
#define FindDefinitionSource4perl(name) FindDefinitionSource4perl2(POLYMAKE_DEFINITION_SOURCE_DIR, name)

#ifdef POLYMAKE_NO_EMBEDDED_RULES
// module with wrapper code only; proper definitions are located in core or another extension

#define DeclareRegularFunction(...) namespace { }
#define InsertEmbeddedRule(...) namespace { }
#define OpaqueClass4perl(...) namespace { }
#define OpaqueMethod4perl(...)

#else

#define SourceLine4perl(line, file) "#line " MacroTokenAsString(line) " \"" MacroTokenAsString(file) "\"\n"

#define DeclareRegularFunction(pre, fptr, decl)  \
namespace {                                       \
   RegistratorInstance4perl( QueueingRegistrator4perl<pm::perl::RegularFunctionWrapper<decltype(fptr),fptr>,__LINE__> ) \
   (pre " " decl " : c++ (regular=>%d);\n", SourceLine4perl(__LINE__, POLYMAKE_DEFINITION_SOURCE_FILE), 0); \
}

#define InsertEmbeddedRule(text)                                                      \
namespace {                                                                            \
   RegistratorInstance4perl( QueueingRegistrator4perl<pm::perl::EmbeddedRule,__LINE__> ) \
      (text, SourceLine4perl(__LINE__, POLYMAKE_DEFINITION_SOURCE_FILE));                               \
}

#define FullPackage4perl(pkg, app) "Polymake::" MacroTokenAsString(app) "::" pkg

#define OpaqueClass4perl(pkg, name, methods)                                        \
namespace {                                                                         \
   ClassInstance4perl(FullPackage4perl(pkg, POLYMAKE_APPNAME), nullptr, 0, name);   \
}                                                                                   \
InsertEmbeddedRule("# @hide\n"                                                      \
                   "declare property_type " pkg " : c++ (special=>'" #name "') {\n" \
                   methods                                                          \
                   "}\n")

#define OpaqueMethod4perl(decl) "\nmethod " decl " : c++;\n"

#endif

#define Function4perl(fptr, decl)           DeclareRegularFunction(            "function",fptr,decl)
#define UserFunction4perl(help, fptr, decl) DeclareRegularFunction(help "\nuser_function",fptr,decl)

#define FunctionTemplate4perl(decl)           InsertEmbeddedRule("function " decl " : c++;\n")
#define UserFunctionTemplate4perl(help, decl) InsertEmbeddedRule(help "\nuser_function " decl " : c++;\n")

#define RecognizeType4perl(name, typelist, ...)                         \
decltype(auto) recognize(pm::perl::type_infos& ti, bait, T*, __VA_ARGS__*) \
{                                                                       \
   const std::is_same<T, __VA_ARGS__ > exact_match{};                   \
   if (SV* proto = pm::perl::PropertyTypeBuilder::build(name, SubstTypeList4perl typelist (), exact_match)) \
      ti.set_proto(proto);                                              \
   return exact_match;                                                  \
}


// Local Variables:
// mode:C++
// c-basic-offset:3
// indent-tabs-mode:nil
// End: