xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/bits/valarray_before.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // The template and inlines for the -*- C++ -*- internal _Meta class.
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4*404b540aSrobert // Free Software Foundation, Inc.
5*404b540aSrobert //
6*404b540aSrobert // This file is part of the GNU ISO C++ Library.  This library is free
7*404b540aSrobert // software; you can redistribute it and/or modify it under the
8*404b540aSrobert // terms of the GNU General Public License as published by the
9*404b540aSrobert // Free Software Foundation; either version 2, or (at your option)
10*404b540aSrobert // any later version.
11*404b540aSrobert 
12*404b540aSrobert // This library is distributed in the hope that it will be useful,
13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*404b540aSrobert // GNU General Public License for more details.
16*404b540aSrobert 
17*404b540aSrobert // You should have received a copy of the GNU General Public License along
18*404b540aSrobert // with this library; see the file COPYING.  If not, write to the Free
19*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20*404b540aSrobert // USA.
21*404b540aSrobert 
22*404b540aSrobert // As a special exception, you may use this file as part of a free software
23*404b540aSrobert // library without restriction.  Specifically, if other files instantiate
24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
25*404b540aSrobert // this file and link it with other files to produce an executable, this
26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
27*404b540aSrobert // the GNU General Public License.  This exception does not however
28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
29*404b540aSrobert // the GNU General Public License.
30*404b540aSrobert 
31*404b540aSrobert /** @file valarray_before.h
32*404b540aSrobert  *  This is an internal header file, included by other library headers.
33*404b540aSrobert  *  You should not attempt to use it directly.
34*404b540aSrobert  */
35*404b540aSrobert 
36*404b540aSrobert // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
37*404b540aSrobert 
38*404b540aSrobert #ifndef _VALARRAY_BEFORE_H
39*404b540aSrobert #define _VALARRAY_BEFORE_H 1
40*404b540aSrobert 
41*404b540aSrobert #pragma GCC system_header
42*404b540aSrobert 
43*404b540aSrobert #include <bits/slice_array.h>
44*404b540aSrobert 
45*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(std)
46*404b540aSrobert 
47*404b540aSrobert   //
48*404b540aSrobert   // Implementing a loosened valarray return value is tricky.
49*404b540aSrobert   // First we need to meet 26.3.1/3: we should not add more than
50*404b540aSrobert   // two levels of template nesting. Therefore we resort to template
51*404b540aSrobert   // template to "flatten" loosened return value types.
52*404b540aSrobert   // At some point we use partial specialization to remove one level
53*404b540aSrobert   // template nesting due to _Expr<>
54*404b540aSrobert   //
55*404b540aSrobert 
56*404b540aSrobert   // This class is NOT defined. It doesn't need to.
57*404b540aSrobert   template<typename _Tp1, typename _Tp2> class _Constant;
58*404b540aSrobert 
59*404b540aSrobert   // Implementations of unary functions applied to valarray<>s.
60*404b540aSrobert   // I use hard-coded object functions here instead of a generic
61*404b540aSrobert   // approach like pointers to function:
62*404b540aSrobert   //    1) correctness: some functions take references, others values.
63*404b540aSrobert   //       we can't deduce the correct type afterwards.
64*404b540aSrobert   //    2) efficiency -- object functions can be easily inlined
65*404b540aSrobert   //    3) be Koenig-lookup-friendly
66*404b540aSrobert 
67*404b540aSrobert   struct __abs
68*404b540aSrobert   {
69*404b540aSrobert     template<typename _Tp>
operator__abs70*404b540aSrobert       _Tp operator()(const _Tp& __t) const
71*404b540aSrobert       { return abs(__t); }
72*404b540aSrobert   };
73*404b540aSrobert 
74*404b540aSrobert   struct __cos
75*404b540aSrobert   {
76*404b540aSrobert     template<typename _Tp>
operator__cos77*404b540aSrobert       _Tp operator()(const _Tp& __t) const
78*404b540aSrobert       { return cos(__t); }
79*404b540aSrobert   };
80*404b540aSrobert 
81*404b540aSrobert   struct __acos
82*404b540aSrobert   {
83*404b540aSrobert     template<typename _Tp>
operator__acos84*404b540aSrobert       _Tp operator()(const _Tp& __t) const
85*404b540aSrobert       { return acos(__t); }
86*404b540aSrobert   };
87*404b540aSrobert 
88*404b540aSrobert   struct __cosh
89*404b540aSrobert   {
90*404b540aSrobert     template<typename _Tp>
operator__cosh91*404b540aSrobert       _Tp operator()(const _Tp& __t) const
92*404b540aSrobert       { return cosh(__t); }
93*404b540aSrobert   };
94*404b540aSrobert 
95*404b540aSrobert   struct __sin
96*404b540aSrobert   {
97*404b540aSrobert     template<typename _Tp>
operator__sin98*404b540aSrobert       _Tp operator()(const _Tp& __t) const
99*404b540aSrobert       { return sin(__t); }
100*404b540aSrobert   };
101*404b540aSrobert 
102*404b540aSrobert   struct __asin
103*404b540aSrobert   {
104*404b540aSrobert     template<typename _Tp>
operator__asin105*404b540aSrobert       _Tp operator()(const _Tp& __t) const
106*404b540aSrobert       { return asin(__t); }
107*404b540aSrobert   };
108*404b540aSrobert 
109*404b540aSrobert   struct __sinh
110*404b540aSrobert   {
111*404b540aSrobert     template<typename _Tp>
operator__sinh112*404b540aSrobert       _Tp operator()(const _Tp& __t) const
113*404b540aSrobert       { return sinh(__t); }
114*404b540aSrobert   };
115*404b540aSrobert 
116*404b540aSrobert   struct __tan
117*404b540aSrobert   {
118*404b540aSrobert     template<typename _Tp>
operator__tan119*404b540aSrobert       _Tp operator()(const _Tp& __t) const
120*404b540aSrobert       { return tan(__t); }
121*404b540aSrobert   };
122*404b540aSrobert 
123*404b540aSrobert   struct __atan
124*404b540aSrobert   {
125*404b540aSrobert     template<typename _Tp>
operator__atan126*404b540aSrobert       _Tp operator()(const _Tp& __t) const
127*404b540aSrobert       { return atan(__t); }
128*404b540aSrobert   };
129*404b540aSrobert 
130*404b540aSrobert   struct __tanh
131*404b540aSrobert   {
132*404b540aSrobert     template<typename _Tp>
operator__tanh133*404b540aSrobert       _Tp operator()(const _Tp& __t) const
134*404b540aSrobert       { return tanh(__t); }
135*404b540aSrobert   };
136*404b540aSrobert 
137*404b540aSrobert   struct __exp
138*404b540aSrobert   {
139*404b540aSrobert     template<typename _Tp>
operator__exp140*404b540aSrobert       _Tp operator()(const _Tp& __t) const
141*404b540aSrobert       { return exp(__t); }
142*404b540aSrobert   };
143*404b540aSrobert 
144*404b540aSrobert   struct __log
145*404b540aSrobert   {
146*404b540aSrobert     template<typename _Tp>
operator__log147*404b540aSrobert       _Tp operator()(const _Tp& __t) const
148*404b540aSrobert       { return log(__t); }
149*404b540aSrobert   };
150*404b540aSrobert 
151*404b540aSrobert   struct __log10
152*404b540aSrobert   {
153*404b540aSrobert     template<typename _Tp>
operator__log10154*404b540aSrobert       _Tp operator()(const _Tp& __t) const
155*404b540aSrobert       { return log10(__t); }
156*404b540aSrobert   };
157*404b540aSrobert 
158*404b540aSrobert   struct __sqrt
159*404b540aSrobert   {
160*404b540aSrobert     template<typename _Tp>
operator__sqrt161*404b540aSrobert       _Tp operator()(const _Tp& __t) const
162*404b540aSrobert       { return sqrt(__t); }
163*404b540aSrobert   };
164*404b540aSrobert 
165*404b540aSrobert   // In the past, we used to tailor operator applications semantics
166*404b540aSrobert   // to the specialization of standard function objects (i.e. plus<>, etc.)
167*404b540aSrobert   // That is incorrect.  Therefore we provide our own surrogates.
168*404b540aSrobert 
169*404b540aSrobert   struct __unary_plus
170*404b540aSrobert   {
171*404b540aSrobert     template<typename _Tp>
operator__unary_plus172*404b540aSrobert       _Tp operator()(const _Tp& __t) const
173*404b540aSrobert       { return +__t; }
174*404b540aSrobert   };
175*404b540aSrobert 
176*404b540aSrobert   struct __negate
177*404b540aSrobert   {
178*404b540aSrobert     template<typename _Tp>
operator__negate179*404b540aSrobert       _Tp operator()(const _Tp& __t) const
180*404b540aSrobert       { return -__t; }
181*404b540aSrobert   };
182*404b540aSrobert 
183*404b540aSrobert   struct __bitwise_not
184*404b540aSrobert   {
185*404b540aSrobert     template<typename _Tp>
operator__bitwise_not186*404b540aSrobert       _Tp operator()(const _Tp& __t) const
187*404b540aSrobert       { return ~__t; }
188*404b540aSrobert   };
189*404b540aSrobert 
190*404b540aSrobert   struct __plus
191*404b540aSrobert   {
192*404b540aSrobert     template<typename _Tp>
operator__plus193*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
194*404b540aSrobert       { return __x + __y; }
195*404b540aSrobert   };
196*404b540aSrobert 
197*404b540aSrobert   struct __minus
198*404b540aSrobert   {
199*404b540aSrobert     template<typename _Tp>
operator__minus200*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
201*404b540aSrobert       { return __x - __y; }
202*404b540aSrobert   };
203*404b540aSrobert 
204*404b540aSrobert   struct __multiplies
205*404b540aSrobert   {
206*404b540aSrobert     template<typename _Tp>
operator__multiplies207*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
208*404b540aSrobert       { return __x * __y; }
209*404b540aSrobert   };
210*404b540aSrobert 
211*404b540aSrobert   struct __divides
212*404b540aSrobert   {
213*404b540aSrobert     template<typename _Tp>
operator__divides214*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
215*404b540aSrobert       { return __x / __y; }
216*404b540aSrobert   };
217*404b540aSrobert 
218*404b540aSrobert   struct __modulus
219*404b540aSrobert   {
220*404b540aSrobert     template<typename _Tp>
operator__modulus221*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
222*404b540aSrobert       { return __x % __y; }
223*404b540aSrobert   };
224*404b540aSrobert 
225*404b540aSrobert   struct __bitwise_xor
226*404b540aSrobert   {
227*404b540aSrobert     template<typename _Tp>
operator__bitwise_xor228*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
229*404b540aSrobert       { return __x ^ __y; }
230*404b540aSrobert   };
231*404b540aSrobert 
232*404b540aSrobert   struct __bitwise_and
233*404b540aSrobert   {
234*404b540aSrobert     template<typename _Tp>
operator__bitwise_and235*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
236*404b540aSrobert       { return __x & __y; }
237*404b540aSrobert   };
238*404b540aSrobert 
239*404b540aSrobert   struct __bitwise_or
240*404b540aSrobert   {
241*404b540aSrobert     template<typename _Tp>
operator__bitwise_or242*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
243*404b540aSrobert       { return __x | __y; }
244*404b540aSrobert   };
245*404b540aSrobert 
246*404b540aSrobert   struct __shift_left
247*404b540aSrobert   {
248*404b540aSrobert     template<typename _Tp>
operator__shift_left249*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
250*404b540aSrobert       { return __x << __y; }
251*404b540aSrobert   };
252*404b540aSrobert 
253*404b540aSrobert   struct __shift_right
254*404b540aSrobert   {
255*404b540aSrobert     template<typename _Tp>
operator__shift_right256*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
257*404b540aSrobert       { return __x >> __y; }
258*404b540aSrobert   };
259*404b540aSrobert 
260*404b540aSrobert   struct __logical_and
261*404b540aSrobert   {
262*404b540aSrobert     template<typename _Tp>
operator__logical_and263*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
264*404b540aSrobert       { return __x && __y; }
265*404b540aSrobert   };
266*404b540aSrobert 
267*404b540aSrobert   struct __logical_or
268*404b540aSrobert   {
269*404b540aSrobert     template<typename _Tp>
operator__logical_or270*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
271*404b540aSrobert       { return __x || __y; }
272*404b540aSrobert   };
273*404b540aSrobert 
274*404b540aSrobert   struct __logical_not
275*404b540aSrobert   {
276*404b540aSrobert     template<typename _Tp>
operator__logical_not277*404b540aSrobert       bool operator()(const _Tp& __x) const { return !__x; }
278*404b540aSrobert   };
279*404b540aSrobert 
280*404b540aSrobert   struct __equal_to
281*404b540aSrobert   {
282*404b540aSrobert     template<typename _Tp>
operator__equal_to283*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
284*404b540aSrobert       { return __x == __y; }
285*404b540aSrobert   };
286*404b540aSrobert 
287*404b540aSrobert   struct __not_equal_to
288*404b540aSrobert   {
289*404b540aSrobert     template<typename _Tp>
operator__not_equal_to290*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
291*404b540aSrobert       { return __x != __y; }
292*404b540aSrobert   };
293*404b540aSrobert 
294*404b540aSrobert   struct __less
295*404b540aSrobert   {
296*404b540aSrobert     template<typename _Tp>
operator__less297*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
298*404b540aSrobert       { return __x < __y; }
299*404b540aSrobert   };
300*404b540aSrobert 
301*404b540aSrobert   struct __greater
302*404b540aSrobert   {
303*404b540aSrobert     template<typename _Tp>
operator__greater304*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
305*404b540aSrobert       { return __x > __y; }
306*404b540aSrobert   };
307*404b540aSrobert 
308*404b540aSrobert   struct __less_equal
309*404b540aSrobert   {
310*404b540aSrobert     template<typename _Tp>
operator__less_equal311*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
312*404b540aSrobert       { return __x <= __y; }
313*404b540aSrobert   };
314*404b540aSrobert 
315*404b540aSrobert   struct __greater_equal
316*404b540aSrobert   {
317*404b540aSrobert     template<typename _Tp>
operator__greater_equal318*404b540aSrobert       bool operator()(const _Tp& __x, const _Tp& __y) const
319*404b540aSrobert       { return __x >= __y; }
320*404b540aSrobert   };
321*404b540aSrobert 
322*404b540aSrobert   // The few binary functions we miss.
323*404b540aSrobert   struct __atan2
324*404b540aSrobert   {
325*404b540aSrobert     template<typename _Tp>
operator__atan2326*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
327*404b540aSrobert       { return atan2(__x, __y); }
328*404b540aSrobert   };
329*404b540aSrobert 
330*404b540aSrobert   struct __pow
331*404b540aSrobert   {
332*404b540aSrobert     template<typename _Tp>
operator__pow333*404b540aSrobert       _Tp operator()(const _Tp& __x, const _Tp& __y) const
334*404b540aSrobert       { return pow(__x, __y); }
335*404b540aSrobert   };
336*404b540aSrobert 
337*404b540aSrobert 
338*404b540aSrobert   // We need these bits in order to recover the return type of
339*404b540aSrobert   // some functions/operators now that we're no longer using
340*404b540aSrobert   // function templates.
341*404b540aSrobert   template<typename, typename _Tp>
342*404b540aSrobert     struct __fun
343*404b540aSrobert     {
344*404b540aSrobert       typedef _Tp result_type;
345*404b540aSrobert     };
346*404b540aSrobert 
347*404b540aSrobert   // several specializations for relational operators.
348*404b540aSrobert   template<typename _Tp>
349*404b540aSrobert     struct __fun<__logical_not, _Tp>
350*404b540aSrobert     {
351*404b540aSrobert       typedef bool result_type;
352*404b540aSrobert     };
353*404b540aSrobert 
354*404b540aSrobert   template<typename _Tp>
355*404b540aSrobert     struct __fun<__logical_and, _Tp>
356*404b540aSrobert     {
357*404b540aSrobert       typedef bool result_type;
358*404b540aSrobert     };
359*404b540aSrobert 
360*404b540aSrobert   template<typename _Tp>
361*404b540aSrobert     struct __fun<__logical_or, _Tp>
362*404b540aSrobert     {
363*404b540aSrobert       typedef bool result_type;
364*404b540aSrobert     };
365*404b540aSrobert 
366*404b540aSrobert   template<typename _Tp>
367*404b540aSrobert     struct __fun<__less, _Tp>
368*404b540aSrobert     {
369*404b540aSrobert       typedef bool result_type;
370*404b540aSrobert     };
371*404b540aSrobert 
372*404b540aSrobert   template<typename _Tp>
373*404b540aSrobert     struct __fun<__greater, _Tp>
374*404b540aSrobert     {
375*404b540aSrobert       typedef bool result_type;
376*404b540aSrobert     };
377*404b540aSrobert 
378*404b540aSrobert   template<typename _Tp>
379*404b540aSrobert     struct __fun<__less_equal, _Tp>
380*404b540aSrobert     {
381*404b540aSrobert       typedef bool result_type;
382*404b540aSrobert     };
383*404b540aSrobert 
384*404b540aSrobert   template<typename _Tp>
385*404b540aSrobert     struct __fun<__greater_equal, _Tp>
386*404b540aSrobert     {
387*404b540aSrobert       typedef bool result_type;
388*404b540aSrobert     };
389*404b540aSrobert 
390*404b540aSrobert   template<typename _Tp>
391*404b540aSrobert     struct __fun<__equal_to, _Tp>
392*404b540aSrobert     {
393*404b540aSrobert       typedef bool result_type;
394*404b540aSrobert     };
395*404b540aSrobert 
396*404b540aSrobert   template<typename _Tp>
397*404b540aSrobert     struct __fun<__not_equal_to, _Tp>
398*404b540aSrobert     {
399*404b540aSrobert       typedef bool result_type;
400*404b540aSrobert     };
401*404b540aSrobert 
402*404b540aSrobert   //
403*404b540aSrobert   // Apply function taking a value/const reference closure
404*404b540aSrobert   //
405*404b540aSrobert 
406*404b540aSrobert   template<typename _Dom, typename _Arg>
407*404b540aSrobert     class _FunBase
408*404b540aSrobert     {
409*404b540aSrobert     public:
410*404b540aSrobert       typedef typename _Dom::value_type value_type;
411*404b540aSrobert 
412*404b540aSrobert       _FunBase(const _Dom& __e, value_type __f(_Arg))
413*404b540aSrobert       : _M_expr(__e), _M_func(__f) {}
414*404b540aSrobert 
415*404b540aSrobert       value_type operator[](size_t __i) const
416*404b540aSrobert       { return _M_func (_M_expr[__i]); }
417*404b540aSrobert 
418*404b540aSrobert       size_t size() const { return _M_expr.size ();}
419*404b540aSrobert 
420*404b540aSrobert     private:
421*404b540aSrobert       const _Dom& _M_expr;
422*404b540aSrobert       value_type (*_M_func)(_Arg);
423*404b540aSrobert     };
424*404b540aSrobert 
425*404b540aSrobert   template<class _Dom>
426*404b540aSrobert     struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
427*404b540aSrobert     {
428*404b540aSrobert       typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
429*404b540aSrobert       typedef typename _Base::value_type value_type;
430*404b540aSrobert       typedef value_type _Tp;
431*404b540aSrobert 
432*404b540aSrobert       _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
433*404b540aSrobert     };
434*404b540aSrobert 
435*404b540aSrobert   template<typename _Tp>
436*404b540aSrobert     struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
437*404b540aSrobert     {
438*404b540aSrobert       typedef _FunBase<valarray<_Tp>, _Tp> _Base;
439*404b540aSrobert       typedef _Tp value_type;
440*404b540aSrobert 
441*404b540aSrobert       _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
442*404b540aSrobert     };
443*404b540aSrobert 
444*404b540aSrobert   template<class _Dom>
445*404b540aSrobert     struct _RefFunClos<_Expr, _Dom>
446*404b540aSrobert     : _FunBase<_Dom, const typename _Dom::value_type&>
447*404b540aSrobert     {
448*404b540aSrobert       typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
449*404b540aSrobert       typedef typename _Base::value_type value_type;
450*404b540aSrobert       typedef value_type _Tp;
451*404b540aSrobert 
452*404b540aSrobert       _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
453*404b540aSrobert       : _Base(__e, __f) {}
454*404b540aSrobert     };
455*404b540aSrobert 
456*404b540aSrobert   template<typename _Tp>
457*404b540aSrobert     struct _RefFunClos<_ValArray, _Tp>
458*404b540aSrobert     : _FunBase<valarray<_Tp>, const _Tp&>
459*404b540aSrobert     {
460*404b540aSrobert       typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
461*404b540aSrobert       typedef _Tp value_type;
462*404b540aSrobert 
463*404b540aSrobert       _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
464*404b540aSrobert       : _Base(__v, __f) {}
465*404b540aSrobert     };
466*404b540aSrobert 
467*404b540aSrobert   //
468*404b540aSrobert   // Unary expression closure.
469*404b540aSrobert   //
470*404b540aSrobert 
471*404b540aSrobert   template<class _Oper, class _Arg>
472*404b540aSrobert     class _UnBase
473*404b540aSrobert     {
474*404b540aSrobert     public:
475*404b540aSrobert       typedef typename _Arg::value_type _Vt;
476*404b540aSrobert       typedef typename __fun<_Oper, _Vt>::result_type value_type;
477*404b540aSrobert 
478*404b540aSrobert       _UnBase(const _Arg& __e) : _M_expr(__e) {}
479*404b540aSrobert 
480*404b540aSrobert       value_type operator[](size_t __i) const
481*404b540aSrobert       { return _Oper()(_M_expr[__i]); }
482*404b540aSrobert 
483*404b540aSrobert       size_t size() const { return _M_expr.size(); }
484*404b540aSrobert 
485*404b540aSrobert     private:
486*404b540aSrobert       const _Arg& _M_expr;
487*404b540aSrobert     };
488*404b540aSrobert 
489*404b540aSrobert   template<class _Oper, class _Dom>
490*404b540aSrobert     struct _UnClos<_Oper, _Expr, _Dom>
491*404b540aSrobert     : _UnBase<_Oper, _Dom>
492*404b540aSrobert     {
493*404b540aSrobert       typedef _Dom _Arg;
494*404b540aSrobert       typedef _UnBase<_Oper, _Dom> _Base;
495*404b540aSrobert       typedef typename _Base::value_type value_type;
496*404b540aSrobert 
497*404b540aSrobert       _UnClos(const _Arg& __e) : _Base(__e) {}
498*404b540aSrobert     };
499*404b540aSrobert 
500*404b540aSrobert   template<class _Oper, typename _Tp>
501*404b540aSrobert     struct _UnClos<_Oper, _ValArray, _Tp>
502*404b540aSrobert     : _UnBase<_Oper, valarray<_Tp> >
503*404b540aSrobert     {
504*404b540aSrobert       typedef valarray<_Tp> _Arg;
505*404b540aSrobert       typedef _UnBase<_Oper, valarray<_Tp> > _Base;
506*404b540aSrobert       typedef typename _Base::value_type value_type;
507*404b540aSrobert 
508*404b540aSrobert       _UnClos(const _Arg& __e) : _Base(__e) {}
509*404b540aSrobert     };
510*404b540aSrobert 
511*404b540aSrobert 
512*404b540aSrobert   //
513*404b540aSrobert   // Binary expression closure.
514*404b540aSrobert   //
515*404b540aSrobert 
516*404b540aSrobert   template<class _Oper, class _FirstArg, class _SecondArg>
517*404b540aSrobert     class _BinBase
518*404b540aSrobert     {
519*404b540aSrobert     public:
520*404b540aSrobert       typedef typename _FirstArg::value_type _Vt;
521*404b540aSrobert       typedef typename __fun<_Oper, _Vt>::result_type value_type;
522*404b540aSrobert 
523*404b540aSrobert       _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
524*404b540aSrobert       : _M_expr1(__e1), _M_expr2(__e2) {}
525*404b540aSrobert 
526*404b540aSrobert       value_type operator[](size_t __i) const
527*404b540aSrobert       { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
528*404b540aSrobert 
529*404b540aSrobert       size_t size() const { return _M_expr1.size(); }
530*404b540aSrobert 
531*404b540aSrobert     private:
532*404b540aSrobert       const _FirstArg& _M_expr1;
533*404b540aSrobert       const _SecondArg& _M_expr2;
534*404b540aSrobert     };
535*404b540aSrobert 
536*404b540aSrobert 
537*404b540aSrobert   template<class _Oper, class _Clos>
538*404b540aSrobert     class _BinBase2
539*404b540aSrobert     {
540*404b540aSrobert     public:
541*404b540aSrobert       typedef typename _Clos::value_type _Vt;
542*404b540aSrobert       typedef typename __fun<_Oper, _Vt>::result_type value_type;
543*404b540aSrobert 
544*404b540aSrobert       _BinBase2(const _Clos& __e, const _Vt& __t)
545*404b540aSrobert       : _M_expr1(__e), _M_expr2(__t) {}
546*404b540aSrobert 
547*404b540aSrobert       value_type operator[](size_t __i) const
548*404b540aSrobert       { return _Oper()(_M_expr1[__i], _M_expr2); }
549*404b540aSrobert 
550*404b540aSrobert       size_t size() const { return _M_expr1.size(); }
551*404b540aSrobert 
552*404b540aSrobert     private:
553*404b540aSrobert       const _Clos& _M_expr1;
554*404b540aSrobert       const _Vt& _M_expr2;
555*404b540aSrobert     };
556*404b540aSrobert 
557*404b540aSrobert   template<class _Oper, class _Clos>
558*404b540aSrobert     class _BinBase1
559*404b540aSrobert     {
560*404b540aSrobert     public:
561*404b540aSrobert       typedef typename _Clos::value_type _Vt;
562*404b540aSrobert       typedef typename __fun<_Oper, _Vt>::result_type value_type;
563*404b540aSrobert 
564*404b540aSrobert       _BinBase1(const _Vt& __t, const _Clos& __e)
565*404b540aSrobert       : _M_expr1(__t), _M_expr2(__e) {}
566*404b540aSrobert 
567*404b540aSrobert       value_type operator[](size_t __i) const
568*404b540aSrobert       { return _Oper()(_M_expr1, _M_expr2[__i]); }
569*404b540aSrobert 
570*404b540aSrobert       size_t size() const { return _M_expr2.size(); }
571*404b540aSrobert 
572*404b540aSrobert     private:
573*404b540aSrobert       const _Vt& _M_expr1;
574*404b540aSrobert       const _Clos& _M_expr2;
575*404b540aSrobert     };
576*404b540aSrobert 
577*404b540aSrobert   template<class _Oper, class _Dom1, class _Dom2>
578*404b540aSrobert     struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
579*404b540aSrobert     : _BinBase<_Oper, _Dom1, _Dom2>
580*404b540aSrobert     {
581*404b540aSrobert       typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
582*404b540aSrobert       typedef typename _Base::value_type value_type;
583*404b540aSrobert 
584*404b540aSrobert       _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
585*404b540aSrobert     };
586*404b540aSrobert 
587*404b540aSrobert   template<class _Oper, typename _Tp>
588*404b540aSrobert     struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp>
589*404b540aSrobert     : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
590*404b540aSrobert     {
591*404b540aSrobert       typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
592*404b540aSrobert       typedef typename _Base::value_type value_type;
593*404b540aSrobert 
594*404b540aSrobert       _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
595*404b540aSrobert       : _Base(__v, __w) {}
596*404b540aSrobert     };
597*404b540aSrobert 
598*404b540aSrobert   template<class _Oper, class _Dom>
599*404b540aSrobert     struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
600*404b540aSrobert     : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
601*404b540aSrobert     {
602*404b540aSrobert       typedef typename _Dom::value_type _Tp;
603*404b540aSrobert       typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
604*404b540aSrobert       typedef typename _Base::value_type value_type;
605*404b540aSrobert 
606*404b540aSrobert       _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
607*404b540aSrobert       : _Base(__e1, __e2) {}
608*404b540aSrobert     };
609*404b540aSrobert 
610*404b540aSrobert   template<class _Oper, class _Dom>
611*404b540aSrobert     struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
612*404b540aSrobert     : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
613*404b540aSrobert     {
614*404b540aSrobert       typedef typename _Dom::value_type _Tp;
615*404b540aSrobert       typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
616*404b540aSrobert       typedef typename _Base::value_type value_type;
617*404b540aSrobert 
618*404b540aSrobert       _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
619*404b540aSrobert       : _Base(__e1, __e2) {}
620*404b540aSrobert     };
621*404b540aSrobert 
622*404b540aSrobert   template<class _Oper, class _Dom>
623*404b540aSrobert     struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
624*404b540aSrobert     : _BinBase2<_Oper, _Dom>
625*404b540aSrobert     {
626*404b540aSrobert       typedef typename _Dom::value_type _Tp;
627*404b540aSrobert       typedef _BinBase2<_Oper,_Dom> _Base;
628*404b540aSrobert       typedef typename _Base::value_type value_type;
629*404b540aSrobert 
630*404b540aSrobert       _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
631*404b540aSrobert     };
632*404b540aSrobert 
633*404b540aSrobert   template<class _Oper, class _Dom>
634*404b540aSrobert     struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
635*404b540aSrobert     : _BinBase1<_Oper, _Dom>
636*404b540aSrobert     {
637*404b540aSrobert       typedef typename _Dom::value_type _Tp;
638*404b540aSrobert       typedef _BinBase1<_Oper, _Dom> _Base;
639*404b540aSrobert       typedef typename _Base::value_type value_type;
640*404b540aSrobert 
641*404b540aSrobert       _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
642*404b540aSrobert     };
643*404b540aSrobert 
644*404b540aSrobert   template<class _Oper, typename _Tp>
645*404b540aSrobert     struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
646*404b540aSrobert     : _BinBase2<_Oper, valarray<_Tp> >
647*404b540aSrobert     {
648*404b540aSrobert       typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
649*404b540aSrobert       typedef typename _Base::value_type value_type;
650*404b540aSrobert 
651*404b540aSrobert       _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
652*404b540aSrobert     };
653*404b540aSrobert 
654*404b540aSrobert   template<class _Oper, typename _Tp>
655*404b540aSrobert     struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
656*404b540aSrobert     : _BinBase1<_Oper, valarray<_Tp> >
657*404b540aSrobert     {
658*404b540aSrobert       typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
659*404b540aSrobert       typedef typename _Base::value_type value_type;
660*404b540aSrobert 
661*404b540aSrobert       _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
662*404b540aSrobert     };
663*404b540aSrobert 
664*404b540aSrobert     //
665*404b540aSrobert     // slice_array closure.
666*404b540aSrobert     //
667*404b540aSrobert   template<typename _Dom>
668*404b540aSrobert     class _SBase
669*404b540aSrobert     {
670*404b540aSrobert     public:
671*404b540aSrobert       typedef typename _Dom::value_type value_type;
672*404b540aSrobert 
673*404b540aSrobert       _SBase (const _Dom& __e, const slice& __s)
674*404b540aSrobert       : _M_expr (__e), _M_slice (__s) {}
675*404b540aSrobert 
676*404b540aSrobert       value_type
677*404b540aSrobert       operator[] (size_t __i) const
678*404b540aSrobert       { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
679*404b540aSrobert 
680*404b540aSrobert       size_t
681*404b540aSrobert       size() const
682*404b540aSrobert       { return _M_slice.size (); }
683*404b540aSrobert 
684*404b540aSrobert     private:
685*404b540aSrobert       const _Dom& _M_expr;
686*404b540aSrobert       const slice& _M_slice;
687*404b540aSrobert     };
688*404b540aSrobert 
689*404b540aSrobert   template<typename _Tp>
690*404b540aSrobert     class _SBase<_Array<_Tp> >
691*404b540aSrobert     {
692*404b540aSrobert     public:
693*404b540aSrobert       typedef _Tp value_type;
694*404b540aSrobert 
695*404b540aSrobert       _SBase (_Array<_Tp> __a, const slice& __s)
696*404b540aSrobert       : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
697*404b540aSrobert 	_M_stride (__s.stride()) {}
698*404b540aSrobert 
699*404b540aSrobert       value_type
700*404b540aSrobert       operator[] (size_t __i) const
701*404b540aSrobert       { return _M_array._M_data[__i * _M_stride]; }
702*404b540aSrobert 
703*404b540aSrobert       size_t
704*404b540aSrobert       size() const
705*404b540aSrobert       { return _M_size; }
706*404b540aSrobert 
707*404b540aSrobert     private:
708*404b540aSrobert       const _Array<_Tp> _M_array;
709*404b540aSrobert       const size_t _M_size;
710*404b540aSrobert       const size_t _M_stride;
711*404b540aSrobert     };
712*404b540aSrobert 
713*404b540aSrobert   template<class _Dom>
714*404b540aSrobert     struct _SClos<_Expr, _Dom>
715*404b540aSrobert     : _SBase<_Dom>
716*404b540aSrobert     {
717*404b540aSrobert       typedef _SBase<_Dom> _Base;
718*404b540aSrobert       typedef typename _Base::value_type value_type;
719*404b540aSrobert 
720*404b540aSrobert       _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
721*404b540aSrobert     };
722*404b540aSrobert 
723*404b540aSrobert   template<typename _Tp>
724*404b540aSrobert     struct _SClos<_ValArray, _Tp>
725*404b540aSrobert     : _SBase<_Array<_Tp> >
726*404b540aSrobert     {
727*404b540aSrobert       typedef  _SBase<_Array<_Tp> > _Base;
728*404b540aSrobert       typedef _Tp value_type;
729*404b540aSrobert 
730*404b540aSrobert       _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
731*404b540aSrobert     };
732*404b540aSrobert 
733*404b540aSrobert _GLIBCXX_END_NAMESPACE
734*404b540aSrobert 
735*404b540aSrobert #endif /* _CPP_VALARRAY_BEFORE_H */
736