~ubuntu-branches/ubuntu/raring/rheolef/raring-proposed

« back to all changes in this revision

Viewing changes to skit/plib2/expr_ops_make.icc

  • Committer: Package Import Robot
  • Author(s): Pierre Saramito
  • Date: 2012-04-06 09:12:21 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120406091221-m58me99p1nxqui49
Tags: 6.0-1
* New upstream release 6.0 (major changes):
  - massively distributed and parallel support
  - full FEM characteristic method (Lagrange-Gakerkin method) support
  - enhanced users documentation 
  - source code supports g++-4.7 (closes: #667356)
* debian/control: dependencies for MPI distributed solvers added
* debian/rules: build commands simplified
* debian/librheolef-dev.install: man1/* to man9/* added
* debian/changelog: package description rewritted (closes: #661689)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <iostream>
 
2
#include <vector>
 
3
#include <string>
 
4
using namespace std;
 
5
typedef string s;
 
6
struct rhs { // + - *...
 
7
  s name, ref;
 
8
  rhs(s n="", s r="") : name(n), ref(r) {} 
 
9
};
 
10
struct op { // + - *...
 
11
  s name, tag;
 
12
  op(s n="", s t="") : name(n), tag(t) {} 
 
13
};
 
14
struct aop { // assign_op: += -= ...
 
15
  s name, long_name;
 
16
  aop(s n="", s ln="") : name(n), long_name(ln) {} 
 
17
};
 
18
enum size_check_t { no_check, class_check, expr_check, expr2_check };
 
19
struct func { // abs sqrt...
 
20
  s f, std_f;
 
21
  func (s f1) : f(f1), std_f(f1) {}
 
22
  func (s f1, s std_f1) : f(f1), std_f(std_f1) {}
 
23
};
 
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
 
29
       << "// " << endl
 
30
       << "//     ./" << name << "_expr_ops_make > " << name << "_expr_ops.h" << endl
 
31
       << "// " << endl
 
32
       << "// ==========================================================================" << endl
 
33
       << "//" << endl
 
34
       << "// This file is part of Rheolef." << endl
 
35
       << "//" << endl
 
36
       << "// Copyright (C) 2000-2009 Pierre Saramito " << endl
 
37
       << "//" << 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
 
42
       << "// " << 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
 
47
       << "//" << 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
 
51
       << "// " << endl
 
52
       << "// ==========================================================================" << endl
 
53
       << "// " << endl
 
54
       << "// " << name << ": template expressions" << endl
 
55
       << "//" << endl
 
56
       << "// author: Pierre.Saramito@imag.fr" << endl
 
57
       << "//" << endl
 
58
       << "// date: 20 march 2011" << endl
 
59
       << "//" << endl
 
60
       << "#include \"rheolef/promote.h\"" << endl
 
61
       << "#include \"rheolef/" << name << "_expr.h\"" << endl
 
62
       << "namespace rheolef {" << endl
 
63
       ;
 
64
}
 
65
void footer(string NAME, string name) {
 
66
  cout << "} // namespace rheolef" << endl
 
67
       << "#endif // _RHEOLEF_" << NAME << "_EXPR_OPS_H" << endl
 
68
      ;
 
69
}
 
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
 
75
       << "typename" << 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
 
84
       << ">::type" << endl
 
85
       << "operator" << op << " (const " << left << "& l, const " << right << "& r)" << endl
 
86
       << "{" << endl
 
87
       << "  return boost::proto::functional::make_expr<" << tag << ", " << domain << ">" << endl
 
88
       << "    ::impl<const " << left << "&, const " << right << "&>() (l, r);" << endl
 
89
       << "}" << 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
 
100
       << "      >" << endl
 
101
       << "    >" << endl
 
102
       << "  >," << 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
 
108
       << "{" << endl
 
109
       << "  return boost::proto::detail::make_expr_<" << tag << ", " << domain << ", "
 
110
               << left << " const &, " << right << " const &>()(left, right);" << endl
 
111
       << "}" << endl
 
112
       << "#endif // BOOST_VERSION" << endl
 
113
     ;
 
114
}
 
115
void binop (s op, s tag, s trait, s domain, const vector<s>& Class, s expr) {
 
116
  // xY
 
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>");
 
122
  }
 
123
  // Xy
 
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");
 
129
  }
 
130
  // XY
 
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>");
 
135
  }}
 
136
  // xE, Ex
 
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");
 
145
  // XE, EX
 
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>");
 
151
  }
 
152
  // EE
 
153
  cout << "template<class Expr1, class Expr2>" << endl;
 
154
  binop_profile(op, tag, trait, domain, expr + "<Expr1>", expr + "<Expr2>");
 
155
}
 
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);
 
160
  }
 
161
}
 
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
 
175
       << "{" << endl
 
176
       << "  return boost::proto::functional::make_expr<" << tag << ", " << domain << ">" << endl
 
177
       << "   ::impl<const " << x << "&>()(arg);" << endl
 
178
       << "}" << 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
 
186
       << "  >," << endl
 
187
       << "  " << tag << "," << endl
 
188
       << "  " << x << " const &" << endl
 
189
       << ">::type const" << endl
 
190
       << "operator" << op << " (const " << x << "& arg)" << endl
 
191
       << "{" << endl
 
192
       << "  return boost::proto::detail::make_expr_<" << tag << ", " << domain << ", "
 
193
               << x << " const &>()(arg);" << endl
 
194
       << "}" << endl
 
195
       << "#endif // BOOST_VERSION" << endl
 
196
    ;
 
197
}
 
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>");
 
203
  }
 
204
  cout << "template<class Expr>" << endl;
 
205
  unop_profile (op, tag, trait, domain, expr + "<Expr>");
 
206
}
 
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);
 
211
  }
 
212
}
 
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
 
221
       << endl
 
222
       << "    template<class This, class T>" << endl
 
223
       << "    struct result<This(T)> : boost::remove_const<typename boost::remove_reference<T>::type> {};" << endl
 
224
       << endl
 
225
       << "    template<class T>" << endl
 
226
       << "    T operator() (const T& x) const { return " << std_f << "(x); }" << endl
 
227
       << "  };" << endl
 
228
       << "} // namespace " << details << endl
 
229
    ;       
 
230
}
 
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
 
239
       << "{" << endl
 
240
       << "    return boost::proto::make_expr<" << tag << ", " << domain << "> ("
 
241
                << details << "::" << f << "_(), boost::ref(x));" << endl
 
242
       << "}" << endl
 
243
    ;
 
244
}
 
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>");
 
250
  }
 
251
  cout << "template<class Expr>" << endl;
 
252
  ufunc_profile (f, tag, domain, details, expr + "<Expr>");
 
253
}
 
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);
 
257
  }
 
258
}
 
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
 
267
       << 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
 
274
       << 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
 
280
       << "  };" << endl
 
281
       << "} // namespace " << details << endl
 
282
    ;       
 
283
}
 
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
 
293
       << "{" << endl
 
294
       << "    return boost::proto::make_expr<" << tag << ", " << domain << "> ("
 
295
                << details << "::" << f << "_(), boost::ref(x), boost::ref(y));" << endl
 
296
       << "}" << endl
 
297
    ;
 
298
}
 
299
/*
 
300
  => binary profile :
 
301
 
 
302
                iF iG iH   iE
 
303
                tF tG tH   tE
 
304
 
 
305
        Fi Ft   FF FG FH   FE
 
306
        Gi Gt   GF GG GH   GE
 
307
        Hi Ht   HF HG HH   HE
 
308
 
 
309
        Ei Et   EF EG EH   EE
 
310
*/
 
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);
 
