Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
// The template and inlines for the -*- C++ -*- internal _Meta class.
2
 
3
// Copyright (C) 1997-1999, 2000, 2001 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 2, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// You should have received a copy of the GNU General Public License along
17
// with this library; see the file COPYING.  If not, write to the Free
18
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19
// USA.
20
 
21
// As a special exception, you may use this file as part of a free software
22
// library without restriction.  Specifically, if other files instantiate
23
// templates or use macros or inline functions from this file, or you compile
24
// this file and link it with other files to produce an executable, this
25
// file does not by itself cause the resulting executable to be covered by
26
// the GNU General Public License.  This exception does not however
27
// invalidate any other reasons why the executable file might be covered by
28
// the GNU General Public License.
29
 
30
// Written by Gabriel Dos Reis 
31
 
32
#ifndef _CPP_VALARRAY_META_H
33
#define _CPP_VALARRAY_META_H 1
34
 
35
#pragma GCC system_header
36
 
37
namespace std
38
{
39
 
40
    //
41
    // Implementing a loosened valarray return value is tricky.
42
    // First we need to meet 26.3.1/3: we should not add more than
43
    // two levels of template nesting. Therefore we resort to template
44
    // template to "flatten" loosened return value types.
45
    // At some point we use partial specialization to remove one level
46
    // template nesting due to _Expr<>
47
    //
48
 
49
 
50
    // This class is NOT defined. It doesn't need to.
51
    template class _Constant;
52
 
53
    //
54
    // Unary function application closure.
55
    //
56
    template class _UnFunBase {
57
    public:
58
        typedef typename _Dom::value_type value_type;
59
        typedef value_type _Vt;
60
 
61
        _UnFunBase (const _Dom& __e, _Vt __f(_Vt))
62
                : _M_expr(__e), _M_func(__f) {}
63
 
64
        _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); }
65
        size_t size () const { return _M_expr.size(); }
66
 
67
    private:
68
        const _Dom& _M_expr;
69
        _Vt (*_M_func)(_Vt);
70
    };
71
 
72
    template class _Meta, class _Dom>
73
        class _UnFunClos;
74
 
75
    template
76
    struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> {
77
        typedef _UnFunBase<_Dom> _Base;
78
        typedef typename _Base::value_type value_type;
79
 
80
        _UnFunClos (const _Dom& __e, value_type __f(value_type))
81
                : _Base (__e, __f) {}
82
    };
83
 
84
    template
85
    struct _UnFunClos<_ValArray,_Tp> : _UnFunBase > {
86
        typedef _UnFunBase > _Base;
87
        typedef typename _Base::value_type value_type;
88
 
89
        _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
90
                : _Base (__v, __f) {}
91
    };
92
 
93
    //
94
    // Binary function application closure.
95
    //
96
    template class _Meta1,
97
        template class Meta2,
98
        class _Dom1, class _Dom2> class _BinFunClos;
99
 
100
    template class _BinFunBase {
101
    public:
102
        typedef typename _Dom1::value_type value_type;
103
        typedef value_type _Vt;
104
 
105
        _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
106
                      _Vt __f (_Vt, _Vt))
107
                : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
108
 
109
        value_type operator[] (size_t __i) const
110
        { return _M_func (_M_expr1[__i], _M_expr2[__i]); }
111
        size_t size () const { return _M_expr1.size (); }
112
 
113
    private:
114
        const _Dom1& _M_expr1;
115
        const _Dom2& _M_expr2;
116
        _Vt (*_M_func)(_Vt, _Vt);
117
    };
118
 
119
    template class _BinFunBase1 {
120
    public:
121
        typedef typename _Dom::value_type value_type ;
122
        typedef value_type _Vt;
123
 
124
        _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
125
                : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
126
 
127
        value_type operator[] (size_t __i) const
128
        { return _M_func (_M_expr1, _M_expr2[__i]); }
129
        size_t size () const { return _M_expr2.size (); }
130
 
131
    private:
132
        const _Vt& _M_expr1;
133
        const _Dom& _M_expr2;
134
        _Vt (*_M_func)(_Vt, _Vt);
135
    };
136
 
137
    template class _BinFunBase2 {
138
    public:
139
        typedef typename _Dom::value_type value_type;
140
        typedef value_type _Vt;
141
 
142
        _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
143
                : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
144
 
145
        value_type operator[] (size_t __i) const
146
        { return _M_func (_M_expr1[__i], _M_expr2); }
147
        size_t size () const { return _M_expr1.size (); }
148
 
149
    private:
150
        const _Dom& _M_expr1;
151
        const _Vt& _M_expr2;
152
        _Vt (*_M_func)(_Vt, _Vt);
153
    };
