1 // The template and inlines for the -*- C++ -*- internal _Meta class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
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)
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.
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,
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.
30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
32 /** @file valarray_meta.h
33 * This is an internal header file, included by other library headers.
34 * You should not attempt to use it directly.
37 #ifndef _VALARRAY_AFTER_H
38 #define _VALARRAY_AFTER_H 1
40 #pragma GCC system_header
46 // gslice_array closure.
48 template<class _Dom
> class _GBase
{
50 typedef typename
_Dom::value_type value_type
;
52 _GBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
53 : _M_expr (__e
), _M_index(__i
) {}
54 value_type
operator[] (size_t __i
) const
55 { return _M_expr
[_M_index
[__i
]]; }
56 size_t size () const { return _M_index
.size(); }
60 const valarray
<size_t>& _M_index
;
63 template<typename _Tp
> class _GBase
<_Array
<_Tp
> > {
65 typedef _Tp value_type
;
67 _GBase (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
68 : _M_array (__a
), _M_index(__i
) {}
69 value_type
operator[] (size_t __i
) const
70 { return _M_array
._M_data
[_M_index
[__i
]]; }
71 size_t size () const { return _M_index
.size(); }
74 const _Array
<_Tp
> _M_array
;
75 const valarray
<size_t>& _M_index
;
78 template<class _Dom
> struct _GClos
<_Expr
,_Dom
> : _GBase
<_Dom
> {
79 typedef _GBase
<_Dom
> _Base
;
80 typedef typename
_Base::value_type value_type
;
82 _GClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
86 template<typename _Tp
>
87 struct _GClos
<_ValArray
,_Tp
> : _GBase
<_Array
<_Tp
> > {
88 typedef _GBase
<_Array
<_Tp
> > _Base
;
89 typedef typename
_Base::value_type value_type
;
91 _GClos (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
96 // indirect_array closure
98 template<class _Dom
> class _IBase
{
100 typedef typename
_Dom::value_type value_type
;
102 _IBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
103 : _M_expr (__e
), _M_index (__i
) {}
104 value_type
operator[] (size_t __i
) const
105 { return _M_expr
[_M_index
[__i
]]; }
106 size_t size() const { return _M_index
.size(); }
110 const valarray
<size_t>& _M_index
;
113 template<class _Dom
> struct _IClos
<_Expr
,_Dom
> : _IBase
<_Dom
> {
114 typedef _IBase
<_Dom
> _Base
;
115 typedef typename
_Base::value_type value_type
;
117 _IClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
118 : _Base (__e
, __i
) {}
121 template<typename _Tp
>
122 struct _IClos
<_ValArray
,_Tp
> : _IBase
<valarray
<_Tp
> > {
123 typedef _IBase
<valarray
<_Tp
> > _Base
;
124 typedef _Tp value_type
;
126 _IClos (const valarray
<_Tp
>& __a
, const valarray
<size_t>& __i
)
127 : _Base (__a
, __i
) {}
133 template<class _Clos
, typename _Tp
>
137 typedef _Tp value_type
;
141 const _Clos
& operator()() const;
143 value_type
operator[](size_t) const;
144 valarray
<value_type
> operator[](slice
) const;
145 valarray
<value_type
> operator[](const gslice
&) const;
146 valarray
<value_type
> operator[](const valarray
<bool>&) const;
147 valarray
<value_type
> operator[](const valarray
<size_t>&) const;
149 _Expr
<_UnClos
<__unary_plus
,std::_Expr
,_Clos
>, value_type
>
152 _Expr
<_UnClos
<__negate
,std::_Expr
,_Clos
>, value_type
>
155 _Expr
<_UnClos
<__bitwise_not
,std::_Expr
,_Clos
>, value_type
>
158 _Expr
<_UnClos
<__logical_not
,std::_Expr
,_Clos
>, bool>
162 value_type
sum() const;
164 valarray
<value_type
> shift(int) const;
165 valarray
<value_type
> cshift(int) const;
167 value_type
min() const;
168 value_type
max() const;
170 valarray
<value_type
> apply(value_type (*)(const value_type
&)) const;
171 valarray
<value_type
> apply(value_type (*)(value_type
)) const;
174 const _Clos _M_closure
;
177 template<class _Clos
, typename _Tp
>
179 _Expr
<_Clos
,_Tp
>::_Expr(const _Clos
& __c
) : _M_closure(__c
) {}
181 template<class _Clos
, typename _Tp
>
183 _Expr
<_Clos
,_Tp
>::operator()() const
184 { return _M_closure
; }
186 template<class _Clos
, typename _Tp
>
188 _Expr
<_Clos
,_Tp
>::operator[](size_t __i
) const
189 { return _M_closure
[__i
]; }
191 template<class _Clos
, typename _Tp
>
193 _Expr
<_Clos
,_Tp
>::operator[](slice __s
) const
194 { return _M_closure
[__s
]; }
196 template<class _Clos
, typename _Tp
>
198 _Expr
<_Clos
,_Tp
>::operator[](const gslice
& __gs
) const
199 { return _M_closure
[__gs
]; }
201 template<class _Clos
, typename _Tp
>
203 _Expr
<_Clos
,_Tp
>::operator[](const valarray
<bool>& __m
) const
204 { return _M_closure
[__m
]; }
206 template<class _Clos
, typename _Tp
>
208 _Expr
<_Clos
,_Tp
>::operator[](const valarray
<size_t>& __i
) const
209 { return _M_closure
[__i
]; }
211 template<class _Clos
, typename _Tp
>
213 _Expr
<_Clos
,_Tp
>::size() const { return _M_closure
.size (); }
215 template<class _Clos
, typename _Tp
>
217 _Expr
<_Clos
, _Tp
>::shift(int __n
) const
218 { return valarray
<_Tp
>(_M_closure
).shift(__n
); }
220 template<class _Clos
, typename _Tp
>
222 _Expr
<_Clos
, _Tp
>::cshift(int __n
) const
223 { return valarray
<_Tp
>(_M_closure
).cshift(__n
); }
225 template<class _Clos
, typename _Tp
>
227 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(const _Tp
&)) const
228 { return valarray
<_Tp
>(_M_closure
).apply(__f
); }
230 template<class _Clos
, typename _Tp
>
232 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(_Tp
)) const
233 { return valarray
<_Tp
>(_M_closure
).apply(__f
); }
235 // XXX: replace this with a more robust summation algorithm.
236 template<class _Clos
, typename _Tp
>
238 _Expr
<_Clos
,_Tp
>::sum() const
240 size_t __n
= _M_closure
.size();
245 _Tp __s
= _M_closure
[--__n
];
247 __s
+= _M_closure
[--__n
];
252 template<class _Clos
, typename _Tp
>
254 _Expr
<_Clos
, _Tp
>::min() const
255 { return __valarray_min(_M_closure
); }
257 template<class _Clos
, typename _Tp
>
259 _Expr
<_Clos
, _Tp
>::max() const
260 { return __valarray_max(_M_closure
); }
262 template<class _Dom
, typename _Tp
>
263 inline _Expr
<_UnClos
<__logical_not
,_Expr
,_Dom
>, bool>
264 _Expr
<_Dom
,_Tp
>::operator!() const
266 typedef _UnClos
<__logical_not
,std::_Expr
,_Dom
> _Closure
;
267 return _Expr
<_Closure
,_Tp
>(_Closure(this->_M_closure
));
270 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
271 template<class _Dom, typename _Tp> \
272 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \
273 _Expr<_Dom,_Tp>::operator _Op() const \
275 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
276 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \
279 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus
)
280 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate
)
281 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not
)
283 #undef _DEFINE_EXPR_UNARY_OPERATOR
286 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
287 template<class _Dom1, class _Dom2> \
288 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \
289 typename __fun<_Name, typename _Dom1::value_type>::result_type>\
290 operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
291 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
293 typedef typename _Dom1::value_type _Arg; \
294 typedef typename __fun<_Name, _Arg>::result_type _Value; \
295 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
296 return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \
299 template<class _Dom> \
300 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\
301 typename __fun<_Name, typename _Dom::value_type>::result_type>\
302 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \
303 const typename _Dom::value_type& __t) \
305 typedef typename _Dom::value_type _Arg; \
306 typedef typename __fun<_Name, _Arg>::result_type _Value; \
307 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
308 return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \
311 template<class _Dom> \
312 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\
313 typename __fun<_Name, typename _Dom::value_type>::result_type>\
314 operator _Op(const typename _Dom::value_type& __t, \
315 const _Expr<_Dom,typename _Dom::value_type>& __v) \
317 typedef typename _Dom::value_type _Arg; \
318 typedef typename __fun<_Name, _Arg>::result_type _Value; \
319 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
320 return _Expr<_Closure,_Value>(_Closure(__t, __v())); \
323 template<class _Dom> \
324 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\
325 typename __fun<_Name, typename _Dom::value_type>::result_type>\
326 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
327 const valarray<typename _Dom::value_type>& __v) \
329 typedef typename _Dom::value_type _Arg; \
330 typedef typename __fun<_Name, _Arg>::result_type _Value; \
331 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \
332 return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \
335 template<class _Dom> \
336 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\
337 typename __fun<_Name, typename _Dom::value_type>::result_type>\
338 operator _Op(const valarray<typename _Dom::value_type>& __v, \
339 const _Expr<_Dom,typename _Dom::value_type>& __e) \
341 typedef typename _Dom::value_type _Tp; \
342 typedef typename __fun<_Name, _Tp>::result_type _Value; \
343 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
344 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \
347 _DEFINE_EXPR_BINARY_OPERATOR(+, __plus
)
348 _DEFINE_EXPR_BINARY_OPERATOR(-, __minus
)
349 _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies
)
350 _DEFINE_EXPR_BINARY_OPERATOR(/, __divides
)
351 _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus
)
352 _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor
)
353 _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and
)
354 _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or
)
355 _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left
)
356 _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right
)
357 _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and
)
358 _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or
)
359 _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to
)
360 _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to
)
361 _DEFINE_EXPR_BINARY_OPERATOR(<, __less
)
362 _DEFINE_EXPR_BINARY_OPERATOR(>, __greater
)
363 _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal
)
364 _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal
)
366 #undef _DEFINE_EXPR_BINARY_OPERATOR
368 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \
369 template<class _Dom> \
370 inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\
371 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \
373 typedef typename _Dom::value_type _Tp; \
374 typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \
375 return _Expr<_Closure,_Tp>(_Closure(__e())); \
378 template<typename _Tp> \
379 inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \
380 _Name(const valarray<_Tp>& __v) \
382 typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \
383 return _Expr<_Closure,_Tp>(_Closure(__v)); \
386 _DEFINE_EXPR_UNARY_FUNCTION(abs
)
387 _DEFINE_EXPR_UNARY_FUNCTION(cos
)
388 _DEFINE_EXPR_UNARY_FUNCTION(acos
)
389 _DEFINE_EXPR_UNARY_FUNCTION(cosh
)
390 _DEFINE_EXPR_UNARY_FUNCTION(sin
)
391 _DEFINE_EXPR_UNARY_FUNCTION(asin
)
392 _DEFINE_EXPR_UNARY_FUNCTION(sinh
)
393 _DEFINE_EXPR_UNARY_FUNCTION(tan
)
394 _DEFINE_EXPR_UNARY_FUNCTION(tanh
)
395 _DEFINE_EXPR_UNARY_FUNCTION(atan
)
396 _DEFINE_EXPR_UNARY_FUNCTION(exp
)
397 _DEFINE_EXPR_UNARY_FUNCTION(log
)
398 _DEFINE_EXPR_UNARY_FUNCTION(log10
)
399 _DEFINE_EXPR_UNARY_FUNCTION(sqrt
)
401 #undef _DEFINE_EXPR_UNARY_FUNCTION
403 #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \
404 template<class _Dom1, class _Dom2> \
405 inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \
406 typename _Dom1::value_type> \
407 _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \
408 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \
410 typedef typename _Dom1::value_type _Tp; \
411 typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
412 return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \
415 template<class _Dom> \
416 inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \
417 typename _Dom::value_type>, \
418 typename _Dom::value_type> \
419 _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \
420 const valarray<typename _Dom::value_type>& __v) \
422 typedef typename _Dom::value_type _Tp; \
423 typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\
424 return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \
427 template<class _Dom> \
428 inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \
429 typename _Dom::value_type,_Dom>, \
430 typename _Dom::value_type> \
431 _Fun(const valarray<typename _Dom::valarray>& __v, \
432 const _Expr<_Dom,typename _Dom::value_type>& __e) \
434 typedef typename _Dom::value_type _Tp; \
435 typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \
436 return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \
439 template<class _Dom> \
440 inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \
441 typename _Dom::value_type>, \
442 typename _Dom::value_type> \
443 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
444 const typename _Dom::value_type& __t) \
446 typedef typename _Dom::value_type _Tp; \
447 typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \
448 return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \
451 template<class _Dom> \
452 inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \
453 typename _Dom::value_type,_Dom>, \
454 typename _Dom::value_type> \
455 _Fun(const typename _Dom::value_type& __t, \
456 const _Expr<_Dom,typename _Dom::value_type>& __e) \
458 typedef typename _Dom::value_type _Tp; \
459 typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \
460 return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \
463 template<typename _Tp> \
464 inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
465 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
467 typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \
468 return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \
471 template<typename _Tp> \
472 inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \
473 _Fun(const valarray<_Tp>& __v, const _Tp& __t) \
475 typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \
476 return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \
479 template<typename _Tp> \
480 inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \
481 _Fun(const _Tp& __t, const valarray<_Tp>& __v) \
483 typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \
484 return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \
487 _DEFINE_EXPR_BINARY_FUNCTION(atan2
)
488 _DEFINE_EXPR_BINARY_FUNCTION(pow
)
490 #undef _DEFINE_EXPR_BINARY_FUNCTION
495 #endif /* _CPP_VALARRAY_AFTER_H */