6
struct rhs { // + - *...
8
rhs(s n="", s r="") : name(n), ref(r) {}
10
struct op { // + - *...
12
op(s n="", s t="") : name(n), tag(t) {}
14
struct aop { // assign_op: += -= ...
16
aop(s n="", s ln="") : name(n), long_name(ln) {}
18
enum size_check_t { no_check, class_check, expr_check, expr2_check };
19
struct func { // abs sqrt...
21
func (s f1) : f(f1), std_f(f1) {}
22
func (s f1, s std_f1) : f(f1), std_f(std_f1) {}
24
void header(string NAME, string name) {
25
cout << "#ifndef _RHEOLEF_" << NAME << "_EXPR_OPS_H" << endl
26
<< "#define _RHEOLEF_" << NAME << "_EXPR_OPS_H" << endl
27
<< "// do not edit !" << endl
28
<< "// this file has been automatically generated by the command:" << endl
30
<< "// ./" << name << "_expr_ops_make > " << name << "_expr_ops.h" << endl
32
<< "// ==========================================================================" << endl
34
<< "// This file is part of Rheolef." << endl
36
<< "// Copyright (C) 2000-2009 Pierre Saramito " << endl
38
<< "// Rheolef is free software; you can redistribute it and/or modify" << endl
39
<< "// it under the terms of the GNU General Public License as published by" << endl
40
<< "// the Free Software Foundation; either version 2 of the License, or" << endl
41
<< "// (at your option) any later version." << endl
43
<< "// Rheolef is distributed in the hope that it will be useful," << endl
44
<< "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << endl
45
<< "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << endl
46
<< "// GNU General Public License for more details." << endl
48
<< "// You should have received a copy of the GNU General Public License" << endl
49
<< "// along with Rheolef; if not, write to the Free Software" << endl
50
<< "// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA" << endl
52
<< "// ==========================================================================" << endl
54
<< "// " << name << ": template expressions" << endl
56
<< "// author: Pierre.Saramito@imag.fr" << endl
58
<< "// date: 20 march 2011" << endl
60
<< "#include \"rheolef/promote.h\"" << endl
61
<< "#include \"rheolef/" << name << "_expr.h\"" << endl
62
<< "namespace rheolef {" << endl
65
void footer(string NAME, string name) {
66
cout << "} // namespace rheolef" << endl
67
<< "#endif // _RHEOLEF_" << NAME << "_EXPR_OPS_H" << endl
70
// =====================================================================================
71
// part 1 : binary operations x+y x-y ...
72
// =====================================================================================
73
void binop_profile (s op, s tag, s trait, s domain, s left, s right) {
74
cout << "#if BOOST_VERSION < 104601" << endl
76
<< "boost::proto::detail::enable_binary<" << endl
77
<< " " << domain << "," << endl
78
<< " " << trait << "<" << left << " >," << endl
79
<< " " << left << "," << endl
80
<< " " << trait << "<" << right << " >," << endl
81
<< " " << right << "," << endl
82
<< " typename boost::proto::functional::make_expr<" << tag << ", " << domain << ">" << endl
83
<< " ::impl<const " << left << "&, const " << right << "&>::result_type const" << endl
85
<< "operator" << op << " (const " << left << "& l, const " << right << "& r)" << endl
87
<< " return boost::proto::functional::make_expr<" << tag << ", " << domain << ">" << endl
88
<< " ::impl<const " << left << "&, const " << right << "&>() (l, r);" << endl
90
<< "#else // BOOST_VERSION >= 104601" << endl
91
<< "typename boost::proto::detail::enable_binary< " << endl
92
<< " " << domain << "," << endl
93
<< " " << domain << "::proto_grammar," << endl
94
<< " boost::mpl::and_<" << endl
95
<< " boost::mpl::or_<" << trait << "<" << left << " >, " << trait << "<" << right << " > >," << endl
96
<< " boost::mpl::not_<" << endl
97
<< " boost::mpl::or_<" << endl
98
<< " boost::proto::is_extension<" << left << " >," << endl
99
<< " boost::proto::is_extension<" << right << " >" << endl
103
<< " " << tag << "," << endl
104
<< " " << left << " const &," << endl
105
<< " " << right << " const &" << endl
106
<< ">::type /* const */" << endl
107
<< "operator" << op << " (" << left << " const &left, " << right << " const &right)" << endl
109
<< " return boost::proto::detail::make_expr_<" << tag << ", " << domain << ", "
110
<< left << " const &, " << right << " const &>()(left, right);" << endl
112
<< "#endif // BOOST_VERSION" << endl
115
void binop (s op, s tag, s trait, s domain, const vector<s>& Class, s expr) {
117
for (size_t j = 0, nc = Class.size(); j < nc; j++) {
118
cout << "template<class T, class M>" << endl;
119
binop_profile (op, tag, trait, domain, "int", Class[j] + "<T,M>");
120
cout << "template<class T, class M>" << endl;
121
binop_profile (op, tag, trait, domain, "T", Class[j] + "<T,M>");
124
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
125
cout << "template<class T, class M>" << endl;
126
binop_profile (op, tag, trait, domain, Class[i] + "<T,M>", "int");
127
cout << "template<class T, class M>" << endl;
128
binop_profile (op, tag, trait, domain, Class[i] + "<T,M>", "T");
131
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
132
for (size_t j = 0, nd = Class.size(); j < nd; j++) {
133
cout << "template<class T1, class T2, class M>" << endl;
134
binop_profile(op, tag, trait, domain, Class[i] + "<T1,M>", Class[j] + "<T2,M>");
137
cout << "template<class Expr>" << endl;
138
binop_profile(op, tag, trait, domain, "int", expr + "<Expr>");
139
cout << "template<class Expr>" << endl;
140
binop_profile(op, tag, trait, domain, expr + "<Expr>", "int");
141
cout << "template<class T, class Expr>" << endl;
142
binop_profile(op, tag, trait, domain, "T", expr + "<Expr>");
143
cout << "template<class T, class Expr>" << endl;
144
binop_profile(op, tag, trait, domain, expr + "<Expr>", "T");
146
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
147
cout << "template<class T, class M, class Expr>" << endl;
148
binop_profile(op, tag, trait, domain, Class[i] + "<T,M>", expr + "<Expr>");
149
cout << "template<class T, class M, class Expr>" << endl;
150
binop_profile(op, tag, trait, domain, expr + "<Expr>", Class[i] + "<T,M>");
153
cout << "template<class Expr1, class Expr2>" << endl;
154
binop_profile(op, tag, trait, domain, expr + "<Expr1>", expr + "<Expr2>");
156
// -----------------------------------------------------------------------------
157
void all_binops (s trait, s domain, const vector<op>& Op, const vector<s>& Class, s expr) {
158
for (size_t i = 0, nop = Op.size(); i < nop; i++) {
159
binop (Op[i].name, Op[i].tag, trait, domain, Class, expr);
162
// =====================================================================================
163
// part 2 : unary operations +x, -x
164
// =====================================================================================
165
void unop_profile (s op, s tag, s trait, s domain, s x) {
166
cout << "#if BOOST_VERSION < 104601" << endl
167
<< "typename boost::proto::detail::enable_unary<" << endl
168
<< " " << domain << "," << endl
169
<< " " << trait << "<" << x << " >," << endl
170
<< " " << x << "," << endl
171
<< " typename boost::proto::functional::make_expr<" << tag << ", " << domain << ">" << endl
172
<< " ::impl<const " << x << "&>::result_type" << endl
173
<< " >::type const" << endl
174
<< "operator" << op << " (const " << x << "& arg)" << endl
176
<< " return boost::proto::functional::make_expr<" << tag << ", " << domain << ">" << endl
177
<< " ::impl<const " << x << "&>()(arg);" << endl
179
<< "#else // BOOST_VERSION >= 104601" << endl
180
<< "typename boost::proto::detail::enable_unary<" << endl
181
<< " " << domain << "," << endl
182
<< " " << domain << "::proto_grammar," << endl
183
<< " boost::mpl::and_<" << endl
184
<< " " << trait << "<" << x << " >," << endl
185
<< " boost::mpl::not_<boost::proto::is_extension<" << x << " > >" << endl
187
<< " " << tag << "," << endl
188
<< " " << x << " const &" << endl
189
<< ">::type const" << endl
190
<< "operator" << op << " (const " << x << "& arg)" << endl
192
<< " return boost::proto::detail::make_expr_<" << tag << ", " << domain << ", "
193
<< x << " const &>()(arg);" << endl
195
<< "#endif // BOOST_VERSION" << endl
198
// -----------------------------------------------------------------------------
199
void unop (s op, s tag, s trait, s domain, const vector<s>& Class, s expr) {
200
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
201
cout << "template<class T, class M>" << endl;
202
unop_profile (op, tag, trait, domain, Class[i] + "<T,M>");
204
cout << "template<class Expr>" << endl;
205
unop_profile (op, tag, trait, domain, expr + "<Expr>");
207
// -----------------------------------------------------------------------------
208
void all_unops (s trait, s domain, const vector<op>& Op, const vector<s>& Class, s expr) {
209
for (size_t i = 0, nop = Op.size(); i < nop; i++) {
210
unop (Op[i].name, Op[i].tag, trait, domain, Class, expr);
213
// =====================================================================================
214
// part 3 : unary std math functions:
215
// =====================================================================================
216
void ufunc_declare (s f, s std_f, s details) {
217
cout << "namespace " << details << " {" << endl
218
<< " struct " << f << "_ {" << endl
219
<< " template<class Sig>" << endl
220
<< " struct result;" << endl
222
<< " template<class This, class T>" << endl
223
<< " struct result<This(T)> : boost::remove_const<typename boost::remove_reference<T>::type> {};" << endl
225
<< " template<class T>" << endl
226
<< " T operator() (const T& x) const { return " << std_f << "(x); }" << endl
228
<< "} // namespace " << details << endl
231
void ufunc_profile (s f, s tag, s domain, s details, s x) {
232
cout << "typename boost::proto::result_of::make_expr<" << endl
233
<< " " << tag << "," << endl
234
<< " " << domain << "," << endl
235
<< " " << "const " << details << "::" << f << "_," << endl
236
<< " " << "const " << x << "&" << endl
237
<< " >::type" << endl
238
<< f << " (const " << x << "& x)" << endl
240
<< " return boost::proto::make_expr<" << tag << ", " << domain << "> ("
241
<< details << "::" << f << "_(), boost::ref(x));" << endl
245
void ufunc (s f, s std_f, s tag, s domain, s details, const vector<s>& Class, s expr) {
246
ufunc_declare (f, std_f, details);
247
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
248
cout << "template<class T, class M>" << endl;
249
ufunc_profile (f, tag, domain, details, Class[i] + "<T,M>");
251
cout << "template<class Expr>" << endl;
252
ufunc_profile (f, tag, domain, details, expr + "<Expr>");
254
void all_ufunc (s tag, s domain, s details, const vector<func>& Ufunc, const vector<s>& Class, s expr) {
255
for (size_t i = 0, nf = Ufunc.size(); i < nf; i++) {
256
ufunc (Ufunc[i].f, Ufunc[i].std_f, tag, domain, details, Class, expr);
259
// =====================================================================================
260
// part 4 : binary std math functions:
261
// =====================================================================================
262
void bifunc_declare (s f, s std_f, s details) {
263
cout << "namespace " << details << " {" << endl
264
<< " struct " << f << "_ {" << endl
265
<< " template<class Sig>" << endl
266
<< " struct result;" << endl
268
<< " template<class This, class U, class V>" << endl
269
<< " struct result<This(U,V)> : boost::remove_const<" << endl
270
<< " typename promote<" << endl
271
<< " typename boost::remove_const<typename boost::remove_reference<U>::type>::type," << endl
272
<< " typename boost::remove_const<typename boost::remove_reference<V>::type>::type" << endl
273
<< " >::type> {};" << endl
275
<< " template<class U, class V>" << endl
276
<< " typename promote<" << endl
277
<< " typename boost::remove_const<typename boost::remove_reference<U>::type>::type," << endl
278
<< " typename boost::remove_const<typename boost::remove_reference<V>::type>::type >::type" << endl
279
<< " operator() (const U& x, const V& y) const { return " << std_f << "(x,y); }" << endl
281
<< "} // namespace " << details << endl
284
void bifunc_profile (s f, s tag, s domain, s details, s x, s y) {
285
cout << "typename boost::proto::result_of::make_expr<" << endl
286
<< " " << tag << "," << endl
287
<< " " << domain << "," << endl
288
<< " " << "const " << details << "::" << f << "_," << endl
289
<< " " << "const " << x << "&," << endl
290
<< " " << "const " << y << "&" << endl
291
<< " >::type" << endl
292
<< f << " (const " << x << "& x, const " << y << "& y)" << endl
294
<< " return boost::proto::make_expr<" << tag << ", " << domain << "> ("
295
<< details << "::" << f << "_(), boost::ref(x), boost::ref(y));" << endl
311
void bifunc (s f, s std_f, s tag, s domain, s details, const vector<s>& Class, s expr) {
312
bifunc_declare (f, std_f, details);
314
for (size_t j = 0, nd = Class.size(); j < nd; j++) {
315
cout << "template<class T, class M>" << endl;
316
bifunc_profile (f, tag, domain, details, "int", Class[j] + "<T,M>");
317
cout << "template<class T1, class T2, class M>" << endl;
318
bifunc_profile (f, tag, domain, details, "T1", Class[j] + "<T2,M>");
321
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
322
cout << "template<class T, class M>" << endl;
323
bifunc_profile (f, tag, domain, details, Class[i] + "<T,M>", "int");
324
cout << "template<class T1, class T2, class M>" << endl;
325
bifunc_profile (f, tag, domain, details, Class[i] + "<T1,M>", "T2");
328
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
329
for (size_t j = 0, nd = Class.size(); j < nd; j++) {
330
cout << "template<class T1, class T2, class M>" << endl;
331
bifunc_profile (f, tag, domain, details, Class[i] + "<T1,M>", Class[j] + "<T2,M>");
334
cout << "template<class Expr>" << endl;
335
bifunc_profile (f, tag, domain, details, "int", expr + "<Expr>");
336
cout << "template<class T, class Expr>" << endl;
337
bifunc_profile (f, tag, domain, details, "T", expr + "<Expr>");
338
cout << "template<class Expr>" << endl;
339
bifunc_profile (f, tag, domain, details, expr + "<Expr>", "int");
340
cout << "template<class T, class Expr>" << endl;
341
bifunc_profile (f, tag, domain, details, expr + "<Expr>", "T");
343
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
344
cout << "template<class T, class M, class Expr>" << endl;
345
bifunc_profile (f, tag, domain, details, Class[i] + "<T,M>", expr + "<Expr>");
346
cout << "template<class T, class M, class Expr>" << endl;
347
bifunc_profile (f, tag, domain, details, expr + "<Expr>", Class[i] + "<T,M>");
350
cout << "template<class Expr1, class Expr2>" << endl;
351
bifunc_profile (f, tag, domain, details, expr + "<Expr1>", expr + "<Expr2>");
353
void all_bifunc (s tag, s domain, s details, const vector<func>& Ufunc, const vector<s>& Class, s expr) {
354
for (size_t i = 0, nf = Ufunc.size(); i < nf; i++) {
355
bifunc (Ufunc[i].f, Ufunc[i].std_f, tag, domain, details, Class, expr);
358
// =====================================================================================
359
// part 5 : unary interpolate compose function: vh=compose(f,uh) aka vh = pi_h(f o uh)
360
// =====================================================================================
361
void ucompose_declare (s f, s details) {
362
cout << "namespace " << details << " {" << endl
363
<< " template<class Function>" << endl
364
<< " struct " << f << "_ {" << endl
365
<< " " << f << "_ (const Function& f) : _f(f) {}" << endl
366
<< " Function _f;" << endl
368
<< " template<class Sig> struct result;" << endl
370
<< " template<class This, class T>" << endl
371
<< " struct result<This(T)> : boost::remove_const<typename boost::remove_reference<T>::type> {};" << endl
373
<< " template<class T>" << endl
374
<< " T operator() (const T& x) const { return _f (x); }" << endl
376
<< " template<class Arg, class Result>" << endl
377
<< " struct " << f << "_<Result(Arg)> {" << endl
378
<< " " << f << "_ (Result (*f)(Arg)) : _f(std::ptr_fun(f)) {}" << endl
379
<< " std::pointer_to_unary_function<Arg,Result> _f;" << endl
381
<< " template<class Sig> struct result;" << endl
383
<< " template<class This, class U>" << endl
384
<< " struct result<This(U)> : boost::remove_const<typename boost::remove_reference<Result>::type> {};" << endl
386
<< " Result operator() (Arg x) const { return _f (x); }" << endl
388
<< "} // namespace " << details << endl
391
void ucompose_profile (s f, s tag, s domain, s details, s x) {
392
cout << "typename boost::proto::result_of::make_expr<" << endl
393
<< " " << tag << "," << endl
394
<< " " << domain << "," << endl
395
<< " const " << details << "::" << f << "_<Function>," << endl
396
<< " const " << x << "&" << endl
397
<< " >::type" << endl
398
<< f << " (const Function& f, const " << x << "& x)" << endl
400
<< " return boost::proto::make_expr<" << tag << ", " << domain << ">" << endl
401
<< " (" << details << "::" << f << "_<Function>(f), boost::ref(x));" << endl
405
void ucompose (s tag, s domain, s details, s f, const vector<s>& Class, s expr) {
406
ucompose_declare (f, details);
407
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
408
cout << "template<class Function, class T, class M>" << endl;
409
ucompose_profile (f, tag, domain, details, Class[i] + "<T,M>");
411
cout << "template<class Function, class Expr>" << endl;
412
ucompose_profile (f, tag, domain, details, expr + "<Expr>");
414
// =====================================================================================
415
// part 6 : binary interpolate compose function: wh=compose(f,uh,vh) aka wh = pi_h(f(uh,vh))
416
// =====================================================================================
417
void bicompose_declare (s f, s details) {
418
cout << "namespace " << details << " {" << endl
419
<< " template<class Function>" << endl
420
<< " struct " << f << "2_ {" << endl
421
<< " " << f << "2_ (const Function& f) : _f(f) {}" << endl
422
<< " Function _f;" << endl
424
<< " template<class Sig> struct result;" << endl
426
<< " template<class This, class U, class V>" << endl
427
<< " struct result<This(U,V)> : boost::remove_const<" << endl
428
<< " typename promote<" << endl
429
<< " typename boost::remove_const<typename boost::remove_reference<U>::type>::type," << endl
430
<< " typename boost::remove_const<typename boost::remove_reference<V>::type>::type" << endl
431
<< " >::type> {};" << endl
433
<< " template<class U, class V>" << endl
434
<< " typename promote<" << endl
435
<< " typename boost::remove_const<typename boost::remove_reference<U>::type>::type," << endl
436
<< " typename boost::remove_const<typename boost::remove_reference<V>::type>::type >::type" << endl
437
<< " operator() (const U& x, const V& y) const { return _f (x); }" << endl
439
<< " template<class Arg1, class Arg2, class Result>" << endl
440
<< " struct " << f << "2_<Result(Arg1,Arg2)> {" << endl
441
<< " " << f << "2_ (Result (*f)(Arg1,Arg2)) : _f(std::ptr_fun(f)) {}" << endl
442
<< " std::pointer_to_binary_function<Arg1,Arg2,Result> _f;" << endl
444
<< " template<class Sig> struct result;" << endl
446
<< " template<class This, class U, class V>" << endl
447
<< " struct result<This(U,V)> : boost::remove_const<" << endl
448
<< " typename promote<" << endl
449
<< " typename boost::remove_const<typename boost::remove_reference<U>::type>::type," << endl
450
<< " typename boost::remove_const<typename boost::remove_reference<V>::type>::type" << endl
451
<< " >::type> {};" << endl
453
<< " Result operator() (Arg1 x, Arg2 y) const { return _f (x,y); }" << endl
455
<< "} // namespace " << details << endl
458
void bicompose_profile (s f, s tag, s domain, s details, s x, s y) {
459
cout << "typename boost::proto::result_of::make_expr<" << endl
460
<< " " << tag << "," << endl
461
<< " " << domain << "," << endl
462
<< " const " << details << "::" << f << "2_<Function>," << endl
463
<< " const " << x << "&," << endl
464
<< " const " << y << "&" << endl
465
<< " >::type" << endl
466
<< f << " (const Function& f, const " << x << "& x, const " << y << "& y)" << endl
468
<< " return boost::proto::make_expr<" << tag << ", " << domain << ">" << endl
469
<< " (" << details << "::" << f << "2_<Function>(f), boost::ref(x), boost::ref(y));" << endl
485
void bicompose (s tag, s domain, s details, s f, const vector<s>& Class, s expr) {
486
bicompose_declare (f, details);
488
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
489
cout << "template<class Function, class T, class M>" << endl;
490
bicompose_profile (f, tag, domain, details, "int", Class[i] + "<T,M>");
491
cout << "template<class Function, class T, class M>" << endl;
492
bicompose_profile (f, tag, domain, details, Class[i] + "<T,M>", "int");
493
cout << "template<class Function, class T1, class T2, class M>" << endl;
494
bicompose_profile (f, tag, domain, details, "T1", Class[i] + "<T2,M>");
495
cout << "template<class Function, class T1, class T2, class M>" << endl;
496
bicompose_profile (f, tag, domain, details, Class[i] + "<T1,M>", "T2");
499
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
500
for (size_t j = 0, nd = Class.size(); j < nd; j++) {
501
cout << "template<class Function, class T1, class T2, class M>" << endl;
502
bicompose_profile (f, tag, domain, details, Class[i] + "<T1,M>", Class[j] + "<T2,M>");
505
cout << "template<class Function, class Expr>" << endl;
506
bicompose_profile (f, tag, domain, details, "int", expr + "<Expr>");
507
cout << "template<class Function, class Expr>" << endl;
508
bicompose_profile (f, tag, domain, details, expr + "<Expr>", "int");
509
cout << "template<class Function, class T, class Expr>" << endl;
510
bicompose_profile (f, tag, domain, details, "T", expr + "<Expr>");
511
cout << "template<class Function, class T, class Expr>" << endl;
512
bicompose_profile (f, tag, domain, details, expr + "<Expr>", "T");
514
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
515
cout << "template<class Function, class Expr, class T, class M>" << endl;
516
bicompose_profile (f, tag, domain, details, Class[i] + "<T,M>", expr + "<Expr>");
517
cout << "template<class Function, class Expr, class T, class M>" << endl;
518
bicompose_profile (f, tag, domain, details, expr + "<Expr>", Class[i] + "<T,M>");
521
cout << "template<class Function, class Expr1, class Expr2>" << endl;
522
bicompose_profile (f, tag, domain, details, expr + "<Expr1>", expr + "<Expr2>");
524
// =====================================================================================
525
// part 7 : assign_op : x += y[dom]; y[dom] *= 2; etc
526
// =====================================================================================
527
void assign_op_declare (s op, s long_name, s details) {
528
cout << "namespace " << details << " {" << endl
529
<< " struct " << long_name << " {" << endl
530
<< " template<class T, class U>" << endl
531
<< " void operator() (T &t, const U &u) const { t " << op << " u; }" << endl
533
<< "} // namespace " << details << endl
536
void assign_op_profile (string name, string size, s op, s long_name, s trait, s domain, s details, s left, s right, size_check_t size_check = no_check) {
537
s begin = (size == "size") ? "begin" : "begin_dof"; // field: ndof, begin_dof, end_dof
538
s end = (size == "size") ? "end" : "end_dof";
540
<< "operator" << op << " (" << left << " l, const " << right << "& r)" << endl
542
if (size_check == class_check) {
543
cout << " check_macro (l." << size << "() == r." << size << "(), \"incompatible spaces \" << l." << size << "()" << endl
544
<< " << \" and \" << r." << size << "() << \" in " << name << " " << op << " expression\");" << endl
546
} else if (size_check == expr_check) {
547
cout << " const " << name << "_check_" << size << "_context check_" << size << " (l." << size << "());" << endl
548
<< " proto::eval (proto::as_expr<" << name << "_domain>(r), check_" << size << ");" << endl
551
cout << " " << details << "::evaluate (l."<<begin<<"(), l."<<end<<"(), proto::as_expr<" << name << "_domain>(r), " << details << "::" << long_name << "());" << endl
552
<< " return l;" << endl
557
The first arg may be modifiable :
558
operator += (X&, const Y&) {...}
561
X = vec_basic, vec_indirect
564
void assign_op_x (string name, string size, s op, s long_name, s trait, s domain, s details, s x, s xref, const vector<s>& Class, s expr)
567
cout << "template<class T, class M>" << endl;
568
assign_op_profile (name, size, op, long_name, trait, domain, details, x + "<T,M>" + xref, "int");
569
cout << "template<class T1, class T2, class M>" << endl;
570
assign_op_profile (name, size, op, long_name, trait, domain, details, x + "<T1,M>" + xref, "T2");
572
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
573
cout << "template<class T1, class T2, class M>" << endl;
574
assign_op_profile (name, size, op, long_name, trait, domain, details, x + "<T1,M>" + xref, Class[i] + "<T2,M>", class_check);
577
cout << "template<class T, class M, class Expr>" << endl;
578
assign_op_profile (name, size, op, long_name, trait, domain, details, x + "<T,M>" + xref, expr + "<Expr>", expr_check);
580
// -----------------------------------------------------------------------------
581
void assign_op (string name, string size, s op, s long_name, s trait, s domain, s details, const vector<rhs>& Rhsclass, const vector<s>& Class, s expr)
583
assign_op_declare (op, long_name, details);
584
for (size_t k = 0, n = Rhsclass.size(); k < n; k++) {
585
assign_op_x (name, size, op, long_name, trait, domain, details, Rhsclass[k].name, Rhsclass[k].ref, Class, expr);
588
// -----------------------------------------------------------------------------
589
void all_assign_ops (string name, string size, s trait, s domain, s details, const vector<aop>& Op, const vector<rhs>& Rhsclass, const vector<s>& Class, s expr) {
590
for (size_t i = 0, nop = Op.size(); i < nop; i++) {
591
assign_op (name, size, Op[i].name, Op[i].long_name, trait, domain, details, Rhsclass, Class, expr);
594
// =====================================================================================
596
// =====================================================================================
597
// TODO: when T=complex<U> ==> conjugate and return the U type
598
void dot_profile (s left, s right, s size_name, size_check_t size_check = no_check) {
599
s begin = (size_name == "size") ? "begin" : "begin_dof"; // field: ndof, begin_dof, end_dof
600
s end = (size_name == "size") ? "end" : "end_dof";
601
cout << "dot (const " << left << "& x, const " << right << "& y)" << endl
603
<< " return dis_inner_product (x."<<begin<<"(), y."<<begin<<"(), x." << size_name << "(), x.ownership().comm());" << endl
607
void dot_profile_rscal (s left, s right, s size_name) {
608
s begin = (size_name == "size") ? "begin" : "begin_dof"; // field: ndof, begin_dof, end_dof
609
s end = (size_name == "size") ? "end" : "end_dof";
610
cout << "dot (const " << left << "& x, const " << right << "& y)" << endl
612
<< " return y*dis_accumulate (x."<<begin<<"(), x." << size_name << "(), x.ownership().comm());" << endl
616
void dot_profile_lscal (s left, s right, s size_name) {
617
s begin = (size_name == "size") ? "begin" : "begin_dof"; // field: ndof, begin_dof, end_dof
618
s end = (size_name == "size") ? "end" : "end_dof";
619
cout << "dot (const " << left << "& x, const " << right << "& y)" << endl
621
<< " return x*dis_accumulate (y."<<begin<<"(), y." << size_name << "(), y.ownership().comm());" << endl
637
void dot (string name, const vector<s>& Class, s expr, s size_name) {
639
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
640
cout << "template <class T, class M>" << endl
642
dot_profile_rscal (Class[i] + "<T,M>", "int", size_name);
643
cout << "template <class T, class M>" << endl
645
dot_profile_lscal ("int", Class[i] + "<T,M>", size_name);
646
cout << "template <class T1, class T2, class M>" << endl
647
<< "typename promote<T1,T2>::type" << endl;
648
dot_profile_rscal (Class[i] + "<T1,M>", "T2", size_name);
649
cout << "template <class T1, class T2, class M>" << endl
650
<< "typename promote<T1,T2>::type" << endl;
651
dot_profile_lscal ("T1", Class[i] + "<T2,M>", size_name);
654
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
655
for (size_t j = 0, nd = Class.size(); j < nd; j++) {
656
cout << "template <class T1, class T2, class M>" << endl
657
<< "typename promote<T1,T2>::type" << endl;
658
dot_profile (Class[i] + "<T1,M>", Class[j] + "<T2,M>", size_name, class_check);
661
cout << "template <class Expr>" << endl
662
<< "typename " << name << "_expr<Expr>::value_type" << endl;
663
dot_profile_rscal (expr + "<Expr>", "int", size_name);
664
cout << "template <class Expr>" << endl
665
<< "typename " << name << "_expr<Expr>::value_type" << endl;
666
dot_profile_lscal ("int", expr + "<Expr>", size_name);
668
cout << "template <class T, class Expr>" << endl
669
<< "typename promote<T,typename " << name << "_expr<Expr>::value_type>::type" << endl;
670
dot_profile_rscal (expr + "<Expr>", "T", size_name);
671
cout << "template <class T, class Expr>" << endl
672
<< "typename promote<T,typename " << name << "_expr<Expr>::value_type>::type" << endl;
673
dot_profile_lscal ("T", expr + "<Expr>", size_name);
676
for (size_t i = 0, nc = Class.size(); i < nc; i++) {
677
cout << "template <class T, class M, class Expr>" << endl
678
<< "typename promote<T,typename " << name << "_expr<Expr>::value_type>::type" << endl;
679
dot_profile (Class[i] + "<T,M>", expr + "<Expr>", size_name, expr_check);
680
cout << "template <class T, class M, class Expr>" << endl
681
<< "typename promote<T,typename " << name << "_expr<Expr>::value_type>::type" << endl;
682
dot_profile (expr + "<Expr>", Class[i] + "<T,M>", size_name, expr_check);
685
cout << "template <class Expr1, class Expr2>" << endl
686
<< "typename promote<" << endl
687
<< " typename " << name << "_expr<Expr1>::value_type," << endl
688
<< " typename " << name << "_expr<Expr2>::value_type" << endl
689
<< ">::type" << endl;
690
dot_profile (expr + "<Expr1>", expr + "<Expr2>", size_name, expr2_check);