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