1*00db7afdSDavid E. O'Brien // The template and inlines for the -*- C++ -*- internal _Array helper class.
2*00db7afdSDavid E. O'Brien 
3*00db7afdSDavid E. O'Brien // Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4*00db7afdSDavid E. O'Brien //
5*00db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
6*00db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
7*00db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
8*00db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
9*00db7afdSDavid E. O'Brien // any later version.
10*00db7afdSDavid E. O'Brien 
11*00db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
12*00db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*00db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*00db7afdSDavid E. O'Brien // GNU General Public License for more details.
15*00db7afdSDavid E. O'Brien 
16*00db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
17*00db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
18*00db7afdSDavid E. O'Brien // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19*00db7afdSDavid E. O'Brien // USA.
20*00db7afdSDavid E. O'Brien 
21*00db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
22*00db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
23*00db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
24*00db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
25*00db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
26*00db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
27*00db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
28*00db7afdSDavid E. O'Brien // the GNU General Public License.
29*00db7afdSDavid E. O'Brien 
30*00db7afdSDavid E. O'Brien // Written by Gabriel Dos Reis <[email protected]>
31*00db7afdSDavid E. O'Brien 
32*00db7afdSDavid E. O'Brien /** @file valarray_array.h
33*00db7afdSDavid E. O'Brien  *  This is an internal header file, included by other library headers.
34*00db7afdSDavid E. O'Brien  *  You should not attempt to use it directly.
35*00db7afdSDavid E. O'Brien  */
36*00db7afdSDavid E. O'Brien 
37*00db7afdSDavid E. O'Brien #ifndef _CPP_BITS_ARRAY_H
38*00db7afdSDavid E. O'Brien #define _CPP_BITS_ARRAY_H 1
39*00db7afdSDavid E. O'Brien 
40*00db7afdSDavid E. O'Brien #pragma GCC system_header
41*00db7afdSDavid E. O'Brien 
42*00db7afdSDavid E. O'Brien #include <bits/c++config.h>
43*00db7afdSDavid E. O'Brien #include <bits/cpp_type_traits.h>
44*00db7afdSDavid E. O'Brien #include <cstdlib>
45*00db7afdSDavid E. O'Brien #include <cstring>
46*00db7afdSDavid E. O'Brien #include <new>
47*00db7afdSDavid E. O'Brien 
48*00db7afdSDavid E. O'Brien namespace std
49*00db7afdSDavid E. O'Brien {
50*00db7afdSDavid E. O'Brien   //
51*00db7afdSDavid E. O'Brien   // Helper functions on raw pointers
52*00db7afdSDavid E. O'Brien   //
53*00db7afdSDavid E. O'Brien 
54*00db7afdSDavid E. O'Brien   // We get memory by the old fashion way
55*00db7afdSDavid E. O'Brien   inline void*
56*00db7afdSDavid E. O'Brien   __valarray_get_memory(size_t __n)
57*00db7afdSDavid E. O'Brien   { return operator new(__n); }
58*00db7afdSDavid E. O'Brien 
59*00db7afdSDavid E. O'Brien   template<typename _Tp>
60*00db7afdSDavid E. O'Brien      inline _Tp*__restrict__
61*00db7afdSDavid E. O'Brien      __valarray_get_storage(size_t __n)
62*00db7afdSDavid E. O'Brien      {
63*00db7afdSDavid E. O'Brien        return static_cast<_Tp*__restrict__>
64*00db7afdSDavid E. O'Brien          (__valarray_get_memory(__n * sizeof(_Tp)));
65*00db7afdSDavid E. O'Brien      }
66*00db7afdSDavid E. O'Brien 
67*00db7afdSDavid E. O'Brien   // Return memory to the system
68*00db7afdSDavid E. O'Brien   inline void
69*00db7afdSDavid E. O'Brien   __valarray_release_memory(void* __p)
70*00db7afdSDavid E. O'Brien   { operator delete(__p); }
71*00db7afdSDavid E. O'Brien 
72*00db7afdSDavid E. O'Brien   // Turn a raw-memory into an array of _Tp filled with _Tp()
73*00db7afdSDavid E. O'Brien   // This is required in 'valarray<T> v(n);'
74*00db7afdSDavid E. O'Brien   template<typename _Tp, bool>
75*00db7afdSDavid E. O'Brien      struct _Array_default_ctor
76*00db7afdSDavid E. O'Brien      {
77*00db7afdSDavid E. O'Brien        // Please note that this isn't exception safe.  But
78*00db7afdSDavid E. O'Brien        // valarrays aren't required to be exception safe.
79*00db7afdSDavid E. O'Brien        inline static void
80*00db7afdSDavid E. O'Brien        _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
81*00db7afdSDavid E. O'Brien        { while (__b != __e) new(__b++) _Tp(); }
82*00db7afdSDavid E. O'Brien      };
83*00db7afdSDavid E. O'Brien 
84*00db7afdSDavid E. O'Brien   template<typename _Tp>
85*00db7afdSDavid E. O'Brien      struct _Array_default_ctor<_Tp, true>
86*00db7afdSDavid E. O'Brien      {
87*00db7afdSDavid E. O'Brien        // For fundamental types, it suffices to say 'memset()'
88*00db7afdSDavid E. O'Brien        inline static void
89*00db7afdSDavid E. O'Brien        _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
90*00db7afdSDavid E. O'Brien        { memset(__b, 0, (__e - __b)*sizeof(_Tp)); }
91*00db7afdSDavid E. O'Brien      };
92*00db7afdSDavid E. O'Brien 
93*00db7afdSDavid E. O'Brien   template<typename _Tp>
94*00db7afdSDavid E. O'Brien      inline void
95*00db7afdSDavid E. O'Brien      __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
96*00db7afdSDavid E. O'Brien      {
97*00db7afdSDavid E. O'Brien        _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
98*00db7afdSDavid E. O'Brien          _S_do_it(__b, __e);
99*00db7afdSDavid E. O'Brien      }
100*00db7afdSDavid E. O'Brien 
101*00db7afdSDavid E. O'Brien   // Turn a raw-memory into an array of _Tp filled with __t
102*00db7afdSDavid E. O'Brien   // This is the required in valarray<T> v(n, t).  Also
103*00db7afdSDavid E. O'Brien   // used in valarray<>::resize().
104*00db7afdSDavid E. O'Brien   template<typename _Tp, bool>
105*00db7afdSDavid E. O'Brien      struct _Array_init_ctor
106*00db7afdSDavid E. O'Brien      {
107*00db7afdSDavid E. O'Brien        // Please note that this isn't exception safe.  But
108*00db7afdSDavid E. O'Brien        // valarrays aren't required to be exception safe.
109*00db7afdSDavid E. O'Brien        inline static void
110*00db7afdSDavid E. O'Brien        _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
111*00db7afdSDavid E. O'Brien        { while (__b != __e) new(__b++) _Tp(__t); }
112*00db7afdSDavid E. O'Brien      };
113*00db7afdSDavid E. O'Brien 
114*00db7afdSDavid E. O'Brien   template<typename _Tp>
115*00db7afdSDavid E. O'Brien      struct _Array_init_ctor<_Tp, true>
116*00db7afdSDavid E. O'Brien      {
117*00db7afdSDavid E. O'Brien        inline static void
118*00db7afdSDavid E. O'Brien        _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e,  const _Tp __t)
119*00db7afdSDavid E. O'Brien        { while (__b != __e) *__b++ = __t; }
120*00db7afdSDavid E. O'Brien      };
121*00db7afdSDavid E. O'Brien 
122*00db7afdSDavid E. O'Brien   template<typename _Tp>
123*00db7afdSDavid E. O'Brien      inline void
124*00db7afdSDavid E. O'Brien      __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
125*00db7afdSDavid E. O'Brien                                const _Tp __t)
126*00db7afdSDavid E. O'Brien      {
127*00db7afdSDavid E. O'Brien        _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
128*00db7afdSDavid E. O'Brien          _S_do_it(__b, __e, __t);
129*00db7afdSDavid E. O'Brien      }
130*00db7afdSDavid E. O'Brien 
131*00db7afdSDavid E. O'Brien   //
132*00db7afdSDavid E. O'Brien   // copy-construct raw array [__o, *) from plain array [__b, __e)
133*00db7afdSDavid E. O'Brien   // We can't just say 'memcpy()'
134*00db7afdSDavid E. O'Brien   //
135*00db7afdSDavid E. O'Brien   template<typename _Tp, bool>
136*00db7afdSDavid E. O'Brien      struct _Array_copy_ctor
137*00db7afdSDavid E. O'Brien      {
138*00db7afdSDavid E. O'Brien        // Please note that this isn't exception safe.  But
139*00db7afdSDavid E. O'Brien        // valarrays aren't required to be exception safe.
140*00db7afdSDavid E. O'Brien        inline static void
141*00db7afdSDavid E. O'Brien        _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
142*00db7afdSDavid E. O'Brien                 _Tp* __restrict__ __o)
143*00db7afdSDavid E. O'Brien        { while (__b != __e) new(__o++) _Tp(*__b++); }
144*00db7afdSDavid E. O'Brien      };
145*00db7afdSDavid E. O'Brien 
146*00db7afdSDavid E. O'Brien   template<typename _Tp>
147*00db7afdSDavid E. O'Brien      struct _Array_copy_ctor<_Tp, true>
148*00db7afdSDavid E. O'Brien      {
149*00db7afdSDavid E. O'Brien        inline static void
150*00db7afdSDavid E. O'Brien        _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
151*00db7afdSDavid E. O'Brien                 _Tp* __restrict__ __o)
152*00db7afdSDavid E. O'Brien        { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); }
153*00db7afdSDavid E. O'Brien      };
154*00db7afdSDavid E. O'Brien 
155*00db7afdSDavid E. O'Brien   template<typename _Tp>
156*00db7afdSDavid E. O'Brien      inline void
157*00db7afdSDavid E. O'Brien      __valarray_copy_construct(const _Tp* __restrict__ __b,
158*00db7afdSDavid E. O'Brien                                const _Tp* __restrict__ __e,
159*00db7afdSDavid E. O'Brien                                _Tp* __restrict__ __o)
160*00db7afdSDavid E. O'Brien      {
161*00db7afdSDavid E. O'Brien        _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
162*00db7afdSDavid E. O'Brien          _S_do_it(__b, __e, __o);
163*00db7afdSDavid E. O'Brien      }
164*00db7afdSDavid E. O'Brien 
165*00db7afdSDavid E. O'Brien   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
166*00db7afdSDavid E. O'Brien   template<typename _Tp>
167*00db7afdSDavid E. O'Brien      inline void
168*00db7afdSDavid E. O'Brien      __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
169*00db7afdSDavid E. O'Brien                                 size_t __s, _Tp* __restrict__ __o)
170*00db7afdSDavid E. O'Brien      {
171*00db7afdSDavid E. O'Brien        if (__is_fundamental<_Tp>::_M_type)
172*00db7afdSDavid E. O'Brien          while (__n--) { *__o++ = *__a; __a += __s; }
173*00db7afdSDavid E. O'Brien        else
174*00db7afdSDavid E. O'Brien          while (__n--) { new(__o++) _Tp(*__a);  __a += __s; }
175*00db7afdSDavid E. O'Brien      }
176*00db7afdSDavid E. O'Brien 
177*00db7afdSDavid E. O'Brien   // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
178*00db7afdSDavid E. O'Brien   template<typename _Tp>
179*00db7afdSDavid E. O'Brien      inline void
180*00db7afdSDavid E. O'Brien      __valarray_copy_construct (const _Tp* __restrict__ __a,
181*00db7afdSDavid E. O'Brien                                 const size_t* __restrict__ __i,
182*00db7afdSDavid E. O'Brien                                 _Tp* __restrict__ __o, size_t __n)
183*00db7afdSDavid E. O'Brien      {
184*00db7afdSDavid E. O'Brien        if (__is_fundamental<_Tp>::_M_type)
185*00db7afdSDavid E. O'Brien          while (__n--) *__o++ = __a[*__i++];
186*00db7afdSDavid E. O'Brien        else
187*00db7afdSDavid E. O'Brien          while (__n--) new (__o++) _Tp(__a[*__i++]);
188*00db7afdSDavid E. O'Brien      }
189*00db7afdSDavid E. O'Brien 
190*00db7afdSDavid E. O'Brien   // Do the necessary cleanup when we're done with arrays.
191*00db7afdSDavid E. O'Brien   template<typename _Tp>
192*00db7afdSDavid E. O'Brien      inline void
193*00db7afdSDavid E. O'Brien      __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
194*00db7afdSDavid E. O'Brien      {
195*00db7afdSDavid E. O'Brien        if (!__is_fundamental<_Tp>::_M_type)
196*00db7afdSDavid E. O'Brien          while (__b != __e) { __b->~_Tp(); ++__b; }
197*00db7afdSDavid E. O'Brien      }
198*00db7afdSDavid E. O'Brien 
199*00db7afdSDavid E. O'Brien   // Fill a plain array __a[<__n>] with __t
200*00db7afdSDavid E. O'Brien   template<typename _Tp>
201*00db7afdSDavid E. O'Brien      inline void
202*00db7afdSDavid E. O'Brien      __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
203*00db7afdSDavid E. O'Brien      { while (__n--) *__a++ = __t; }
204*00db7afdSDavid E. O'Brien 
205*00db7afdSDavid E. O'Brien   // fill strided array __a[<__n-1 : __s>] with __t
206*00db7afdSDavid E. O'Brien   template<typename _Tp>
207*00db7afdSDavid E. O'Brien      inline void
208*00db7afdSDavid E. O'Brien      __valarray_fill (_Tp* __restrict__ __a, size_t __n,
209*00db7afdSDavid E. O'Brien                       size_t __s, const _Tp& __t)
210*00db7afdSDavid E. O'Brien      { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; }
211*00db7afdSDavid E. O'Brien 
212*00db7afdSDavid E. O'Brien   // fill indir   ect array __a[__i[<__n>]] with __i
213*00db7afdSDavid E. O'Brien   template<typename _Tp>
214*00db7afdSDavid E. O'Brien      inline void
215*00db7afdSDavid E. O'Brien      __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
216*00db7afdSDavid E. O'Brien                      size_t __n, const _Tp& __t)
217*00db7afdSDavid E. O'Brien      { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; }
218*00db7afdSDavid E. O'Brien 
219*00db7afdSDavid E. O'Brien   // copy plain array __a[<__n>] in __b[<__n>]
220*00db7afdSDavid E. O'Brien   // For non-fundamental types, it is wrong to say 'memcpy()'
221*00db7afdSDavid E. O'Brien   template<typename _Tp, bool>
222*00db7afdSDavid E. O'Brien      struct _Array_copier
223*00db7afdSDavid E. O'Brien      {
224*00db7afdSDavid E. O'Brien        inline static void
225*00db7afdSDavid E. O'Brien        _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
226*00db7afdSDavid E. O'Brien        { while (__n--) *__b++ = *__a++; }
227*00db7afdSDavid E. O'Brien      };
228*00db7afdSDavid E. O'Brien 
229*00db7afdSDavid E. O'Brien   template<typename _Tp>
230*00db7afdSDavid E. O'Brien      struct _Array_copier<_Tp, true>
231*00db7afdSDavid E. O'Brien      {
232*00db7afdSDavid E. O'Brien        inline static void
233*00db7afdSDavid E. O'Brien        _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
234*00db7afdSDavid E. O'Brien        { memcpy (__b, __a, __n * sizeof (_Tp)); }
235*00db7afdSDavid E. O'Brien      };
236*00db7afdSDavid E. O'Brien 
237*00db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] into a play array __b[<>]
238*00db7afdSDavid E. O'Brien   template<typename _Tp>
239*00db7afdSDavid E. O'Brien      inline void
240*00db7afdSDavid E. O'Brien      __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
241*00db7afdSDavid E. O'Brien                       _Tp* __restrict__ __b)
242*00db7afdSDavid E. O'Brien      {
243*00db7afdSDavid E. O'Brien        _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>::
244*00db7afdSDavid E. O'Brien          _S_do_it(__a, __n, __b);
245*00db7afdSDavid E. O'Brien      }
246*00db7afdSDavid E. O'Brien 
247*00db7afdSDavid E. O'Brien   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
248*00db7afdSDavid E. O'Brien   template<typename _Tp>
249*00db7afdSDavid E. O'Brien      inline void
250*00db7afdSDavid E. O'Brien      __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
251*00db7afdSDavid E. O'Brien                       _Tp* __restrict__ __b)
252*00db7afdSDavid E. O'Brien      { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; }
253*00db7afdSDavid E. O'Brien 
254*00db7afdSDavid E. O'Brien   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
255*00db7afdSDavid E. O'Brien   template<typename _Tp>
256*00db7afdSDavid E. O'Brien      inline void
257*00db7afdSDavid E. O'Brien      __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
258*00db7afdSDavid E. O'Brien                       size_t __n, size_t __s)
259*00db7afdSDavid E. O'Brien      { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; }
260*00db7afdSDavid E. O'Brien 
261*00db7afdSDavid E. O'Brien   // Copy strided array __src[<__n : __s1>] into another
262*00db7afdSDavid E. O'Brien   // strided array __dst[< : __s2>].  Their sizes must match.
263*00db7afdSDavid E. O'Brien   template<typename _Tp>
264*00db7afdSDavid E. O'Brien      inline void
265*00db7afdSDavid E. O'Brien      __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
266*00db7afdSDavid E. O'Brien                      _Tp* __restrict__ __dst, size_t __s2)
267*00db7afdSDavid E. O'Brien      {
268*00db7afdSDavid E. O'Brien        for (size_t __i = 0; __i < __n; ++__i)
269*00db7afdSDavid E. O'Brien          __dst[__i * __s2] = __src [ __i * __s1];
270*00db7afdSDavid E. O'Brien      }
271*00db7afdSDavid E. O'Brien 
272*00db7afdSDavid E. O'Brien 
273*00db7afdSDavid E. O'Brien   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
274*00db7afdSDavid E. O'Brien   template<typename _Tp>
275*00db7afdSDavid E. O'Brien      inline void
276*00db7afdSDavid E. O'Brien      __valarray_copy (const _Tp* __restrict__ __a,
277*00db7afdSDavid E. O'Brien                       const size_t* __restrict__ __i,
278*00db7afdSDavid E. O'Brien                       _Tp* __restrict__ __b, size_t __n)
279*00db7afdSDavid E. O'Brien      { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; }
280*00db7afdSDavid E. O'Brien 
281*00db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
282*00db7afdSDavid E. O'Brien   template<typename _Tp>
283*00db7afdSDavid E. O'Brien      inline void
284*00db7afdSDavid E. O'Brien      __valarray_copy (const _Tp* __restrict__ __a, size_t __n,
285*00db7afdSDavid E. O'Brien                       _Tp* __restrict__ __b, const size_t* __restrict__ __i)
286*00db7afdSDavid E. O'Brien      { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; }
287*00db7afdSDavid E. O'Brien 
288*00db7afdSDavid E. O'Brien   // Copy the __n first elements of an indexed array __src[<__i>] into
289*00db7afdSDavid E. O'Brien   // another indexed array __dst[<__j>].
290*00db7afdSDavid E. O'Brien   template<typename _Tp>
291*00db7afdSDavid E. O'Brien      inline void
292*00db7afdSDavid E. O'Brien      __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
293*00db7afdSDavid E. O'Brien                      const size_t* __restrict__ __i,
294*00db7afdSDavid E. O'Brien                      _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
295*00db7afdSDavid E. O'Brien      {
296*00db7afdSDavid E. O'Brien        for (size_t __k = 0; __k < __n; ++__k)
297*00db7afdSDavid E. O'Brien          __dst[*__j++] = __src[*__i++];
298*00db7afdSDavid E. O'Brien      }
299*00db7afdSDavid E. O'Brien 
300*00db7afdSDavid E. O'Brien   //
301*00db7afdSDavid E. O'Brien   // Compute the sum of elements in range [__f, __l)
302*00db7afdSDavid E. O'Brien   // This is a naive algorithm.  It suffers from cancelling.
303*00db7afdSDavid E. O'Brien   // In the future try to specialize
304*00db7afdSDavid E. O'Brien   // for _Tp = float, double, long double using a more accurate
305*00db7afdSDavid E. O'Brien   // algorithm.
306*00db7afdSDavid E. O'Brien   //
307*00db7afdSDavid E. O'Brien   template<typename _Tp>
308*00db7afdSDavid E. O'Brien      inline _Tp
309*00db7afdSDavid E. O'Brien      __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
310*00db7afdSDavid E. O'Brien      {
311*00db7afdSDavid E. O'Brien        _Tp __r = _Tp();
312*00db7afdSDavid E. O'Brien        while (__f != __l) __r += *__f++;
313*00db7afdSDavid E. O'Brien        return __r;
314*00db7afdSDavid E. O'Brien      }
315*00db7afdSDavid E. O'Brien 
316*00db7afdSDavid E. O'Brien   // Compute the product of all elements in range [__f, __l)
317*00db7afdSDavid E. O'Brien   template<typename _Tp>
318*00db7afdSDavid E. O'Brien      inline _Tp
319*00db7afdSDavid E. O'Brien      __valarray_product(const _Tp* __restrict__ __f,
320*00db7afdSDavid E. O'Brien                         const _Tp* __restrict__ __l)
321*00db7afdSDavid E. O'Brien      {
322*00db7afdSDavid E. O'Brien        _Tp __r = _Tp(1);
323*00db7afdSDavid E. O'Brien        while (__f != __l) __r = __r * *__f++;
324*00db7afdSDavid E. O'Brien        return __r;
325*00db7afdSDavid E. O'Brien      }
326*00db7afdSDavid E. O'Brien 
327*00db7afdSDavid E. O'Brien   // Compute the min/max of an array-expression
328*00db7afdSDavid E. O'Brien   template<typename _Ta>
329*00db7afdSDavid E. O'Brien      inline typename _Ta::value_type
330*00db7afdSDavid E. O'Brien      __valarray_min(const _Ta& __a)
331*00db7afdSDavid E. O'Brien      {
332*00db7afdSDavid E. O'Brien        size_t __s = __a.size();
333*00db7afdSDavid E. O'Brien        typedef typename _Ta::value_type _Value_type;
334*00db7afdSDavid E. O'Brien        _Value_type __r = __s == 0 ? _Value_type() : __a[0];
335*00db7afdSDavid E. O'Brien        for (size_t __i = 1; __i < __s; ++__i)
336*00db7afdSDavid E. O'Brien          {
337*00db7afdSDavid E. O'Brien            _Value_type __t = __a[__i];
338*00db7afdSDavid E. O'Brien            if (__t < __r)
339*00db7afdSDavid E. O'Brien              __r = __t;
340*00db7afdSDavid E. O'Brien          }
341*00db7afdSDavid E. O'Brien        return __r;
342*00db7afdSDavid E. O'Brien      }
343*00db7afdSDavid E. O'Brien 
344*00db7afdSDavid E. O'Brien   template<typename _Ta>
345*00db7afdSDavid E. O'Brien      inline typename _Ta::value_type
346*00db7afdSDavid E. O'Brien      __valarray_max(const _Ta& __a)
347*00db7afdSDavid E. O'Brien      {
348*00db7afdSDavid E. O'Brien        size_t __s = __a.size();
349*00db7afdSDavid E. O'Brien        typedef typename _Ta::value_type _Value_type;
350*00db7afdSDavid E. O'Brien        _Value_type __r = __s == 0 ? _Value_type() : __a[0];
351*00db7afdSDavid E. O'Brien        for (size_t __i = 1; __i < __s; ++__i)
352*00db7afdSDavid E. O'Brien          {
353*00db7afdSDavid E. O'Brien            _Value_type __t = __a[__i];
354*00db7afdSDavid E. O'Brien            if (__t > __r)
355*00db7afdSDavid E. O'Brien              __r = __t;
356*00db7afdSDavid E. O'Brien          }
357*00db7afdSDavid E. O'Brien        return __r;
358*00db7afdSDavid E. O'Brien      }
359*00db7afdSDavid E. O'Brien 
360*00db7afdSDavid E. O'Brien   //
361*00db7afdSDavid E. O'Brien   // Helper class _Array, first layer of valarray abstraction.
362*00db7afdSDavid E. O'Brien   // All operations on valarray should be forwarded to this class
363*00db7afdSDavid E. O'Brien   // whenever possible. -- gdr
364*00db7afdSDavid E. O'Brien   //
365*00db7afdSDavid E. O'Brien 
366*00db7afdSDavid E. O'Brien   template<typename _Tp>
367*00db7afdSDavid E. O'Brien      struct _Array
368*00db7afdSDavid E. O'Brien      {
369*00db7afdSDavid E. O'Brien        explicit _Array (size_t);
370*00db7afdSDavid E. O'Brien        explicit _Array (_Tp* const __restrict__);
371*00db7afdSDavid E. O'Brien        explicit _Array (const valarray<_Tp>&);
372*00db7afdSDavid E. O'Brien        _Array (const _Tp* __restrict__, size_t);
373*00db7afdSDavid E. O'Brien 
374*00db7afdSDavid E. O'Brien        _Tp* begin () const;
375*00db7afdSDavid E. O'Brien 
376*00db7afdSDavid E. O'Brien        _Tp* const __restrict__ _M_data;
377*00db7afdSDavid E. O'Brien      };
378*00db7afdSDavid E. O'Brien 
379*00db7afdSDavid E. O'Brien   template<typename _Tp>
380*00db7afdSDavid E. O'Brien      inline void
381*00db7afdSDavid E. O'Brien      __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
382*00db7afdSDavid E. O'Brien      { __valarray_fill (__a._M_data, __n, __t); }
383*00db7afdSDavid E. O'Brien 
384*00db7afdSDavid E. O'Brien   template<typename _Tp>
385*00db7afdSDavid E. O'Brien      inline void
386*00db7afdSDavid E. O'Brien      __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
387*00db7afdSDavid E. O'Brien      { __valarray_fill (__a._M_data, __n, __s, __t); }
388*00db7afdSDavid E. O'Brien 
389*00db7afdSDavid E. O'Brien   template<typename _Tp>
390*00db7afdSDavid E. O'Brien      inline void
391*00db7afdSDavid E. O'Brien      __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i,
392*00db7afdSDavid E. O'Brien                       size_t __n, const _Tp& __t)
393*00db7afdSDavid E. O'Brien      { __valarray_fill (__a._M_data, __i._M_data, __n, __t); }
394*00db7afdSDavid E. O'Brien 
395*00db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] into a play array __b[<>]
396*00db7afdSDavid E. O'Brien   template<typename _Tp>
397*00db7afdSDavid E. O'Brien      inline void
398*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
399*00db7afdSDavid E. O'Brien      { __valarray_copy(__a._M_data, __n, __b._M_data); }
400*00db7afdSDavid E. O'Brien 
401*00db7afdSDavid E. O'Brien   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
402*00db7afdSDavid E. O'Brien   template<typename _Tp>
403*00db7afdSDavid E. O'Brien      inline void
404*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
405*00db7afdSDavid E. O'Brien      { __valarray_copy(__a._M_data, __n, __s, __b._M_data); }
406*00db7afdSDavid E. O'Brien 
407*00db7afdSDavid E. O'Brien   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
408*00db7afdSDavid E. O'Brien   template<typename _Tp>
409*00db7afdSDavid E. O'Brien      inline void
410*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
411*00db7afdSDavid E. O'Brien      { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
412*00db7afdSDavid E. O'Brien 
413*00db7afdSDavid E. O'Brien   // Copy strided array __src[<__n : __s1>] into another
414*00db7afdSDavid E. O'Brien   // strided array __dst[< : __s2>].  Their sizes must match.
415*00db7afdSDavid E. O'Brien   template<typename _Tp>
416*00db7afdSDavid E. O'Brien      inline void
417*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
418*00db7afdSDavid E. O'Brien                      _Array<_Tp> __b, size_t __s2)
419*00db7afdSDavid E. O'Brien      { __valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
420*00db7afdSDavid E. O'Brien 
421*00db7afdSDavid E. O'Brien 
422*00db7afdSDavid E. O'Brien   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
423*00db7afdSDavid E. O'Brien   template<typename _Tp>
424*00db7afdSDavid E. O'Brien      inline void
425*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
426*00db7afdSDavid E. O'Brien                       _Array<_Tp> __b, size_t __n)
427*00db7afdSDavid E. O'Brien      { __valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
428*00db7afdSDavid E. O'Brien 
429*00db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
430*00db7afdSDavid E. O'Brien   template<typename _Tp>
431*00db7afdSDavid E. O'Brien      inline void
432*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
433*00db7afdSDavid E. O'Brien                       _Array<size_t> __i)
434*00db7afdSDavid E. O'Brien      { __valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
435*00db7afdSDavid E. O'Brien 
436*00db7afdSDavid E. O'Brien   // Copy the __n first elements of an indexed array __src[<__i>] into
437*00db7afdSDavid E. O'Brien   // another indexed array __dst[<__j>].
438*00db7afdSDavid E. O'Brien   template<typename _Tp>
439*00db7afdSDavid E. O'Brien      inline void
440*00db7afdSDavid E. O'Brien      __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
441*00db7afdSDavid E. O'Brien                      _Array<_Tp> __dst, _Array<size_t> __j)
442*00db7afdSDavid E. O'Brien      {
443*00db7afdSDavid E. O'Brien        __valarray_copy(__src._M_data, __n, __i._M_data,
444*00db7afdSDavid E. O'Brien                        __dst._M_data, __j._M_data);
445*00db7afdSDavid E. O'Brien      }
446*00db7afdSDavid E. O'Brien 
447*00db7afdSDavid E. O'Brien   template<typename _Tp>
448*00db7afdSDavid E. O'Brien      inline
449*00db7afdSDavid E. O'Brien      _Array<_Tp>::_Array (size_t __n)
450*00db7afdSDavid E. O'Brien        : _M_data(__valarray_get_storage<_Tp>(__n))
451*00db7afdSDavid E. O'Brien      { __valarray_default_construct(_M_data, _M_data + __n); }
452*00db7afdSDavid E. O'Brien 
453*00db7afdSDavid E. O'Brien   template<typename _Tp>
454*00db7afdSDavid E. O'Brien      inline
455*00db7afdSDavid E. O'Brien      _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {}
456*00db7afdSDavid E. O'Brien 
457*00db7afdSDavid E. O'Brien   template<typename _Tp>
458*00db7afdSDavid E. O'Brien      inline _Array<_Tp>::_Array (const valarray<_Tp>& __v)
459*00db7afdSDavid E. O'Brien          : _M_data (__v._M_data) {}
460*00db7afdSDavid E. O'Brien 
461*00db7afdSDavid E. O'Brien   template<typename _Tp>
462*00db7afdSDavid E. O'Brien      inline
463*00db7afdSDavid E. O'Brien      _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s)
464*00db7afdSDavid E. O'Brien        : _M_data(__valarray_get_storage<_Tp>(__s))
465*00db7afdSDavid E. O'Brien      { __valarray_copy_construct(__b, __s, _M_data); }
466*00db7afdSDavid E. O'Brien 
467*00db7afdSDavid E. O'Brien   template<typename _Tp>
468*00db7afdSDavid E. O'Brien      inline _Tp*
469*00db7afdSDavid E. O'Brien      _Array<_Tp>::begin () const
470*00db7afdSDavid E. O'Brien      { return _M_data; }
471*00db7afdSDavid E. O'Brien 
472*00db7afdSDavid E. O'Brien #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)				\
473*00db7afdSDavid E. O'Brien template<typename _Tp>							\
474*00db7afdSDavid E. O'Brien inline void								\
475*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t)	\
476*00db7afdSDavid E. O'Brien {									\
477*00db7afdSDavid E. O'Brien   for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p)		\
478*00db7afdSDavid E. O'Brien     *__p _Op##= __t;							\
479*00db7afdSDavid E. O'Brien }									\
480*00db7afdSDavid E. O'Brien 									\
481*00db7afdSDavid E. O'Brien template<typename _Tp>							\
482*00db7afdSDavid E. O'Brien inline void								\
483*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)	\
484*00db7afdSDavid E. O'Brien {									\
485*00db7afdSDavid E. O'Brien   _Tp* __p = __a._M_data;						\
486*00db7afdSDavid E. O'Brien   for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q)		\
487*00db7afdSDavid E. O'Brien     *__p _Op##= *__q;							\
488*00db7afdSDavid E. O'Brien }									\
489*00db7afdSDavid E. O'Brien 									\
490*00db7afdSDavid E. O'Brien template<typename _Tp, class _Dom>					\
491*00db7afdSDavid E. O'Brien void									\
492*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, 				\
493*00db7afdSDavid E. O'Brien                          const _Expr<_Dom,_Tp>& __e, size_t __n)	\
494*00db7afdSDavid E. O'Brien {									\
495*00db7afdSDavid E. O'Brien     _Tp* __p (__a._M_data);						\
496*00db7afdSDavid E. O'Brien     for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i];	\
497*00db7afdSDavid E. O'Brien }									\
498*00db7afdSDavid E. O'Brien 									\
499*00db7afdSDavid E. O'Brien template<typename _Tp>							\
500*00db7afdSDavid E. O'Brien inline void								\
501*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, 	\
502*00db7afdSDavid E. O'Brien 			 _Array<_Tp> __b)				\
503*00db7afdSDavid E. O'Brien {					       				\
504*00db7afdSDavid E. O'Brien     _Tp* __q (__b._M_data);						\
505*00db7afdSDavid E. O'Brien     for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \
506*00db7afdSDavid E. O'Brien       *__p _Op##= *__q;							\
507*00db7afdSDavid E. O'Brien }									\
508*00db7afdSDavid E. O'Brien 									\
509*00db7afdSDavid E. O'Brien template<typename _Tp>							\
510*00db7afdSDavid E. O'Brien inline void								\
511*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, 		\
512*00db7afdSDavid E. O'Brien 			 size_t __n, size_t __s)			\
513*00db7afdSDavid E. O'Brien {									\
514*00db7afdSDavid E. O'Brien     _Tp* __q (__b._M_data);						\
515*00db7afdSDavid E. O'Brien     for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s)	\
516*00db7afdSDavid E. O'Brien       *__p _Op##= *__q;							\
517*00db7afdSDavid E. O'Brien }									\
518*00db7afdSDavid E. O'Brien 									\
519*00db7afdSDavid E. O'Brien template<typename _Tp, class _Dom>					\
520*00db7afdSDavid E. O'Brien void									\
521*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s,			\
522*00db7afdSDavid E. O'Brien                           const _Expr<_Dom,_Tp>& __e, size_t __n)	\
523*00db7afdSDavid E. O'Brien {									\
524*00db7afdSDavid E. O'Brien     _Tp* __p (__a._M_data);						\
525*00db7afdSDavid E. O'Brien     for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i];	\
526*00db7afdSDavid E. O'Brien }									\
527*00db7afdSDavid E. O'Brien 									\
528*00db7afdSDavid E. O'Brien template<typename _Tp>							\
529*00db7afdSDavid E. O'Brien inline void								\
530*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i,		\
531*00db7afdSDavid E. O'Brien                           _Array<_Tp> __b, size_t __n)			\
532*00db7afdSDavid E. O'Brien {									\
533*00db7afdSDavid E. O'Brien     _Tp* __q (__b._M_data);						\
534*00db7afdSDavid E. O'Brien     for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q)	\
535*00db7afdSDavid E. O'Brien         __a._M_data[*__j] _Op##= *__q;					\
536*00db7afdSDavid E. O'Brien }									\
537*00db7afdSDavid E. O'Brien 									\
538*00db7afdSDavid E. O'Brien template<typename _Tp>							\
539*00db7afdSDavid E. O'Brien inline void								\
540*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n,			\
541*00db7afdSDavid E. O'Brien                           _Array<_Tp> __b, _Array<size_t> __i)		\
542*00db7afdSDavid E. O'Brien {									\
543*00db7afdSDavid E. O'Brien     _Tp* __p (__a._M_data);						\
544*00db7afdSDavid E. O'Brien     for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p)	\
545*00db7afdSDavid E. O'Brien         *__p _Op##= __b._M_data[*__j];					\
546*00db7afdSDavid E. O'Brien }									\
547*00db7afdSDavid E. O'Brien 									\
548*00db7afdSDavid E. O'Brien template<typename _Tp, class _Dom>					\
549*00db7afdSDavid E. O'Brien void									\
550*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i,		\
551*00db7afdSDavid E. O'Brien                           const _Expr<_Dom, _Tp>& __e, size_t __n)	\
552*00db7afdSDavid E. O'Brien {									\
553*00db7afdSDavid E. O'Brien     size_t* __j (__i._M_data);						\
554*00db7afdSDavid E. O'Brien     for (size_t __k=0; __k<__n; ++__k, ++__j) 				\
555*00db7afdSDavid E. O'Brien       __a._M_data[*__j] _Op##= __e[__k];				\
556*00db7afdSDavid E. O'Brien }									\
557*00db7afdSDavid E. O'Brien 									\
558*00db7afdSDavid E. O'Brien template<typename _Tp>							\
559*00db7afdSDavid E. O'Brien void									\
560*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m,		\
561*00db7afdSDavid E. O'Brien                           _Array<_Tp> __b, size_t __n)			\
562*00db7afdSDavid E. O'Brien {									\
563*00db7afdSDavid E. O'Brien     bool* ok (__m._M_data);						\
564*00db7afdSDavid E. O'Brien     _Tp* __p (__a._M_data);						\
565*00db7afdSDavid E. O'Brien     for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \
566*00db7afdSDavid E. O'Brien         while (! *ok) {							\
567*00db7afdSDavid E. O'Brien             ++ok;							\
568*00db7afdSDavid E. O'Brien             ++__p;							\
569*00db7afdSDavid E. O'Brien         }								\
570*00db7afdSDavid E. O'Brien         *__p _Op##= *__q;						\
571*00db7afdSDavid E. O'Brien     }									\
572*00db7afdSDavid E. O'Brien }									\
573*00db7afdSDavid E. O'Brien 									\
574*00db7afdSDavid E. O'Brien template<typename _Tp>							\
575*00db7afdSDavid E. O'Brien void									\
576*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n,			\
577*00db7afdSDavid E. O'Brien                          _Array<_Tp> __b, _Array<bool> __m)		\
578*00db7afdSDavid E. O'Brien {									\
579*00db7afdSDavid E. O'Brien     bool* ok (__m._M_data);						\
580*00db7afdSDavid E. O'Brien     _Tp* __q (__b._M_data);						\
581*00db7afdSDavid E. O'Brien     for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \
582*00db7afdSDavid E. O'Brien         while (! *ok) {							\
583*00db7afdSDavid E. O'Brien             ++ok;							\
584*00db7afdSDavid E. O'Brien             ++__q;							\
585*00db7afdSDavid E. O'Brien         }								\
586*00db7afdSDavid E. O'Brien         *__p _Op##= *__q;						\
587*00db7afdSDavid E. O'Brien     }									\
588*00db7afdSDavid E. O'Brien }									\
589*00db7afdSDavid E. O'Brien 									\
590*00db7afdSDavid E. O'Brien template<typename _Tp, class _Dom>					\
591*00db7afdSDavid E. O'Brien void									\
592*00db7afdSDavid E. O'Brien _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m,		\
593*00db7afdSDavid E. O'Brien                           const _Expr<_Dom, _Tp>& __e, size_t __n)	\
594*00db7afdSDavid E. O'Brien {									\
595*00db7afdSDavid E. O'Brien     bool* ok(__m._M_data);						\
596*00db7afdSDavid E. O'Brien     _Tp* __p (__a._M_data);						\
597*00db7afdSDavid E. O'Brien     for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) {			\
598*00db7afdSDavid E. O'Brien         while (! *ok) {							\
599*00db7afdSDavid E. O'Brien             ++ok;							\
600*00db7afdSDavid E. O'Brien             ++__p;							\
601*00db7afdSDavid E. O'Brien         }								\
602*00db7afdSDavid E. O'Brien         *__p _Op##= __e[__i];						\
603*00db7afdSDavid E. O'Brien     }									\
604*00db7afdSDavid E. O'Brien }
605*00db7afdSDavid E. O'Brien 
606*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(+, plus)
607*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(-, minus)
608*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(*, multiplies)
609*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(/, divides)
610*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(%, modulus)
611*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(^, xor)
612*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(|, or)
613*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(&, and)
614*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(<<, shift_left)
615*00db7afdSDavid E. O'Brien    _DEFINE_ARRAY_FUNCTION(>>, shift_right)
616*00db7afdSDavid E. O'Brien 
617*00db7afdSDavid E. O'Brien #undef _DEFINE_VALARRAY_FUNCTION
618*00db7afdSDavid E. O'Brien 
619*00db7afdSDavid E. O'Brien } // std::
620*00db7afdSDavid E. O'Brien 
621*00db7afdSDavid E. O'Brien #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
622*00db7afdSDavid E. O'Brien # define export
623*00db7afdSDavid E. O'Brien # include <bits/valarray_array.tcc>
624*00db7afdSDavid E. O'Brien #endif
625*00db7afdSDavid E. O'Brien 
626*00db7afdSDavid E. O'Brien #endif /* _CPP_BITS_ARRAY_H */
627*00db7afdSDavid E. O'Brien 
628*00db7afdSDavid E. O'Brien // Local Variables:
629*00db7afdSDavid E. O'Brien // mode:c++
630*00db7afdSDavid E. O'Brien // End:
631