valarray_array.h

Go to the documentation of this file.
00001 // The template and inlines for the -*- C++ -*- internal _Array helper class.
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00004 // 2006, 2007
00005 // Free Software Foundation, Inc.
00006 //
00007 // This file is part of the GNU ISO C++ Library.  This library is free
00008 // software; you can redistribute it and/or modify it under the
00009 // terms of the GNU General Public License as published by the
00010 // Free Software Foundation; either version 2, or (at your option)
00011 // any later version.
00012 
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 
00018 // You should have received a copy of the GNU General Public License along
00019 // with this library; see the file COPYING.  If not, write to the Free
00020 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021 // USA.
00022 
00023 // As a special exception, you may use this file as part of a free software
00024 // library without restriction.  Specifically, if other files instantiate
00025 // templates or use macros or inline functions from this file, or you compile
00026 // this file and link it with other files to produce an executable, this
00027 // file does not by itself cause the resulting executable to be covered by
00028 // the GNU General Public License.  This exception does not however
00029 // invalidate any other reasons why the executable file might be covered by
00030 // the GNU General Public License.
00031 
00032 /** @file valarray_array.h
00033  *  This is an internal header file, included by other library headers.
00034  *  You should not attempt to use it directly.
00035  */
00036 
00037 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
00038 
00039 #ifndef _VALARRAY_ARRAY_H
00040 #define _VALARRAY_ARRAY_H 1
00041 
00042 #pragma GCC system_header
00043 
00044 #include <bits/c++config.h>
00045 #include <bits/cpp_type_traits.h>
00046 #include <cstdlib>
00047 #include <new>
00048 
00049 _GLIBCXX_BEGIN_NAMESPACE(std)
00050 
00051   //
00052   // Helper functions on raw pointers
00053   //
00054 
00055   // We get memory by the old fashion way
00056   inline void*
00057   __valarray_get_memory(size_t __n)
00058   { return operator new(__n); }
00059 
00060   template<typename _Tp>
00061     inline _Tp*__restrict__
00062     __valarray_get_storage(size_t __n)
00063     {
00064       return static_cast<_Tp*__restrict__>
00065     (std::__valarray_get_memory(__n * sizeof(_Tp)));
00066     }
00067 
00068   // Return memory to the system
00069   inline void
00070   __valarray_release_memory(void* __p)
00071   { operator delete(__p); }
00072 
00073   // Turn a raw-memory into an array of _Tp filled with _Tp()
00074   // This is required in 'valarray<T> v(n);'
00075   template<typename _Tp, bool>
00076     struct _Array_default_ctor
00077     {
00078       // Please note that this isn't exception safe.  But
00079       // valarrays aren't required to be exception safe.
00080       inline static void
00081       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
00082       {
00083     while (__b != __e)
00084       new(__b++) _Tp();
00085       }
00086     };
00087 
00088   template<typename _Tp>
00089     struct _Array_default_ctor<_Tp, true>
00090     {
00091       // For fundamental types, it suffices to say 'memset()'
00092       inline static void
00093       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
00094       { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
00095     };
00096 
00097   template<typename _Tp>
00098     inline void
00099     __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
00100     {
00101       _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e);
00102     }
00103 
00104   // Turn a raw-memory into an array of _Tp filled with __t
00105   // This is the required in valarray<T> v(n, t).  Also
00106   // used in valarray<>::resize().
00107   template<typename _Tp, bool>
00108     struct _Array_init_ctor
00109     {
00110       // Please note that this isn't exception safe.  But
00111       // valarrays aren't required to be exception safe.
00112       inline static void
00113       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
00114       {
00115     while (__b != __e)
00116       new(__b++) _Tp(__t);
00117       }
00118     };
00119 
00120   template<typename _Tp>
00121     struct _Array_init_ctor<_Tp, true>
00122     {
00123       inline static void
00124       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e,  const _Tp __t)
00125       {
00126     while (__b != __e)
00127       *__b++ = __t;
00128       }
00129     };
00130 
00131   template<typename _Tp>
00132     inline void
00133     __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
00134                   const _Tp __t)
00135     {
00136       _Array_init_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e, __t);
00137     }
00138 
00139   //
00140   // copy-construct raw array [__o, *) from plain array [__b, __e)
00141   // We can't just say 'memcpy()'
00142   //
00143   template<typename _Tp, bool>
00144     struct _Array_copy_ctor
00145     {
00146       // Please note that this isn't exception safe.  But
00147       // valarrays aren't required to be exception safe.
00148       inline static void
00149       _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
00150            _Tp* __restrict__ __o)
00151       {
00152     while (__b != __e)
00153       new(__o++) _Tp(*__b++);
00154       }
00155     };
00156 
00157   template<typename _Tp>
00158     struct _Array_copy_ctor<_Tp, true>
00159     {
00160       inline static void
00161       _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
00162            _Tp* __restrict__ __o)
00163       { __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); }
00164     };
00165 
00166   template<typename _Tp>
00167     inline void
00168     __valarray_copy_construct(const _Tp* __restrict__ __b,
00169                   const _Tp* __restrict__ __e,
00170                   _Tp* __restrict__ __o)
00171     {
00172       _Array_copy_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e, __o);
00173     }
00174 
00175   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
00176   template<typename _Tp>
00177     inline void
00178     __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
00179                    size_t __s, _Tp* __restrict__ __o)
00180     {
00181       if (__is_pod(_Tp))
00182     while (__n--)
00183       {
00184         *__o++ = *__a;
00185         __a += __s;
00186       }
00187       else
00188     while (__n--)
00189       {
00190         new(__o++) _Tp(*__a);
00191         __a += __s;
00192       }
00193     }
00194 
00195   // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
00196   template<typename _Tp>
00197     inline void
00198     __valarray_copy_construct (const _Tp* __restrict__ __a,
00199                    const size_t* __restrict__ __i,
00200                    _Tp* __restrict__ __o, size_t __n)
00201     {
00202       if (__is_pod(_Tp))
00203     while (__n--)
00204       *__o++ = __a[*__i++];
00205       else
00206     while (__n--)
00207       new (__o++) _Tp(__a[*__i++]);
00208     }
00209 
00210   // Do the necessary cleanup when we're done with arrays.
00211   template<typename _Tp>
00212     inline void
00213     __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
00214     {
00215       if (!__is_pod(_Tp))
00216     while (__b != __e)
00217       {
00218         __b->~_Tp();
00219         ++__b;
00220       }
00221     }
00222 
00223   // Fill a plain array __a[<__n>] with __t
00224   template<typename _Tp>
00225     inline void
00226     __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
00227     {
00228       while (__n--)
00229     *__a++ = __t;
00230     }
00231   
00232   // fill strided array __a[<__n-1 : __s>] with __t
00233   template<typename _Tp>
00234     inline void
00235     __valarray_fill(_Tp* __restrict__ __a, size_t __n,
00236             size_t __s, const _Tp& __t)
00237     { 
00238       for (size_t __i = 0; __i < __n; ++__i, __a += __s)
00239     *__a = __t;
00240     }
00241 
00242   // fill indirect array __a[__i[<__n>]] with __i
00243   template<typename _Tp>
00244     inline void
00245     __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
00246             size_t __n, const _Tp& __t)
00247     {
00248       for (size_t __j = 0; __j < __n; ++__j, ++__i)
00249     __a[*__i] = __t;
00250     }
00251   
00252   // copy plain array __a[<__n>] in __b[<__n>]
00253   // For non-fundamental types, it is wrong to say 'memcpy()'
00254   template<typename _Tp, bool>
00255     struct _Array_copier
00256     {
00257       inline static void
00258       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
00259       {
00260     while(__n--)
00261       *__b++ = *__a++;
00262       }
00263     };
00264 
00265   template<typename _Tp>
00266     struct _Array_copier<_Tp, true>
00267     {
00268       inline static void
00269       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
00270       { __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); }
00271     };
00272 
00273   // Copy a plain array __a[<__n>] into a play array __b[<>]
00274   template<typename _Tp>
00275     inline void
00276     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
00277             _Tp* __restrict__ __b)
00278     {
00279       _Array_copier<_Tp, __is_pod(_Tp)>::_S_do_it(__a, __n, __b);
00280     }
00281 
00282   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
00283   template<typename _Tp>
00284     inline void
00285     __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
00286             _Tp* __restrict__ __b)
00287     {
00288       for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
00289     *__b = *__a;
00290     }
00291 
00292   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
00293   template<typename _Tp>
00294     inline void
00295     __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
00296             size_t __n, size_t __s)
00297     {
00298       for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
00299     *__b = *__a;
00300     }
00301 
00302   // Copy strided array __src[<__n : __s1>] into another
00303   // strided array __dst[< : __s2>].  Their sizes must match.
00304   template<typename _Tp>
00305     inline void
00306     __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
00307             _Tp* __restrict__ __dst, size_t __s2)
00308     {
00309       for (size_t __i = 0; __i < __n; ++__i)
00310     __dst[__i * __s2] = __src[__i * __s1];
00311     }
00312 
00313   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
00314   template<typename _Tp>
00315     inline void
00316     __valarray_copy(const _Tp* __restrict__ __a,
00317             const size_t* __restrict__ __i,
00318             _Tp* __restrict__ __b, size_t __n)
00319     {
00320       for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
00321     *__b = __a[*__i];
00322     }
00323 
00324   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
00325   template<typename _Tp>
00326     inline void
00327     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
00328             _Tp* __restrict__ __b, const size_t* __restrict__ __i)
00329     {
00330       for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
00331     __b[*__i] = *__a;
00332     }
00333 
00334   // Copy the __n first elements of an indexed array __src[<__i>] into
00335   // another indexed array __dst[<__j>].
00336   template<typename _Tp>
00337     inline void
00338     __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
00339             const size_t* __restrict__ __i,
00340             _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
00341     {
00342       for (size_t __k = 0; __k < __n; ++__k)
00343     __dst[*__j++] = __src[*__i++];
00344     }
00345 
00346   //
00347   // Compute the sum of elements in range [__f, __l)
00348   // This is a naive algorithm.  It suffers from cancelling.
00349   // In the future try to specialize
00350   // for _Tp = float, double, long double using a more accurate
00351   // algorithm.
00352   //
00353   template<typename _Tp>
00354     inline _Tp
00355     __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
00356     {
00357       _Tp __r = _Tp();
00358       while (__f != __l)
00359     __r += *__f++;
00360       return __r;
00361     }
00362 
00363   // Compute the product of all elements in range [__f, __l)
00364   template<typename _Tp>
00365     inline _Tp
00366     __valarray_product(const _Tp* __restrict__ __f,
00367                const _Tp* __restrict__ __l)
00368     {
00369       _Tp __r = _Tp(1);
00370       while (__f != __l)
00371     __r = __r * *__f++;
00372       return __r;
00373     }
00374 
00375   // Compute the min/max of an array-expression
00376   template<typename _Ta>
00377     inline typename _Ta::value_type
00378     __valarray_min(const _Ta& __a)
00379     {
00380       size_t __s = __a.size();
00381       typedef typename _Ta::value_type _Value_type;
00382       _Value_type __r = __s == 0 ? _Value_type() : __a[0];
00383       for (size_t __i = 1; __i < __s; ++__i)
00384     {
00385       _Value_type __t = __a[__i];
00386       if (__t < __r)
00387         __r = __t;
00388     }
00389       return __r;
00390     }
00391 
00392   template<typename _Ta>
00393     inline typename _Ta::value_type
00394     __valarray_max(const _Ta& __a)
00395     {
00396       size_t __s = __a.size();
00397       typedef typename _Ta::value_type _Value_type;
00398       _Value_type __r = __s == 0 ? _Value_type() : __a[0];
00399       for (size_t __i = 1; __i < __s; ++__i)
00400     {
00401       _Value_type __t = __a[__i];
00402       if (__t > __r)
00403         __r = __t;
00404     }
00405       return __r;
00406     }
00407 
00408   //
00409   // Helper class _Array, first layer of valarray abstraction.
00410   // All operations on valarray should be forwarded to this class
00411   // whenever possible. -- gdr
00412   //
00413 
00414   template<typename _Tp>
00415     struct _Array
00416     {
00417       explicit _Array(size_t);
00418       explicit _Array(_Tp* const __restrict__);
00419       explicit _Array(const valarray<_Tp>&);
00420       _Array(const _Tp* __restrict__, size_t);
00421       
00422       _Tp* begin() const;
00423       
00424       _Tp* const __restrict__ _M_data;
00425     };
00426 
00427 
00428   // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]]
00429   template<typename _Tp>
00430     inline void
00431     __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i,
00432                   _Array<_Tp> __b, size_t __n)
00433     { std::__valarray_copy_construct(__a._M_data, __i._M_data,
00434                      __b._M_data, __n); }
00435 
00436   // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>]
00437   template<typename _Tp>
00438     inline void
00439     __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s,
00440                   _Array<_Tp> __b)
00441     { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); }
00442 
00443   template<typename _Tp>
00444     inline void
00445     __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
00446     { std::__valarray_fill(__a._M_data, __n, __t); }
00447 
00448   template<typename _Tp>
00449     inline void
00450     __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
00451     { std::__valarray_fill(__a._M_data, __n, __s, __t); }
00452 
00453   template<typename _Tp>
00454     inline void
00455     __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
00456             size_t __n, const _Tp& __t)
00457     { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
00458 
00459   // Copy a plain array __a[<__n>] into a play array __b[<>]
00460   template<typename _Tp>
00461     inline void
00462     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
00463     { std::__valarray_copy(__a._M_data, __n, __b._M_data); }
00464 
00465   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
00466   template<typename _Tp>
00467     inline void
00468     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
00469     { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
00470 
00471   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
00472   template<typename _Tp>
00473     inline void
00474     __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
00475     { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
00476 
00477   // Copy strided array __src[<__n : __s1>] into another
00478   // strided array __dst[< : __s2>].  Their sizes must match.
00479   template<typename _Tp>
00480     inline void
00481     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
00482                     _Array<_Tp> __b, size_t __s2)
00483     { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
00484 
00485   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
00486   template<typename _Tp>
00487     inline void
00488     __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
00489             _Array<_Tp> __b, size_t __n)
00490     { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
00491 
00492   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
00493   template<typename _Tp>
00494     inline void
00495     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
00496             _Array<size_t> __i)
00497     { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
00498 
00499   // Copy the __n first elements of an indexed array __src[<__i>] into
00500   // another indexed array __dst[<__j>].
00501   template<typename _Tp>
00502     inline void
00503     __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
00504                     _Array<_Tp> __dst, _Array<size_t> __j)
00505     {
00506       std::__valarray_copy(__src._M_data, __n, __i._M_data,
00507             __dst._M_data, __j._M_data);
00508     }
00509 
00510   template<typename _Tp>
00511     inline
00512     _Array<_Tp>::_Array(size_t __n)
00513     : _M_data(__valarray_get_storage<_Tp>(__n))
00514     { std::__valarray_default_construct(_M_data, _M_data + __n); }
00515 
00516   template<typename _Tp>
00517     inline
00518     _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
00519     : _M_data (__p) {}
00520 
00521   template<typename _Tp>
00522     inline
00523     _Array<_Tp>::_Array(const valarray<_Tp>& __v)
00524     : _M_data (__v._M_data) {}
00525 
00526   template<typename _Tp>
00527     inline
00528     _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
00529     : _M_data(__valarray_get_storage<_Tp>(__s))
00530     { std::__valarray_copy_construct(__b, __s, _M_data); }
00531 
00532   template<typename _Tp>
00533     inline _Tp*
00534     _Array<_Tp>::begin () const
00535     { return _M_data; }
00536 
00537 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)              \
00538   template<typename _Tp>                            \
00539     inline void                             \
00540     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
00541     {                                   \
00542       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p)  \
00543         *__p _Op##= __t;                        \
00544     }                                   \
00545                                     \
00546   template<typename _Tp>                        \
00547     inline void                             \
00548     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
00549     {                                   \
00550       _Tp* __p = __a._M_data;                       \
00551       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
00552         *__p _Op##= *__q;                       \
00553     }                                   \
00554                                     \
00555   template<typename _Tp, class _Dom>                    \
00556     void                                \
00557     _Array_augmented_##_Name(_Array<_Tp> __a,                   \
00558                              const _Expr<_Dom, _Tp>& __e, size_t __n)   \
00559     {                                   \
00560       _Tp* __p(__a._M_data);                        \
00561       for (size_t __i = 0; __i < __n; ++__i, ++__p)                     \
00562         *__p _Op##= __e[__i];                                           \
00563     }                                   \
00564                                     \
00565   template<typename _Tp>                        \
00566     inline void                             \
00567     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s,   \
00568                          _Array<_Tp> __b)               \
00569     {                                   \
00570       _Tp* __q(__b._M_data);                        \
00571       for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n;       \
00572        __p += __s, ++__q)                                           \
00573         *__p _Op##= *__q;                       \
00574     }                                   \
00575                                     \
00576   template<typename _Tp>                        \
00577     inline void                             \
00578     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b,      \
00579                      size_t __n, size_t __s)            \
00580     {                                   \
00581       _Tp* __q(__b._M_data);                        \
00582       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
00583        ++__p, __q += __s)                                           \
00584         *__p _Op##= *__q;                       \
00585     }                                   \
00586                                     \
00587   template<typename _Tp, class _Dom>                    \
00588     void                                \
00589     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s,       \
00590                              const _Expr<_Dom, _Tp>& __e, size_t __n)   \
00591     {                                   \
00592       _Tp* __p(__a._M_data);                        \
00593       for (size_t __i = 0; __i < __n; ++__i, __p += __s)                \
00594         *__p _Op##= __e[__i];                                           \
00595     }                                   \
00596                                     \
00597   template<typename _Tp>                        \
00598     inline void                             \
00599     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,   \
00600                              _Array<_Tp> __b, size_t __n)       \
00601     {                                   \
00602       _Tp* __q(__b._M_data);                        \
00603       for (size_t* __j = __i._M_data; __j < __i._M_data + __n;          \
00604            ++__j, ++__q)                                                \
00605         __a._M_data[*__j] _Op##= *__q;                  \
00606     }                                   \
00607                                     \
00608   template<typename _Tp>                        \
00609     inline void                                 \
00610     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,       \
00611                              _Array<_Tp> __b, _Array<size_t> __i)   \
00612     {                                   \
00613       _Tp* __p(__a._M_data);                        \
00614       for (size_t* __j = __i._M_data; __j<__i._M_data + __n;            \
00615        ++__j, ++__p)                                                \
00616         *__p _Op##= __b._M_data[*__j];                  \
00617     }                                   \
00618                                     \
00619   template<typename _Tp, class _Dom>                    \
00620     void                                \
00621     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,   \
00622                              const _Expr<_Dom, _Tp>& __e, size_t __n)   \
00623     {                                   \
00624       size_t* __j(__i._M_data);                         \
00625       for (size_t __k = 0; __k<__n; ++__k, ++__j)           \
00626         __a._M_data[*__j] _Op##= __e[__k];              \
00627     }                                   \
00628                                     \
00629   template<typename _Tp>                        \
00630     void                                \
00631     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,         \
00632                              _Array<_Tp> __b, size_t __n)       \
00633     {                                   \
00634       bool* __ok(__m._M_data);                      \
00635       _Tp* __p(__a._M_data);                        \
00636       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;             \
00637        ++__q, ++__ok, ++__p)                                        \
00638         {                                                               \
00639           while (! *__ok)                                               \
00640             {                                   \
00641               ++__ok;                           \
00642               ++__p;                            \
00643             }                               \
00644           *__p _Op##= *__q;                     \
00645         }                               \
00646     }                                   \
00647                                     \
00648   template<typename _Tp>                        \
00649     void                                \
00650     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,       \
00651                              _Array<_Tp> __b, _Array<bool> __m)     \
00652     {                                   \
00653       bool* __ok(__m._M_data);                      \
00654       _Tp* __q(__b._M_data);                        \
00655       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
00656        ++__p, ++__ok, ++__q)                                        \
00657         {                                                               \
00658           while (! *__ok)                                               \
00659             {                                   \
00660               ++__ok;                           \
00661               ++__q;                            \
00662             }                               \
00663           *__p _Op##= *__q;                     \
00664         }                               \
00665     }                                   \
00666                                     \
00667   template<typename _Tp, class _Dom>                    \
00668     void                                \
00669     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,     \
00670                              const _Expr<_Dom, _Tp>& __e, size_t __n)   \
00671     {                                   \
00672       bool* __ok(__m._M_data);                      \
00673       _Tp* __p(__a._M_data);                        \
00674       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)             \
00675         {                                                   \
00676           while (! *__ok)                                               \
00677             {                                   \
00678           ++__ok;                           \
00679               ++__p;                            \
00680             }                               \
00681           *__p _Op##= __e[__i];                     \
00682         }                               \
00683     }
00684 
00685    _DEFINE_ARRAY_FUNCTION(+, __plus)
00686    _DEFINE_ARRAY_FUNCTION(-, __minus)
00687    _DEFINE_ARRAY_FUNCTION(*, __multiplies)
00688    _DEFINE_ARRAY_FUNCTION(/, __divides)
00689    _DEFINE_ARRAY_FUNCTION(%, __modulus)
00690    _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
00691    _DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
00692    _DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
00693    _DEFINE_ARRAY_FUNCTION(<<, __shift_left)
00694    _DEFINE_ARRAY_FUNCTION(>>, __shift_right)
00695 
00696 #undef _DEFINE_ARRAY_FUNCTION
00697 
00698 _GLIBCXX_END_NAMESPACE
00699 
00700 #ifndef _GLIBCXX_EXPORT_TEMPLATE
00701 # include <bits/valarray_array.tcc>
00702 #endif
00703 
00704 #endif /* _ARRAY_H */

Generated on Wed Mar 26 00:43:28 2008 for libstdc++ by  doxygen 1.5.1