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