154
 
155
    template
156
    struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> {
157
        typedef _BinFunBase<_Dom1,_Dom2> _Base;
158
        typedef typename _Base::value_type value_type;
159
        typedef value_type _Tp;
160
 
161
        _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
162
                     _Tp __f(_Tp, _Tp))
163
                : _Base (__e1, __e2, __f) {}
164
    };
165
 
166
    template
167
    struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp>
168
        : _BinFunBase, valarray<_Tp> > {
169
        typedef _BinFunBase, valarray<_Tp> > _Base;
170
        typedef _Tp value_type;
171
 
172
        _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
173
                     _Tp __f(_Tp, _Tp))
174
                : _Base (__v, __w, __f) {}
175
    };
176
 
177
    template
178
    struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>
179
        : _BinFunBase<_Dom,valarray > {
180
        typedef typename _Dom::value_type _Tp;
181
        typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
182
        typedef _Tp value_type;
183
 
184
        _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
185
                     _Tp __f(_Tp, _Tp))
186
                : _Base (__e, __v, __f) {}
187
    };
188
 
189
    template
190
    struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>
191
        : _BinFunBase,_Dom> {
192
        typedef typename _Dom::value_type _Tp;
193
        typedef _BinFunBase<_Dom,valarray<_Tp> > _Base;
194
        typedef _Tp value_type;
195
 
196
        _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
197
                     _Tp __f(_Tp, _Tp))
198
                : _Base (__v, __e, __f) {}
199
    };
200
 
201
    template
202
    struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>
203
        : _BinFunBase2<_Dom> {
204
        typedef typename _Dom::value_type _Tp;
205
        typedef _Tp value_type;
206
        typedef _BinFunBase2<_Dom> _Base;
207
 
208
        _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
209
                : _Base (__e, __t, __f) {}
210
    };
211
 
212
    template
213
    struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type>
214
        : _BinFunBase1<_Dom> {
215
        typedef typename _Dom::value_type _Tp;
216
        typedef _Tp value_type;
217
        typedef _BinFunBase1<_Dom> _Base;
218
 
219
        _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
220
                : _Base (__t, __e, __f) {}
221
    };
222
 
223
    template
224
    struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp>
225
        : _BinFunBase2 > {
226
        typedef _BinFunBase2 > _Base;
227
        typedef _Tp value_type;
228
 
229
        _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
230
                     _Tp __f(_Tp, _Tp))
231
                : _Base (__v, __t, __f) {}
232
    };
233
 
234
    template
235
    struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp>
236
        : _BinFunBase1 > {
237
        typedef _BinFunBase1 > _Base;
238
        typedef _Tp value_type;
239
 
240
        _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
241
                     _Tp __f (_Tp, _Tp))
242
                : _Base (__t, __v, __f) {}
243
    };
244
 
245
    //
246
    // Apply function taking a value/const reference closure
247
    //
248
 
249
    template class _FunBase {
250
    public:
251
        typedef typename _Dom::value_type value_type;
252
 
253
        _FunBase (const _Dom& __e, value_type __f(_Arg))
254
                : _M_expr (__e), _M_func (__f) {}
255
 
256
        value_type operator[] (size_t __i) const
257
        { return _M_func (_M_expr[__i]); }
258
        size_t size() const { return _M_expr.size ();}
259
 
260
    private:
261
        const _Dom& _M_expr;
262
        value_type (*_M_func)(_Arg);
263
    };
264
 
265
    template
266
    struct _ValFunClos<_Expr,_Dom>
267
        : _FunBase<_Dom, typename _Dom::value_type> {
268
        typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
269
        typedef typename _Base::value_type value_type;
270
        typedef value_type _Tp;
271
 
272
        _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
273
    };
274
 
275
    template
276
    struct _ValFunClos<_ValArray,_Tp>
277
        : _FunBase, _Tp> {
278
        typedef _FunBase, _Tp> _Base;
279
        typedef _Tp value_type;
280
 
281
        _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
282
                : _Base (__v, __f) {}
283
    };
284
 
285
    template
286
    struct _RefFunClos<_Expr,_Dom> :
287
        _FunBase<_Dom, const typename _Dom::value_type&> {
288
        typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
289
        typedef typename _Base::value_type value_type;
290
        typedef value_type _Tp;
291
 
292
        _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
293
                : _Base (__e, __f) {}
294
    };
295
 
296
    template
297
    struct _RefFunClos<_ValArray,_Tp>
