Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // The template and inlines for the -*- C++ -*- valarray class.
  2.  
  3. // Copyright (C) 1997-1999, 2000, 2001 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. #ifndef _CPP_VALARRAY
  33. #define _CPP_VALARRAY 1
  34.  
  35. #pragma GCC system_header
  36.  
  37. #include <bits/c++config.h>
  38. #include <bits/std_cstddef.h>
  39. #include <bits/std_cmath.h>
  40. #include <bits/std_cstdlib.h>
  41. #include <bits/std_numeric.h>
  42. #include <bits/std_functional.h>
  43. #include <bits/std_algorithm.h>
  44.  
  45. namespace std
  46. {
  47.     template<class _Clos, typename _Tp> class _Expr;
  48.  
  49.     template<typename _Tp1, typename _Tp2> class _ValArray;    
  50.  
  51.     template<template<class> class _Oper,
  52.         template<class, class> class _Meta, class _Dom> struct _UnClos;
  53.  
  54.     template<template<class> class _Oper,
  55.         template<class, class> class _Meta1,
  56.         template<class, class> class _Meta2,
  57.         class _Dom1, class _Dom2> class _BinClos;
  58.  
  59.     template<template<class, class> class _Meta, class _Dom> class _SClos;
  60.  
  61.     template<template<class, class> class _Meta, class _Dom> class _GClos;
  62.    
  63.     template<template<class, class> class _Meta, class _Dom> class _IClos;
  64.    
  65.     template<template<class, class> class _Meta, class _Dom> class _ValFunClos;
  66.  
  67.     template<template<class, class> class _Meta, class _Dom> class _RefFunClos;
  68.  
  69.     template<class _Tp> struct _Unary_plus;
  70.     template<class _Tp> struct _Bitwise_and;
  71.     template<class _Tp> struct _Bitwise_or;
  72.     template<class _Tp> struct _Bitwise_xor;  
  73.     template<class _Tp> struct _Bitwise_not;
  74.     template<class _Tp> struct _Shift_left;
  75.     template<class _Tp> struct _Shift_right;
  76.  
  77.     template<class _Tp> class valarray;   // An array of type _Tp
  78.     class slice;                          // BLAS-like slice out of an array
  79.     template<class _Tp> class slice_array;
  80.     class gslice;                         // generalized slice out of an array
  81.     template<class _Tp> class gslice_array;
  82.     template<class _Tp> class mask_array;     // masked array
  83.     template<class _Tp> class indirect_array; // indirected array
  84.  
  85. } // namespace std
  86.  
  87. #include <bits/valarray_array.h>
  88. #include <bits/valarray_meta.h>
  89.  
  90. namespace std
  91. {
  92.   template<class _Tp> class valarray
  93.   {
  94.   public:
  95.       typedef _Tp value_type;
  96.  
  97.       // _lib.valarray.cons_ construct/destroy:
  98.       valarray();
  99.       explicit valarray(size_t);
  100.       valarray(const _Tp&, size_t);
  101.       valarray(const _Tp* __restrict__, size_t);
  102.       valarray(const valarray&);
  103.       valarray(const slice_array<_Tp>&);
  104.       valarray(const gslice_array<_Tp>&);
  105.       valarray(const mask_array<_Tp>&);
  106.       valarray(const indirect_array<_Tp>&);
  107.       template<class _Dom>
  108.       valarray(const _Expr<_Dom,_Tp>& __e);
  109.      ~valarray();
  110.  
  111.       // _lib.valarray.assign_ assignment:
  112.       valarray<_Tp>& operator=(const valarray<_Tp>&);
  113.       valarray<_Tp>& operator=(const _Tp&);
  114.       valarray<_Tp>& operator=(const slice_array<_Tp>&);
  115.       valarray<_Tp>& operator=(const gslice_array<_Tp>&);
  116.       valarray<_Tp>& operator=(const mask_array<_Tp>&);
  117.       valarray<_Tp>& operator=(const indirect_array<_Tp>&);
  118.  
  119.       template<class _Dom> valarray<_Tp>&
  120.         operator= (const _Expr<_Dom,_Tp>&);
  121.  
  122.       // _lib.valarray.access_ element access:
  123.       // XXX: LWG to be resolved.
  124.       const _Tp&                 operator[](size_t) const;
  125.       _Tp&                operator[](size_t);          
  126.       // _lib.valarray.sub_ subset operations:
  127.       _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
  128.       slice_array<_Tp>    operator[](slice);
  129.       _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
  130.       gslice_array<_Tp>   operator[](const gslice&);
  131.       valarray<_Tp>              operator[](const valarray<bool>&) const;
  132.       mask_array<_Tp>     operator[](const valarray<bool>&);
  133.       _Expr<_IClos<_ValArray, _Tp>, _Tp>
  134.         operator[](const valarray<size_t>&) const;
  135.       indirect_array<_Tp> operator[](const valarray<size_t>&);
  136.  
  137.       // _lib.valarray.unary_ unary operators:
  138.       _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp>  operator+ () const;
  139.       _Expr<_UnClos<negate,_ValArray,_Tp>,_Tp> operator- () const;
  140.       _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const;
  141.       _Expr<_UnClos<logical_not,_ValArray,_Tp>,bool> operator! () const;
  142.      
  143.       // _lib.valarray.cassign_ computed assignment:
  144.       valarray<_Tp>& operator*= (const _Tp&);
  145.       valarray<_Tp>& operator/= (const _Tp&);
  146.       valarray<_Tp>& operator%= (const _Tp&);
  147.       valarray<_Tp>& operator+= (const _Tp&);
  148.       valarray<_Tp>& operator-= (const _Tp&);
  149.       valarray<_Tp>& operator^= (const _Tp&);
  150.       valarray<_Tp>& operator&= (const _Tp&);
  151.       valarray<_Tp>& operator|= (const _Tp&);
  152.       valarray<_Tp>& operator<<=(const _Tp&);
  153.       valarray<_Tp>& operator>>=(const _Tp&);
  154.       valarray<_Tp>& operator*= (const valarray<_Tp>&);
  155.       valarray<_Tp>& operator/= (const valarray<_Tp>&);
  156.       valarray<_Tp>& operator%= (const valarray<_Tp>&);
  157.       valarray<_Tp>& operator+= (const valarray<_Tp>&);
  158.       valarray<_Tp>& operator-= (const valarray<_Tp>&);
  159.       valarray<_Tp>& operator^= (const valarray<_Tp>&);
  160.       valarray<_Tp>& operator|= (const valarray<_Tp>&);
  161.       valarray<_Tp>& operator&= (const valarray<_Tp>&);
  162.       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
  163.       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
  164.  
  165.       template<class _Dom>
  166.         valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&);
  167.       template<class _Dom>
  168.         valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&);
  169.       template<class _Dom>
  170.         valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&);
  171.       template<class _Dom>
  172.         valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&);
  173.       template<class _Dom>
  174.         valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&);
  175.       template<class _Dom>
  176.         valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&);
  177.       template<class _Dom>
  178.         valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&);
  179.       template<class _Dom>
  180.         valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&);
  181.       template<class _Dom>
  182.         valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
  183.       template<class _Dom>
  184.         valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
  185.  
  186.      
  187.       // _lib.valarray.members_ member functions:
  188.       size_t size() const;
  189.       _Tp    sum() const;      
  190.       _Tp    min() const;      
  191.       _Tp    max() const;      
  192.  
  193. //           // FIXME: Extension
  194. //       _Tp    product () const;
  195.  
  196.       valarray<_Tp> shift (int) const;
  197.       valarray<_Tp> cshift(int) const;
  198.       _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
  199.       _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
  200.       void resize(size_t __size, _Tp __c = _Tp());
  201.  
  202.   private:
  203.       size_t _M_size;
  204.       _Tp* __restrict__ _M_data;
  205.  
  206.       friend class _Array<_Tp>;
  207.   };
  208.  
  209.  
  210.   template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> {
  211.       _Tp operator() (const _Tp& __t) const { return __t; }
  212.   };
  213.  
  214.   template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> {
  215.       _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; }
  216.   };
  217.  
  218.   template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> {
  219.       _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; }
  220.   };
  221.  
  222.   template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> {
  223.       _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; }
  224.   };
  225.  
  226.   template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> {
  227.       _Tp operator() (_Tp __t) const { return ~__t; }
  228.   };
  229.  
  230.   template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> {
  231.       _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; }
  232.   };
  233.  
  234.   template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> {
  235.       _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; }
  236.   };
  237.  
  238.  
  239.   template<typename _Tp>
  240.   inline const _Tp&
  241.   valarray<_Tp>::operator[] (size_t __i) const
  242.   { return _M_data[__i]; }
  243.  
  244.   template<typename _Tp>
  245.   inline _Tp&
  246.   valarray<_Tp>::operator[] (size_t __i)
  247.   { return _M_data[__i]; }
  248.  
  249. } // std::
  250.      
  251. #include <bits/slice.h>
  252. #include <bits/slice_array.h>
  253. #include <bits/gslice.h>
  254. #include <bits/gslice_array.h>
  255. #include <bits/mask_array.h>
  256. #include <bits/indirect_array.h>
  257.  
  258. namespace std
  259. {
  260.   template<typename _Tp>
  261.   inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {}
  262.  
  263.   template<typename _Tp>
  264.   inline valarray<_Tp>::valarray (size_t __n)
  265.       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  266.   { __valarray_default_construct(_M_data, _M_data + __n); }
  267.  
  268.   template<typename _Tp>
  269.   inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n)
  270.     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  271.   { __valarray_fill_construct (_M_data, _M_data + __n, __t); }
  272.  
  273.   template<typename _Tp>
  274.   inline valarray<_Tp>::valarray (const _Tp* __restrict__ __p, size_t __n)
  275.     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  276.   { __valarray_copy_construct (__p, __p + __n, _M_data); }
  277.  
  278.   template<typename _Tp>
  279.   inline valarray<_Tp>::valarray (const valarray<_Tp>& __v)
  280.     : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
  281.   { __valarray_copy_construct (__v._M_data, __v._M_data + _M_size, _M_data); }
  282.  
  283.   template<typename _Tp>
  284.   inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa)
  285.     : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
  286.   {
  287.     __valarray_copy
  288.       (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
  289.   }
  290.  
  291.   template<typename _Tp>
  292.   inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga)
  293.     : _M_size(__ga._M_index.size()),
  294.       _M_data(__valarray_get_storage<_Tp>(_M_size))
  295.   {
  296.     __valarray_copy
  297.       (__ga._M_array, _Array<size_t>(__ga._M_index),
  298.        _Array<_Tp>(_M_data), _M_size);
  299.   }
  300.  
  301.   template<typename _Tp>
  302.   inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma)
  303.     : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
  304.   {
  305.     __valarray_copy
  306.       (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
  307.   }
  308.  
  309.   template<typename _Tp>
  310.   inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia)
  311.     : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
  312.   {
  313.     __valarray_copy
  314.       (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
  315.   }
  316.  
  317.   template<typename _Tp> template<class _Dom>
  318.   inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e)
  319.     : _M_size(__e.size ()), _M_data(__valarray_get_storage<_Tp>(_M_size))
  320.   { __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); }
  321.  
  322.   template<typename _Tp>
  323.   inline valarray<_Tp>::~valarray ()
  324.   {
  325.       __valarray_destroy_elements(_M_data, _M_data + _M_size);
  326.       __valarray_release_memory(_M_data);
  327.   }
  328.  
  329.   template<typename _Tp>
  330.   inline valarray<_Tp>&
  331.   valarray<_Tp>::operator= (const valarray<_Tp>& __v)
  332.   {
  333.       __valarray_copy(__v._M_data, _M_size, _M_data);
  334.       return *this;
  335.   }
  336.  
  337.   template<typename _Tp>
  338.   inline valarray<_Tp>&
  339.   valarray<_Tp>::operator= (const _Tp& __t)
  340.   {
  341.       __valarray_fill (_M_data, _M_size, __t);
  342.       return *this;
  343.   }
  344.  
  345.   template<typename _Tp>
  346.   inline valarray<_Tp>&
  347.   valarray<_Tp>::operator= (const slice_array<_Tp>& __sa)
  348.   {
  349.       __valarray_copy (__sa._M_array, __sa._M_sz,
  350.               __sa._M_stride, _Array<_Tp>(_M_data));
  351.       return *this;
  352.   }
  353.  
  354.   template<typename _Tp>
  355.   inline valarray<_Tp>&
  356.   valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga)
  357.   {
  358.       __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index),
  359.               _Array<_Tp>(_M_data), _M_size);
  360.       return *this;
  361.   }
  362.  
  363.   template<typename _Tp>
  364.   inline valarray<_Tp>&
  365.   valarray<_Tp>::operator= (const mask_array<_Tp>& __ma)
  366.   {
  367.       __valarray_copy (__ma._M_array, __ma._M_mask,
  368.               _Array<_Tp>(_M_data), _M_size);
  369.       return *this;
  370.   }
  371.  
  372.   template<typename _Tp>
  373.   inline valarray<_Tp>&
  374.   valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia)
  375.   {
  376.       __valarray_copy (__ia._M_array, __ia._M_index,
  377.                _Array<_Tp>(_M_data), _M_size);
  378.       return *this;
  379.   }
  380.  
  381.   template<typename _Tp> template<class _Dom>
  382.   inline valarray<_Tp>&
  383.   valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e)
  384.   {
  385.       __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data));
  386.       return *this;
  387.   }
  388.  
  389.   template<typename _Tp>
  390.   inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
  391.   valarray<_Tp>::operator[] (slice __s) const
  392.   {
  393.       typedef _SClos<_ValArray,_Tp> _Closure;
  394.       return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s));
  395.   }
  396.  
  397.   template<typename _Tp>
  398.   inline slice_array<_Tp>
  399.   valarray<_Tp>::operator[] (slice __s)
  400.   {
  401.       return slice_array<_Tp> (_Array<_Tp>(_M_data), __s);
  402.   }
  403.  
  404.   template<typename _Tp>
  405.   inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
  406.   valarray<_Tp>::operator[] (const gslice& __gs) const
  407.   {
  408.       typedef _GClos<_ValArray,_Tp> _Closure;
  409.       return _Expr<_Closure, _Tp>
  410.           (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index));
  411.   }
  412.  
  413.   template<typename _Tp>
  414.   inline gslice_array<_Tp>
  415.   valarray<_Tp>::operator[] (const gslice& __gs)
  416.   {
  417.       return gslice_array<_Tp>
  418.           (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
  419.   }
  420.  
  421.   template<typename _Tp>
  422.   inline valarray<_Tp>
  423.   valarray<_Tp>::operator[] (const valarray<bool>& __m) const
  424.   {
  425.       size_t __s (0);
  426.       size_t __e (__m.size ());
  427.       for (size_t __i=0; __i<__e; ++__i)
  428.           if (__m[__i]) ++__s;
  429.       return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s,
  430.                                          _Array<bool> (__m)));
  431.   }
  432.  
  433.   template<typename _Tp>
  434.   inline mask_array<_Tp>
  435.   valarray<_Tp>::operator[] (const valarray<bool>& __m)
  436.   {
  437.       size_t __s (0);
  438.       size_t __e (__m.size ());
  439.       for (size_t __i=0; __i<__e; ++__i)
  440.           if (__m[__i]) ++__s;
  441.       return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array<bool> (__m));
  442.   }
  443.  
  444.   template<typename _Tp>
  445.   inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
  446.   valarray<_Tp>::operator[] (const valarray<size_t>& __i) const
  447.   {
  448.       typedef _IClos<_ValArray,_Tp> _Closure;
  449.       return _Expr<_Closure, _Tp> (_Closure (*this, __i));
  450.   }
  451.  
  452.   template<typename _Tp>
  453.   inline indirect_array<_Tp>
  454.   valarray<_Tp>::operator[] (const valarray<size_t>& __i)
  455.   {
  456.       return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(),
  457.                                 _Array<size_t> (__i));
  458.   }
  459.  
  460.   template<class _Tp>
  461.   inline size_t valarray<_Tp>::size () const { return _M_size; }
  462.  
  463.   template<class _Tp>
  464.   inline _Tp
  465.   valarray<_Tp>::sum () const
  466.   {
  467.       return __valarray_sum(_M_data, _M_data + _M_size);
  468.   }
  469.  
  470. //   template<typename _Tp>
  471. //   inline _Tp
  472. //   valarray<_Tp>::product () const
  473. //   {
  474. //       return __valarray_product(_M_data, _M_data + _M_size);
  475. //   }
  476.  
  477.   template <class _Tp>
  478.      inline valarray<_Tp>
  479.      valarray<_Tp>::shift(int __n) const
  480.      {
  481.        _Tp* const __a = static_cast<_Tp*>
  482.          (__builtin_alloca(sizeof(_Tp) * _M_size));
  483.        if (__n == 0)                          // no shift
  484.          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
  485.        else if (__n > 0)         // __n > 0: shift left
  486.          {                
  487.            if (size_t(__n) > _M_size)
  488.              __valarray_default_construct(__a, __a + __n);
  489.            else
  490.              {
  491.                __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
  492.                __valarray_default_construct(__a+_M_size-__n, __a + _M_size);
  493.              }
  494.          }
  495.        else                        // __n < 0: shift right
  496.          {                          
  497.            __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
  498.            __valarray_default_construct(__a, __a - __n);
  499.          }
  500.        return valarray<_Tp> (__a, _M_size);
  501.      }
  502.  
  503.   template <class _Tp>
  504.      inline valarray<_Tp>
  505.      valarray<_Tp>::cshift (int __n) const
  506.      {
  507.        _Tp* const __a = static_cast<_Tp*>
  508.          (__builtin_alloca (sizeof(_Tp) * _M_size));
  509.        if (__n == 0)               // no cshift
  510.          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
  511.        else if (__n > 0)           // cshift left
  512.          {              
  513.            __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
  514.            __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
  515.          }
  516.        else                        // cshift right
  517.          {                      
  518.            __valarray_copy_construct
  519.              (_M_data + _M_size+__n, _M_data + _M_size, __a);
  520.            __valarray_copy_construct
  521.              (_M_data, _M_data + _M_size+__n, __a - __n);
  522.          }
  523.        return valarray<_Tp>(__a, _M_size);
  524.      }
  525.  
  526.   template <class _Tp>
  527.   inline void
  528.   valarray<_Tp>::resize (size_t __n, _Tp __c)
  529.   {
  530.     // This complication is so to make valarray<valarray<T> > work
  531.     // even though it is not required by the standard.  Nobody should
  532.     // be saying valarray<valarray<T> > anyway.  See the specs.
  533.     __valarray_destroy_elements(_M_data, _M_data + _M_size);
  534.     if (_M_size != __n)
  535.       {
  536.         __valarray_release_memory(_M_data);
  537.         _M_size = __n;
  538.         _M_data = __valarray_get_storage<_Tp>(__n);
  539.       }
  540.     __valarray_fill_construct(_M_data, _M_data + __n, __c);
  541.   }
  542.    
  543.   template<typename _Tp>
  544.   inline _Tp
  545.   valarray<_Tp>::min() const
  546.   {
  547.       return *min_element (_M_data, _M_data+_M_size);
  548.   }
  549.  
  550.   template<typename _Tp>
  551.   inline _Tp
  552.   valarray<_Tp>::max() const
  553.   {
  554.       return *max_element (_M_data, _M_data+_M_size);
  555.   }
  556.  
  557.   template<class _Tp>
  558.   inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
  559.   valarray<_Tp>::apply (_Tp func (_Tp)) const
  560.   {
  561.       typedef _ValFunClos<_ValArray,_Tp> _Closure;
  562.       return _Expr<_Closure,_Tp> (_Closure (*this, func));
  563.   }
  564.  
  565.   template<class _Tp>
  566.   inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
  567.   valarray<_Tp>::apply (_Tp func (const _Tp &)) const
  568.   {
  569.       typedef _RefFunClos<_ValArray,_Tp> _Closure;
  570.       return _Expr<_Closure,_Tp> (_Closure (*this, func));
  571.   }
  572.  
  573. #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
  574.   template<typename _Tp>                                                \
  575.   inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp>                       \
  576.   valarray<_Tp>::operator _Op() const                                   \
  577.   {                                                                     \
  578.       typedef _UnClos<_Name,_ValArray,_Tp> _Closure;                    \
  579.       return _Expr<_Closure, _Tp> (_Closure (*this));                   \
  580.   }
  581.  
  582.     _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus)
  583.     _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate)
  584.     _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not)
  585.  
  586. #undef _DEFINE_VALARRAY_UNARY_OPERATOR
  587.  
  588.   template<typename _Tp>
  589.   inline _Expr<_UnClos<logical_not,_ValArray,_Tp>, bool>
  590.   valarray<_Tp>::operator!() const
  591.   {
  592.       typedef _UnClos<logical_not,_ValArray,_Tp> _Closure;
  593.       return _Expr<_Closure, bool> (_Closure (*this));
  594.   }
  595.  
  596. #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
  597.   template<class _Tp>                                                   \
  598.   inline valarray<_Tp> &                                                \
  599.   valarray<_Tp>::operator _Op##= (const _Tp &__t)                       \
  600.   {                                                                     \
  601.       _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t);    \
  602.       return *this;                                                     \
  603.   }                                                                     \
  604.                                                                         \
  605.   template<class _Tp>                                                   \
  606.   inline valarray<_Tp> &                                                \
  607.   valarray<_Tp>::operator _Op##= (const valarray<_Tp> &__v)             \
  608.   {                                                                     \
  609.       _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size,          \
  610.                                _Array<_Tp>(__v._M_data));               \
  611.       return *this;                                                     \
  612.   }
  613.  
  614. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus)
  615. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus)
  616. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies)
  617. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides)
  618. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus)
  619. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor)
  620. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and)
  621. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or)
  622. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left)
  623. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right)
  624.  
  625. #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
  626.  
  627.  
  628. } // std::
  629.  
  630.  
  631. namespace std
  632. {
  633.  
  634. #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
  635.   template<class _Tp> template<class _Dom>                              \
  636.   inline valarray<_Tp> &                                                \
  637.   valarray<_Tp>::operator _Op##= (const _Expr<_Dom,_Tp> &__e)           \
  638.   {                                                                     \
  639.       _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size);    \
  640.       return *this;                                                     \
  641.   }
  642.  
  643. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus)
  644. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus)
  645. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies)
  646. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides)
  647. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus)
  648. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor)
  649. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and)
  650. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or)
  651. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left)
  652. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right)
  653.  
  654. #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
  655.    
  656.  
  657. #define _DEFINE_BINARY_OPERATOR(_Op, _Name)                             \
  658.   template<typename _Tp>                                                \
  659.   inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp>        \
  660.   operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w)     \
  661.   {                                                                     \
  662.       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
  663.       return _Expr<_Closure, _Tp> (_Closure (__v, __w));                \
  664.   }                                                                     \
  665.                                                                         \
  666.   template<typename _Tp>                                                \
  667.   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp>         \
  668.   operator _Op (const valarray<_Tp> &__v, const _Tp &__t)               \
  669.   {                                                                     \
  670.       typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;     \
  671.       return _Expr<_Closure, _Tp> (_Closure (__v, __t));                \
  672.   }                                                                     \
  673.                                                                         \
  674.   template<typename _Tp>                                                \
  675.   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp>         \
  676.   operator _Op (const _Tp &__t, const valarray<_Tp> &__v)               \
  677.   {                                                                     \
  678.       typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;     \
  679.       return _Expr<_Closure, _Tp> (_Closure (__t, __v));                \
  680.   }
  681.  
  682. _DEFINE_BINARY_OPERATOR(+, plus)
  683. _DEFINE_BINARY_OPERATOR(-, minus)
  684. _DEFINE_BINARY_OPERATOR(*, multiplies)
  685. _DEFINE_BINARY_OPERATOR(/, divides)
  686. _DEFINE_BINARY_OPERATOR(%, modulus)
  687. _DEFINE_BINARY_OPERATOR(^, _Bitwise_xor)
  688. _DEFINE_BINARY_OPERATOR(&, _Bitwise_and)
  689. _DEFINE_BINARY_OPERATOR(|, _Bitwise_or)
  690. _DEFINE_BINARY_OPERATOR(<<, _Shift_left)
  691. _DEFINE_BINARY_OPERATOR(>>, _Shift_right)
  692.  
  693. #undef _DEFINE_BINARY_OPERATOR
  694.  
  695. #define _DEFINE_LOGICAL_OPERATOR(_Op, _Name)                            \
  696.   template<typename _Tp>                                                \
  697.   inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool>        \
  698.   operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w)     \
  699.   {                                                                     \
  700.       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
  701.       return _Expr<_Closure, bool> (_Closure (__v, __w));               \
  702.   }                                                                     \
  703.                                                                         \
  704.   template<class _Tp>                                                   \
  705.   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool>        \
  706.   operator _Op (const valarray<_Tp> &__v, const _Tp &__t)               \
  707.   {                                                                     \
  708.       typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;     \
  709.       return _Expr<_Closure, bool> (_Closure (__v, __t));               \
  710.   }                                                                     \
  711.                                                                         \
  712.   template<class _Tp>                                                   \
  713.   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool>        \
  714.   operator _Op (const _Tp &__t, const valarray<_Tp> &__v)               \
  715.   {                                                                     \
  716.       typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;     \
  717.       return _Expr<_Closure, bool> (_Closure (__t, __v));               \
  718.   }
  719.  
  720. _DEFINE_LOGICAL_OPERATOR(&&, logical_and)
  721. _DEFINE_LOGICAL_OPERATOR(||, logical_or)
  722. _DEFINE_LOGICAL_OPERATOR(==, equal_to)
  723. _DEFINE_LOGICAL_OPERATOR(!=, not_equal_to)
  724. _DEFINE_LOGICAL_OPERATOR(<, less)
  725. _DEFINE_LOGICAL_OPERATOR(>, greater)
  726. _DEFINE_LOGICAL_OPERATOR(<=, less_equal)
  727. _DEFINE_LOGICAL_OPERATOR(>=, greater_equal)
  728.  
  729. #undef _DEFINE_LOGICAL_OPERATOR
  730.  
  731. } // namespace std
  732.  
  733. #endif // _CPP_VALARRAY
  734.  
  735. // Local Variables:
  736. // mode:c++
  737. // End:
  738.