Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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