298
        : _FunBase, const _Tp&> {
299
        typedef _FunBase, const _Tp&> _Base;
300
        typedef _Tp value_type;
301
 
302
        _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
303
                : _Base (__v, __f) {}
304
    };
305
 
306
    //
307
    // Unary expression closure.
308
    //
309
 
310
    template class _Oper, typename _Arg>
311
    class _UnBase {
312
    public:
313
        typedef _Oper _Op;
314
        typedef typename _Op::result_type value_type;
315
 
316
        _UnBase (const _Arg& __e) : _M_expr(__e) {}
317
        value_type operator[] (size_t) const;
318
        size_t size () const { return _M_expr.size (); }
319
 
320
    private:
321
        const _Arg& _M_expr;
322
    };
323
 
324
    template class _Oper, typename _Arg>
325
    inline typename _UnBase<_Oper, _Arg>::value_type
326
    _UnBase<_Oper, _Arg>::operator[] (size_t __i) const
327
    { return _Op() (_M_expr[__i]); }
328
 
329
    template class _Oper, class _Dom>
330
    struct _UnClos<_Oper, _Expr, _Dom> :  _UnBase<_Oper, _Dom> {
331
        typedef _Dom _Arg;
332
        typedef _UnBase<_Oper, _Dom> _Base;
333
        typedef typename _Base::value_type value_type;
334
 
335
        _UnClos (const _Arg& __e) : _Base(__e) {}
336
    };
337
 
338
    template class _Oper, typename _Tp>
339
    struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > {
340
        typedef valarray<_Tp> _Arg;
341
        typedef _UnBase<_Oper, valarray<_Tp> > _Base;
342
        typedef typename _Base::value_type value_type;
343
 
344
        _UnClos (const _Arg& __e) : _Base(__e) {}
345
    };
346
 
347
 
348
    //
349
    // Binary expression closure.
350
    //
351
 
352
    template class _Oper,
353
        typename _FirstArg, typename _SecondArg>
354
    class _BinBase {
355
    public:
356
        typedef _Oper _Op;
357
        typedef typename _Op::result_type value_type;
358
 
359
        _BinBase (const _FirstArg& __e1, const _SecondArg& __e2)
360
                : _M_expr1 (__e1), _M_expr2 (__e2) {}
361
        value_type operator[] (size_t) const;
362
        size_t size () const { return _M_expr1.size (); }
363
 
364
    private:
365
        const _FirstArg& _M_expr1;
366
        const _SecondArg& _M_expr2;
367
    };
368
 
369
    template class _Oper,
370
        typename _FirstArg, typename _SecondArg>
371
    inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type
372
    _BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const
373
    { return _Op() (_M_expr1[__i], _M_expr2[__i]); }
374
 
375
 
376
    template class _Oper, class _Clos>
377
    class _BinBase2 {
378
    public:
379
        typedef typename _Clos::value_type _Vt;
380
        typedef _Oper<_Vt> _Op;
381
        typedef typename _Op::result_type value_type;
382
 
383
        _BinBase2 (const _Clos& __e, const _Vt& __t)
384
                : _M_expr1 (__e), _M_expr2 (__t) {}
385
        value_type operator[] (size_t) const;
386
        size_t size () const { return _M_expr1.size (); }
387
 
388
    private:
389
        const _Clos& _M_expr1;
390
        const _Vt& _M_expr2;
391
    };
392
 
393
    template class _Oper, class _Clos>
394
    inline typename _BinBase2<_Oper,_Clos>::value_type
395
    _BinBase2<_Oper,_Clos>::operator[] (size_t __i) const
396
    { return _Op() (_M_expr1[__i], _M_expr2); }
397
 
398
 
399
    template class _Oper, class _Clos>
400
    class _BinBase1 {
401
    public:
402
        typedef typename _Clos::value_type _Vt;
403
        typedef _Oper<_Vt> _Op;
404
        typedef typename _Op::result_type value_type;
405
 
406
        _BinBase1 (const _Vt& __t, const _Clos& __e)
407
                : _M_expr1 (__t), _M_expr2 (__e) {}
408
        value_type operator[] (size_t) const;
409
        size_t size () const { return _M_expr2.size (); }
410
 
411
    private:
412
        const _Vt& _M_expr1;
413
        const _Clos& _M_expr2;
414
    };
415
 
416
    template class _Oper, class _Clos>
417
    inline typename
418
    _BinBase1<_Oper,_Clos>::value_type
419
    _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
420
    { return _Op() (_M_expr1, _M_expr2[__i]); }
421
 
422
 
423
    template class _Oper, class _Dom1, class _Dom2>
424
    struct  _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