313
  // xY
 
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>");
 
319
  }
 
320
  // Xy
 
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");
 
326
  }
 
327
  // XY
 
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>");
 
332
  }}
 
333
  // xE, Ey
 
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");
 
342
  // XE, EY
 
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>");
 
348
  }
 
349
  // EE
 
350
  cout << "template<class Expr1, class Expr2>" << endl;
 
351
  bifunc_profile (f, tag, domain, details, expr + "<Expr1>", expr + "<Expr2>");
 
352
}
 
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);
 
356
  }
 
357
}
 
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
 
367
       << endl
 
368
       << "    template<class Sig> struct result;" << endl
 
369
       << endl
 
370
       << "    template<class This, class T>" << endl
 
371
       << "    struct result<This(T)> : boost::remove_const<typename boost::remove_reference<T>::type> {};" << endl
 
372
       << endl
 
373
       << "    template<class T>" << endl
 
374
       << "    T operator() (const T& x) const { return _f (x); }" << endl
 
375
       << "  };" << 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
 
380
       << endl
 
381
       << "    template<class Sig> struct result;" << endl
 
382
       << endl
 
383
       << "    template<class This, class U>" << endl
 
384
       << "    struct result<This(U)> : boost::remove_const<typename boost::remove_reference<Result>::type> {};" << endl
 
385
       << endl
 
386
       << "    Result operator() (Arg x) const { return _f (x); }" << endl
 
387
       << "  };" << endl
 
388
       << "} // namespace " << details << endl
 
389
     ;
 
390
}
 
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
 
399
       << "{" << endl
 
400
       << "    return boost::proto::make_expr<" << tag << ", " << domain << ">" << endl
 
401
       << "     (" << details << "::" << f << "_<Function>(f), boost::ref(x));" << endl
 
402
       << "}" << endl
 
403
    ;
 
404
}
 
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>");
 
410
  }
 
411
  cout << "template<class Function, class Expr>" << endl;
 
412
  ucompose_profile (f, tag, domain, details, expr + "<Expr>");
 
413
}
 
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
 
423
       << endl
 
424
       << "    template<class Sig> struct result;" << endl
 
425
       << 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
 
432
       << 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
 
438
       << "  };" << 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
 
