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