425
        : _BinBase<_Oper,_Dom1,_Dom2> {
426
        typedef _BinBase<_Oper,_Dom1,_Dom2> _Base;
427
        typedef typename _Base::value_type value_type;
428
 
429
        _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
430
    };
431
 
432
    template class _Oper, typename _Tp>
433
    struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp>
434
        : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > {
435
        typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base;
436
        typedef _Tp value_type;
437
 
438
        _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
439
                : _Base (__v, __w) {}
440
    };
441
 
442
    template class _Oper, class _Dom>
443
    struct  _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type>
444
        : _BinBase<_Oper,_Dom,valarray > {
445
        typedef typename _Dom::value_type _Tp;
446
        typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
447
        typedef typename _Base::value_type value_type;
448
 
449
        _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
450
                : _Base (__e1, __e2) {}
451
    };
452
 
453
    template class _Oper, class _Dom>
454
    struct  _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom>
455
        : _BinBase<_Oper,valarray,_Dom> {
456
        typedef typename _Dom::value_type _Tp;
457
        typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base;
458
        typedef typename _Base::value_type value_type;
459
 
460
        _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
461
                : _Base (__e1, __e2) {}
462
    };
463
 
464
    template class _Oper, class _Dom>
465
    struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type>
466
        : _BinBase2<_Oper,_Dom> {
467
        typedef typename _Dom::value_type _Tp;
468
        typedef _BinBase2<_Oper,_Dom> _Base;
469
        typedef typename _Base::value_type value_type;
470
 
471
        _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
472
    };
473
 
474
    template class _Oper, class _Dom>
475
    struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom>
476
        : _BinBase1<_Oper,_Dom> {
477
        typedef typename _Dom::value_type _Tp;
478
        typedef _BinBase1<_Oper,_Dom> _Base;
479
        typedef typename _Base::value_type value_type;
480
 
481
        _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
482
    };
483
 
484
    template class _Oper, typename _Tp>
485
    struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp>
486
        : _BinBase2<_Oper,valarray<_Tp> > {
487
        typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
488
        typedef typename _Base::value_type value_type;
489
 
490
        _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
491
                : _Base (__v, __t) {}
492
    };
493
 
494
    template class _Oper, typename _Tp>
495
    struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp>
496
        : _BinBase1<_Oper,valarray<_Tp> > {
497
        typedef _BinBase1<_Oper,valarray<_Tp> > _Base;
498
        typedef typename _Base::value_type value_type;
499
 
500
        _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
501
                : _Base (__t, __v) {}
502
    };
503
 
504
 
505
    //
506
    // slice_array closure.
507
    //
508
    template  class _SBase {
509
    public:
510
        typedef typename _Dom::value_type value_type;
511
 
512
        _SBase (const _Dom& __e, const slice& __s)
513
                : _M_expr (__e), _M_slice (__s) {}
514
        value_type operator[] (size_t __i) const
515
        { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
516
        size_t size() const { return _M_slice.size (); }
517
 
518
    private:
519
        const _Dom& _M_expr;
520
        const slice& _M_slice;
521
    };
522
 
523
    template class _SBase<_Array<_Tp> > {
524
    public:
525
        typedef _Tp value_type;
526
 
527
        _SBase (_Array<_Tp> __a, const slice& __s)
528
                : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
529
                  _M_stride (__s.stride()) {}
530
        value_type operator[] (size_t __i) const
531
        { return _M_array._M_data[__i * _M_stride]; }
532
        size_t size() const { return _M_size; }
533
 
534
    private:
535
        const _Array<_Tp> _M_array;
536
        const size_t _M_size;
537
        const size_t _M_stride;
538
    };
539
 
540
    template struct  _SClos<_Expr,_Dom> : _SBase<_Dom> {
541
        typedef _SBase<_Dom> _Base;
542
        typedef typename _Base::value_type value_type;
543
 
544
        _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
545
    };
546
 
547
    template
548
    struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
549
        typedef  _SBase<_Array<_Tp> > _Base;
550
        typedef _Tp value_type;
551
 
552
        _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
553
    };
554
 
555
    //
556
    // gslice_array closure.
557
    //
558
    template class _GBase {
559
    public:
560
        typedef typename _Dom::value_type value_type;
561
 
562
        _GBase (const _Dom& __e, const valarray& __i)
563
                : _M_expr (__e), _M_index(__i) {}
564
        value_type operator[] (size_t __i) const
565
        { return _M_expr[_M_index[__i]]; }
566
        size_t size () const { return _M_index.size(); }
567
 
568
    private:
569
        const _Dom&	 _M_expr;
570
        const valarray& _M_index;
571
    };
572
 