443
       << endl
 
444
       << "    template<class Sig> struct result;" << endl
 
445
       << 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
 
452
       << endl
 
453
       << "    Result operator() (Arg1 x, Arg2 y) const { return _f (x,y); }" << endl
 
454
       << "  };" << endl
 
455
       << "} // namespace " << details << endl
 
456
     ;
 
457
}
 
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
 
467
       << "{" << endl
 
468
       << "    return boost::proto::make_expr<" << tag << ", " << domain << ">" << endl
 
469
       << "     (" << details << "::" << f << "2_<Function>(f), boost::ref(x), boost::ref(y));" << endl
 
470
       << "}" << endl
 
471
    ;
 
472
}
 
473
/*
 
474
  => binary profile :
 
475
 
 
476
                iF iG iH   iE
 
477
                tF tG tH   tE
 
478
 
 
479
        Fi Ft   FF FG FH   FE
 
480
        Gi Gt   GF GG GH   GE
 
481
        Hi Ht   HF HG HH   HE
 
482
 
 
483
        Ei Et   EF EG EH   EE
 
484
*/
 
485
void bicompose (s tag, s domain, s details, s f, const vector<s>& Class, s expr) {
 
486
  bicompose_declare (f, details);
 
487
  // xY, Xy
 
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");
 
497
  }
 
498
  // XY
 
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>");
 
503
  }}
 
504
  // xE, Ey
 
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");
 
513
  // XE, EY
 
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>");
 
519
  }
 
520
  // EE
 
521
  cout << "template<class Function, class Expr1, class Expr2>" << endl;
 
522
  bicompose_profile (f, tag, domain, details, expr + "<Expr1>", expr + "<Expr2>");
 
523
}
 
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
 
532
       << "    };" << endl
 
533
       << "} // namespace " << details << endl
 
534
    ;
 
535
}
 
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"; 
 
539
  cout << left << endl
 
540
       << "operator" << op << " (" << left << " l, const " << right << "& r)" << endl
 
541
       << "{" << 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
 
545
       ;
 
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
 
549
      ;
 
550
  }
 
551
  cout << "  " << details << "::evaluate (l."<<begin<<"(), l."<<end<<"(), proto::as_expr<" << name << "_domain>(r), " << details << "::" << long_name << "());" << endl
 
552
       << "  return l;" << endl
 
553
       << "}" << endl
 
554
    ;
 
555
}
 
556
/*
 
557
  The first arg may be modifiable :
 
558
  operator += (X&, const Y&) {...}
 
559
 
 
560
  => binary profile :
 
561
        X = vec_basic, vec_indirect
 
562
        Y = any itFGHE
 
563
*/
 
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)
 
565
{
 
566
  // Xi, Xt
 
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");
 
571
  // XY
 
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);
 
575
  }
 
576
  // XE
 
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);
 
579
}
 
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)
 
582
{
 
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);
 
586
  }
 
587
}
 
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);
 
592
  }
 
593
}
 
594
// =====================================================================================
 
595
// part 8 : dot(.,.)
 
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
 
602
       << "{" << endl
 
603
       << "  return dis_inner_product (x."<<begin<<"(), y."<<begin<<"(), x." << size_name << "(), x.ownership().comm());" << endl
 
604
       << "}" << endl
 
605
    ;
 
606
}
 
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
 
611
       << "{" << endl
 
612
       << "  return y*dis_accumulate (x."<<begin<<"(), x." << size_name << "(), x.ownership().comm());" << endl
 
613
       << "}" << endl
 
614
    ;
 
615
}
 
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
 
620
       << "{" << endl
 
621
       << "  return x*dis_accumulate (y."<<begin<<"(), y." << size_name << "(), y.ownership().comm());" << endl
 
622
       << "}" << endl
 
623
    ;
 
624
}
 
625
/*
 
626
  => binary profile :
 
627
 
 
628
                iF iG iH   iE
 
629
                tF tG tH   tE
 
630
 
 
631
        Fi Ft   FF FG FH   FE
 
632
        Gi Gt   GF GG GH   GE
 
633
        Hi Ht   HF HG HH   HE
 
634
 
 
635
        Ei Et   EF EG EH   EE
 
636
*/
 
637
void dot (string name, const vector<s>& Class, s expr, s size_name) {
 
638
  // iX, Xi
 
639
  for (size_t i = 0, nc = Class.size();  i < nc; i++) {
 
640
    cout << "template <class T, class M>" << endl
 
641
         << "T" << endl;
 
642
    dot_profile_rscal (Class[i] + "<T,M>", "int", size_name);
 
643
    cout << "template <class T, class M>" << endl
 
644
         << "T" << 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);
 
652
  }
 
653
  // XY
 
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);
 
659
  }}
 
660
  // iE, Ei
 
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);
 
667
  // tE, Et
 
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);
 
674
 
 
675
  // XE, EY
 
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);
 
683
  }
 
684
  // EE
 
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);
 
691
}