home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 14 / hacker14.iso / programacao / cwin / c.exe / $INSTDIR / include / c++ / bits / valarray_array.h < prev    next >
Encoding:
C/C++ Source or Header  |  2003-12-15  |  20.6 KB  |  631 lines

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