573
    template class _GBase<_Array<_Tp> > {
574
    public:
575
        typedef _Tp value_type;
576
 
577
        _GBase (_Array<_Tp> __a, const valarray& __i)
578
                : _M_array (__a), _M_index(__i) {}
579
        value_type operator[] (size_t __i) const
580
        { return _M_array._M_data[_M_index[__i]]; }
581
        size_t size () const { return _M_index.size(); }
582
 
583
    private:
584
        const _Array<_Tp>     _M_array;
585
        const valarray& _M_index;
586
    };
587
 
588
    template struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
589
        typedef _GBase<_Dom> _Base;
590
        typedef typename _Base::value_type value_type;
591
 
592
        _GClos (const _Dom& __e, const valarray& __i)
593
                : _Base (__e, __i) {}
594
    };
595
 
596
    template
597
    struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > {
598
        typedef _GBase<_Array<_Tp> > _Base;
599
        typedef typename _Base::value_type value_type;
600
 
601
        _GClos (_Array<_Tp> __a, const valarray& __i)
602
                : _Base (__a, __i) {}
603
    };
604
 
605
    //
606
    // indirect_array closure
607
    //
608
 
609
    template class _IBase {
610
    public:
611
        typedef typename _Dom::value_type value_type;
612
 
613
        _IBase (const _Dom& __e, const valarray& __i)
614
                : _M_expr (__e), _M_index (__i) {}
615
        value_type operator[] (size_t __i) const
616
        { return _M_expr[_M_index[__i]]; }
617
        size_t size() const { return _M_index.size(); }
618
 
619
    private:
620
        const _Dom& 	    _M_expr;
621
        const valarray& _M_index;
622
    };
623
 
624
    template struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
625
        typedef _IBase<_Dom> _Base;
626
        typedef typename _Base::value_type value_type;
627
 
628
        _IClos (const _Dom& __e, const valarray& __i)
629
                : _Base (__e, __i) {}
630
    };
631
 
632
    template
633
    struct _IClos<_ValArray,_Tp>  : _IBase > {
634
        typedef _IBase > _Base;
635
        typedef _Tp value_type;
636
 
637
        _IClos (const valarray<_Tp>& __a, const valarray& __i)
638
                : _Base (__a, __i) {}
639
    };
640
 
641
    //
642
    // class _Expr
643
    //
644
    template class _Expr {
645
    public:
646
        typedef _Tp value_type;
647
 
648
        _Expr (const _Clos&);
649
 
650
        const _Clos& operator() () const;
651
 
652
        value_type operator[] (size_t) const;
653
        valarray operator[] (slice) const;
654
        valarray operator[] (const gslice&) const;
655
        valarray operator[] (const valarray&) const;
656
        valarray operator[] (const valarray&) const;
657
 
658
        _Expr<_UnClos<_Unary_plus,_Expr,_Clos>, value_type>
659
        operator+ () const;
660
 
661
        _Expr<_UnClos, value_type>
662
        operator- () const;
663
 
664
        _Expr<_UnClos<_Bitwise_not,_Expr,_Clos>, value_type>
665
        operator~ () const;
666
 
667
        _Expr<_UnClos, bool>
668
        operator! () const;
669
 
670
        size_t size () const;
671
        value_type sum () const;
672
 
673
        valarray shift (int) const;
674
        valarray cshift (int) const;
675
 
676
      value_type min() const;
677
      value_type max() const;
678
 
679
      valarray apply(value_type (*) (const value_type&)) const;
680
      valarray apply(value_type (*) (value_type)) const;
681
 
682
    private:
683
        const _Clos _M_closure;
684
    };
685
 
686
    template
687
    inline
688
    _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {}
689
 
690
    template
691
    inline const _Clos&
692
    _Expr<_Clos,_Tp>::operator() () const
693
    { return _M_closure; }
694
 
695
    template
696
    inline _Tp
697
    _Expr<_Clos,_Tp>::operator[] (size_t __i) const
698
    { return _M_closure[__i]; }
699
 
700
    template
701
    inline valarray<_Tp>
702
    _Expr<_Clos,_Tp>::operator[] (slice __s) const
703
    { return _M_closure[__s]; }
704
 
705
    template
706
    inline valarray<_Tp>
707
    _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const
708
    { return _M_closure[__gs]; }
709
 
710
    template
711
    inline valarray<_Tp>
712
    _Expr<_Clos,_Tp>::operator[] (const valarray& __m) const
713
    { return _M_closure[__m]; }
714
 
715
    template
716
    inline valarray<_Tp>
717
    _Expr<_Clos,_Tp>::operator[] (const valarray& __i) const
718
    { return _M_closure[__i]; }
719
 
720
    template
721
    inline size_t
722
    _Expr<_Clos,_Tp>::size () const  { return _M_closure.size (); }
723
 
724
  template
725
  inline valarray<_Tp>
726
  _Expr<_Clos, _Tp>::shift(int __n) const
727
  { return valarray<_Tp>(_M_closure).shift(__n); }
728
 
729
  template
730
  inline valarray<_Tp>
731
  _Expr<_Clos, _Tp>::cshift(int __n) const
732
  { return valarray<_Tp>(_M_closure).cshift(__n); }
733
 
734
  template
735
  inline valarray<_Tp>
736
  _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
737
  { return valarray<_Tp>(_M_closure).apply(__f); }
738
 
739
  template
740
  inline valarray<_Tp>
741
  _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
742
  { return valarray<_Tp>(_M_closure).apply(__f); }
743
 
744
    // XXX: replace this with a more robust summation algorithm.
745
    template
746
    inline _Tp
747
    _Expr<_Clos,_Tp>::sum () const
748
    {
749
        size_t __n = _M_closure.size();
750
        if (__n == 0) return _Tp();
751
        else {
752
            _Tp __s = _M_closure[--__n];
753
            while (__n != 0) __s += _M_closure[--__n];
754
            return __s;
755
        }
756
    }
757
 
758
  template
759
  inline _Tp
760
  _Expr<_Clos, _Tp>::min() const
761
  { return __valarray_min(_M_closure); }
762
 
763
  template
764
  inline _Tp
765
  _Expr<_Clos, _Tp>::max() const
766
  { return __valarray_max(_M_closure); }
767
 
768
    template
769
    inline _Expr<_UnClos, bool>
770
    _Expr<_Dom,_Tp>::operator! () const
771
    {
772
        typedef _UnClos _Closure;
773
        return _Expr<_Closure,_Tp> (_Closure(this->_M_closure));
774
    }
775
 
776
#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                         \
777
template                                      \
778
inline _Expr<_UnClos<_Name,_Expr,_Dom>,_Tp>                             \
779
_Expr<_Dom,_Tp>::operator _Op () const                                 \
780
{                                                                       \
781
    typedef _UnClos<_Name,_Expr,_Dom> _Closure;                         \
782
    return _Expr<_Closure,_Tp> (_Closure (this->_M_closure));           \
783
}
784
 
785
    _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus)
786
    _DEFINE_EXPR_UNARY_OPERATOR(-, negate)
787
    _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not)
788
 
789
#undef _DEFINE_EXPR_UNARY_OPERATOR
790
 
791
 
792
#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
793
template					\
794
inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>,                   \
795
             typename _Name::result_type>   \
796
operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v,      \
797
              const _Expr<_Dom2,typename _Dom2::value_type>& __w)       \
798
{                                                                       \
799
    typedef typename _Dom1::value_type _Arg;                            \
800
    typedef typename _Name<_Arg>::result_type _Value;                   \
801
    typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure;           \
802
    return _Expr<_Closure,_Value> (_Closure (__v (), __w ()));          \
803
}                                                                       \
804
                                                                        \
805
template                                                    \
806
inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
807
             typename _Name::result_type>    \
808
operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v,        \
809
              const typename _Dom::value_type& __t)                     \
810
{                                                                       \
811
    typedef typename _Dom::value_type _Arg;                             \
812
    typedef typename _Name<_Arg>::result_type _Value;                   \
813
    typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure;         \
814
    return _Expr<_Closure,_Value> (_Closure (__v (), __t));             \
815
}                                                                       \
816
                                                                        \
817
template                                                    \
818
inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
819
             typename _Name::result_type>    \
820
operator _Op (const typename _Dom::value_type& __t,                    \
821
               const _Expr<_Dom,typename _Dom::value_type>& __v)        \
822
{                                                                       \
823
    typedef typename _Dom::value_type _Arg;                             \
824
    typedef typename _Name<_Arg>::result_type _Value;                   \
825
    typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure;         \
826
    return _Expr<_Closure,_Value> (_Closure (__t, __v ()));             \
827
}                                                                       \
828
                                                                        \
829
template                                                    \
830
inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
831
             typename _Name::result_type>    \
832
operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e,        \
833
               const valarray& __v)          \
834
{                                                                       \
835
    typedef typename _Dom::value_type _Arg;                             \
836
    typedef typename _Name<_Arg>::result_type _Value;                   \
837
    typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure;         \
838
    return  _Expr<_Closure,_Value> (_Closure (__e (), __v));            \
839
}                                                                       \
840
                                                                        \
841
template                                                    \
842
inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
843
             typename _Name::result_type>    \
844
operator _Op (const valarray& __v,          \
845
               const _Expr<_Dom,typename _Dom::value_type>& __e)        \
846
{                                                                       \
847
    typedef typename _Dom::value_type _Tp;                              \
848
    typedef typename _Name<_Tp>::result_type _Value;                    \
849
    typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure;          \
850
    return _Expr<_Closure,_Value> (_Closure (__v, __e ()));             \
851
}
852
 
853
    _DEFINE_EXPR_BINARY_OPERATOR(+, plus)
854
    _DEFINE_EXPR_BINARY_OPERATOR(-, minus)
855
    _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies)
856
    _DEFINE_EXPR_BINARY_OPERATOR(/, divides)
857
    _DEFINE_EXPR_BINARY_OPERATOR(%, modulus)
858
    _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor)
859
    _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and)
860
    _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or)
861
    _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left)
862
    _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right)
863
 
864
#undef _DEFINE_EXPR_BINARY_OPERATOR
865
 
866
#define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name)                    \
867
template					\
868
inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool>             \
869
operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v,      \
870
              const _Expr<_Dom2,typename _Dom2::value_type>& __w)       \
871
{                                                                       \
872
    typedef typename _Dom1::value_type _Arg;                            \
873
    typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure;           \
874
    return _Expr<_Closure,bool> (_Closure (__v (), __w ()));            \
875
}                                                                       \
876
                                                                        \
877
template                                                    \
878
inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
879
             bool>                                                      \
880
operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v,        \
881
              const typename _Dom::value_type& __t)                     \
882
{                                                                       \
883
    typedef typename _Dom::value_type _Arg;                             \
884
    typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure;         \
885
    return _Expr<_Closure,bool> (_Closure (__v (), __t));               \
886
}                                                                       \
887
                                                                        \
888
template                                                    \
889
inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
890
             bool>                                                      \
891
operator _Op (const typename _Dom::value_type& __t,                    \
892
               const _Expr<_Dom,typename _Dom::value_type>& __v)        \
893
{                                                                       \
894
    typedef typename _Dom::value_type _Arg;                             \
895
    typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure;         \
896
    return _Expr<_Closure,bool> (_Closure (__t, __v ()));               \
897
}                                                                       \
898
                                                                        \
899
template                                                    \
900
inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
901
             bool>                                                      \
902
operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e,        \
903
               const valarray& __v)          \
904
{                                                                       \
905
    typedef typename _Dom::value_type _Tp;                              \
906
    typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure;          \
907
    return  _Expr<_Closure,bool> (_Closure (__e (), __v));              \
908
}                                                                       \
909
                                                                        \
910
template                                                    \
911
inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
912
             bool>                                                      \
913
operator _Op (const valarray& __v,          \
914
               const _Expr<_Dom,typename _Dom::value_type>& __e)        \
915
{                                                                       \
916
    typedef typename _Dom::value_type _Tp;                              \
917
    typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure;          \
918
    return _Expr<_Closure,bool> (_Closure (__v, __e ()));               \
919
}
920
 
921
    _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and)
922
    _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or)
923
    _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to)
924
    _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to)
925
    _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less)
926
    _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater)
927
    _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal)
928
    _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal)
929
 
930
#undef _DEFINE_EXPR_RELATIONAL_OPERATOR
931
 
932
 
933
 
934
#define _DEFINE_EXPR_UNARY_FUNCTION(_Name)                              \
935
template                                                    \
936
inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type>          \
937
_Name(const _Expr<_Dom,typename _Dom::value_type>& __e)                 \
938
{                                                                       \
939
    typedef typename _Dom::value_type _Tp;                              \
940
    typedef _UnFunClos<_Expr,_Dom> _Closure;                            \
941
    return _Expr<_Closure,_Tp>(_Closure(__e(), (_Tp(*)(_Tp))(&_Name))); \
942
}                                                                       \
943
                                                                        \
944
template                                                  \
945
inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp>                             \
946
_Name(const valarray<_Tp>& __v)                                         \
947
{                                                                       \
948
    typedef _UnFunClos<_ValArray,_Tp> _Closure;                         \
949
    return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \
950
}
951
 
952
 
953
    _DEFINE_EXPR_UNARY_FUNCTION(abs)
954
    _DEFINE_EXPR_UNARY_FUNCTION(cos)
955
    _DEFINE_EXPR_UNARY_FUNCTION(acos)
956
    _DEFINE_EXPR_UNARY_FUNCTION(cosh)
957
    _DEFINE_EXPR_UNARY_FUNCTION(sin)
958
    _DEFINE_EXPR_UNARY_FUNCTION(asin)
959
    _DEFINE_EXPR_UNARY_FUNCTION(sinh)
960
    _DEFINE_EXPR_UNARY_FUNCTION(tan)
961
    _DEFINE_EXPR_UNARY_FUNCTION(tanh)
962
    _DEFINE_EXPR_UNARY_FUNCTION(atan)
963
    _DEFINE_EXPR_UNARY_FUNCTION(exp)
964
    _DEFINE_EXPR_UNARY_FUNCTION(log)
965
    _DEFINE_EXPR_UNARY_FUNCTION(log10)
966
    _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
967
 
968
#undef _DEFINE_EXPR_UNARY_FUNCTION
969
 
970
 
971
#define _DEFINE_EXPR_BINARY_FUNCTION(_Name)                             \
972
template                                      \
973
inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
974
_Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1,             \
975
       const _Expr<_Dom2,typename _Dom2::value_type>& __e2)             \
976
{                                                                       \
977
    typedef typename _Dom1::value_type _Tp;                             \
978
    typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure;              \
979
    return _Expr<_Closure,_Tp>                                          \
980
        (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name)));      \
981
}                                                                       \
982
                                                                        \
983
template                                                    \
984
inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
985
             typename _Dom::value_type>                                 \
986
_Name (const _Expr<_Dom,typename _Dom::value_type>& __e,                \
987
       const valarray& __v)                  \
988
{                                                                       \
989
    typedef typename _Dom::value_type _Tp;                              \
990
    typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure;             \
991
    return _Expr<_Closure,_Tp>                                          \
992
        (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name)));           \
993
}                                                                       \
994
                                                                        \
995
template                                                    \
996
inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
997
             typename _Dom::value_type>                                 \
998
_Name (const valarray& __v,                    \
999
       const _Expr<_Dom,typename _Dom::value_type>& __e)                \
1000
{                                                                       \
1001
    typedef typename _Dom::value_type _Tp;                              \
1002
    typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure;             \
1003
    return _Expr<_Closure,_Tp>                                          \
1004
        (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name)));           \
1005
}                                                                       \
1006
                                                                        \
1007
template                                                    \
1008
inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1009
             typename _Dom::value_type>                                 \
1010
_Name (const _Expr<_Dom, typename _Dom::value_type>& __e,               \
1011
       const typename _Dom::value_type& __t)                            \
1012
{                                                                       \
1013
    typedef typename _Dom::value_type _Tp;                              \
1014
    typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure;             \
1015
    return _Expr<_Closure,_Tp>                                          \
1016
        (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name)));           \
1017
}                                                                       \
1018
                                                                        \
1019
template                                                    \
1020
inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1021
             typename _Dom::value_type>                                 \
1022
_Name (const typename _Dom::value_type& __t,                            \
1023
       const _Expr<_Dom,typename _Dom::value_type>& __e)                \
1024
{                                                                       \
1025
    typedef typename _Dom::value_type _Tp;                              \
1026
    typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure;             \
1027
    return _Expr<_Closure,_Tp>                                          \
1028
        (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name)));           \
1029
}                                                                       \
1030
                                                                        \
1031
template                                                  \
1032
inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp>             \
1033
_Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w)              \
1034
{                                                                       \
1035
    typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure;          \
1036
    return _Expr<_Closure,_Tp>                                          \
1037
        (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
1038
}                                                                       \
1039
                                                                        \
1040
template                                                  \
1041
inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp>              \
1042
_Name (const valarray<_Tp>& __v, const _Tp& __t)                        \
1043
{                                                                       \
1044
    typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure;          \
1045
    return _Expr<_Closure,_Tp>                                          \
1046
        (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
1047
}                                                                       \
1048
                                                                        \
1049
template                                                  \
1050
inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp>              \
1051
_Name (const _Tp& __t, const valarray<_Tp>& __v)                        \
1052
{                                                                       \
1053
    typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure;          \
1054
    return _Expr<_Closure,_Tp>                                          \
1055
        (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name)));               \
1056
}
1057
 
1058
_DEFINE_EXPR_BINARY_FUNCTION(atan2)
1059
_DEFINE_EXPR_BINARY_FUNCTION(pow)
1060
 
1061
#undef _DEFINE_EXPR_BINARY_FUNCTION
1062
 
1063
} // std::
1064
 
1065
 
1066
#endif /* _CPP_VALARRAY_META_H */
1067
 
1068
// Local Variables:
1069
// mode:c++
1070
// End: