home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / valarray < prev    next >
Text File  |  2005-01-29  |  35KB  |  1,018 lines

  1. // The template and inlines for the -*- C++ -*- valarray class.
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
  4. // Free Software Foundation, Inc.
  5. //
  6. // This file is part of the GNU ISO C++ Library.  This library is free
  7. // software; you can redistribute it and/or modify it under the
  8. // terms of the GNU General Public License as published by the
  9. // Free Software Foundation; either version 2, or (at your option)
  10. // any later version.
  11.  
  12. // This library is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16.  
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING.  If not, write to the Free
  19. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20. // USA.
  21.  
  22. // As a special exception, you may use this file as part of a free software
  23. // library without restriction.  Specifically, if other files instantiate
  24. // templates or use macros or inline functions from this file, or you compile
  25. // this file and link it with other files to produce an executable, this
  26. // file does not by itself cause the resulting executable to be covered by
  27. // the GNU General Public License.  This exception does not however
  28. // invalidate any other reasons why the executable file might be covered by
  29. // the GNU General Public License.
  30.  
  31. // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
  32.  
  33. /** @file valarray
  34.  *  This is a Standard C++ Library header.  You should @c #include this header
  35.  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
  36.  */
  37.  
  38. #ifndef _GLIBCXX_VALARRAY
  39. #define _GLIBCXX_VALARRAY 1
  40.  
  41. #pragma GCC system_header
  42.  
  43. #include <bits/c++config.h>
  44. #include <cstddef>
  45. #include <cmath>
  46. #include <cstdlib>
  47. #include <numeric>
  48. #include <algorithm>
  49. #include <debug/debug.h>
  50.  
  51. namespace std
  52. {
  53.   template<class _Clos, typename _Tp> 
  54.     class _Expr;
  55.  
  56.   template<typename _Tp1, typename _Tp2> 
  57.     class _ValArray;    
  58.  
  59.   template<class _Oper, template<class, class> class _Meta, class _Dom>
  60.     struct _UnClos;
  61.  
  62.   template<class _Oper,
  63.         template<class, class> class _Meta1,
  64.         template<class, class> class _Meta2,
  65.         class _Dom1, class _Dom2> 
  66.     class _BinClos;
  67.  
  68.   template<template<class, class> class _Meta, class _Dom> 
  69.     class _SClos;
  70.  
  71.   template<template<class, class> class _Meta, class _Dom> 
  72.     class _GClos;
  73.     
  74.   template<template<class, class> class _Meta, class _Dom> 
  75.     class _IClos;
  76.     
  77.   template<template<class, class> class _Meta, class _Dom> 
  78.     class _ValFunClos;
  79.   
  80.   template<template<class, class> class _Meta, class _Dom> 
  81.     class _RefFunClos;
  82.  
  83.   template<class _Tp> class valarray;   // An array of type _Tp
  84.   class slice;                          // BLAS-like slice out of an array
  85.   template<class _Tp> class slice_array;
  86.   class gslice;                         // generalized slice out of an array
  87.   template<class _Tp> class gslice_array;
  88.   template<class _Tp> class mask_array;     // masked array
  89.   template<class _Tp> class indirect_array; // indirected array
  90.  
  91. } // namespace std
  92.  
  93. #include <bits/valarray_array.h>
  94. #include <bits/valarray_before.h>
  95.   
  96. namespace std
  97. {
  98.   /**
  99.    *  @brief  Smart array designed to support numeric processing.
  100.    *
  101.    *  A valarray is an array that provides constraints intended to allow for
  102.    *  effective optimization of numeric array processing by reducing the
  103.    *  aliasing that can result from pointer representations.  It represents a
  104.    *  one-dimensional array from which different multidimensional subsets can
  105.    *  be accessed and modified.
  106.    *  
  107.    *  @param  Tp  Type of object in the array.
  108.    */
  109.   template<class _Tp> 
  110.     class valarray
  111.     {
  112.       template<class _Op>
  113.     struct _UnaryOp 
  114.     {
  115.       typedef typename __fun<_Op, _Tp>::result_type __rt;
  116.       typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
  117.     };
  118.     public:
  119.       typedef _Tp value_type;
  120.       
  121.     // _lib.valarray.cons_ construct/destroy:
  122.       ///  Construct an empty array.
  123.       valarray();
  124.  
  125.       ///  Construct an array with @a n elements.
  126.       explicit valarray(size_t);
  127.  
  128.       ///  Construct an array with @a n elements initialized to @a t.
  129.       valarray(const _Tp&, size_t);
  130.  
  131.       ///  Construct an array initialized to the first @a n elements of @a t.
  132.       valarray(const _Tp* __restrict__, size_t);
  133.  
  134.       ///  Copy constructor.
  135.       valarray(const valarray&);
  136.  
  137.       ///  Construct an array with the same size and values in @a sa.
  138.       valarray(const slice_array<_Tp>&);
  139.  
  140.       ///  Construct an array with the same size and values in @a ga.
  141.       valarray(const gslice_array<_Tp>&);
  142.  
  143.       ///  Construct an array with the same size and values in @a ma.
  144.       valarray(const mask_array<_Tp>&);
  145.  
  146.       ///  Construct an array with the same size and values in @a ia.
  147.       valarray(const indirect_array<_Tp>&);
  148.  
  149.       template<class _Dom>
  150.     valarray(const _Expr<_Dom,_Tp>& __e);
  151.       ~valarray();
  152.  
  153.       // _lib.valarray.assign_ assignment:
  154.       /**
  155.        *  @brief  Assign elements to an array.
  156.        *
  157.        *  Assign elements of array to values in @a v.  Results are undefined
  158.        *  if @a v is not the same size as this array.
  159.        *
  160.        *  @param  v  Valarray to get values from.
  161.        */
  162.       valarray<_Tp>& operator=(const valarray<_Tp>&);
  163.  
  164.       /**
  165.        *  @brief  Assign elements to a value.
  166.        *
  167.        *  Assign all elements of array to @a t.
  168.        *
  169.        *  @param  t  Value for elements.
  170.        */
  171.       valarray<_Tp>& operator=(const _Tp&);
  172.  
  173.       /**
  174.        *  @brief  Assign elements to an array subset.
  175.        *
  176.        *  Assign elements of array to values in @a sa.  Results are undefined
  177.        *  if @a sa is not the same size as this array.
  178.        *
  179.        *  @param  sa  Array slice to get values from.
  180.        */
  181.       valarray<_Tp>& operator=(const slice_array<_Tp>&);
  182.  
  183.       /**
  184.        *  @brief  Assign elements to an array subset.
  185.        *
  186.        *  Assign elements of array to values in @a ga.  Results are undefined
  187.        *  if @a ga is not the same size as this array.
  188.        *
  189.        *  @param  ga  Array slice to get values from.
  190.        */
  191.       valarray<_Tp>& operator=(const gslice_array<_Tp>&);
  192.  
  193.       /**
  194.        *  @brief  Assign elements to an array subset.
  195.        *
  196.        *  Assign elements of array to values in @a ma.  Results are undefined
  197.        *  if @a ma is not the same size as this array.
  198.        *
  199.        *  @param  ma  Array slice to get values from.
  200.        */
  201.       valarray<_Tp>& operator=(const mask_array<_Tp>&);
  202.  
  203.       /**
  204.        *  @brief  Assign elements to an array subset.
  205.        *
  206.        *  Assign elements of array to values in @a ia.  Results are undefined
  207.        *  if @a ia is not the same size as this array.
  208.        *
  209.        *  @param  ia  Array slice to get values from.
  210.        */
  211.       valarray<_Tp>& operator=(const indirect_array<_Tp>&);
  212.  
  213.       template<class _Dom> valarray<_Tp>&
  214.     operator= (const _Expr<_Dom,_Tp>&);
  215.  
  216.       // _lib.valarray.access_ element access:
  217.       /**
  218.        *  Return a reference to the i'th array element.  
  219.        *
  220.        *  @param  i  Index of element to return.
  221.        *  @return  Reference to the i'th element.
  222.        */
  223.       _Tp&                operator[](size_t);
  224.  
  225.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  226.       // 389. Const overload of valarray::operator[] returns by value.
  227.       const _Tp&          operator[](size_t) const;
  228.  
  229.       // _lib.valarray.sub_ subset operations:
  230.       /**
  231.        *  @brief  Return an array subset.
  232.        *
  233.        *  Returns a new valarray containing the elements of the array
  234.        *  indicated by the slice argument.  The new valarray is the size of
  235.        *  the input slice.  @see slice.
  236.        *
  237.        *  @param  s  The source slice.
  238.        *  @return  New valarray containing elements in @a s.
  239.        */
  240.       _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
  241.  
  242.       /**
  243.        *  @brief  Return a reference to an array subset.
  244.        *
  245.        *  Returns a new valarray containing the elements of the array
  246.        *  indicated by the slice argument.  The new valarray is the size of
  247.        *  the input slice.  @see slice.
  248.        *
  249.        *  @param  s  The source slice.
  250.        *  @return  New valarray containing elements in @a s.
  251.        */
  252.       slice_array<_Tp>    operator[](slice);
  253.  
  254.       /**
  255.        *  @brief  Return an array subset.
  256.        *
  257.        *  Returns a slice_array referencing the elements of the array
  258.        *  indicated by the slice argument.  @see gslice.
  259.        *
  260.        *  @param  s  The source slice.
  261.        *  @return  Slice_array referencing elements indicated by @a s.
  262.        */
  263.       _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
  264.  
  265.       /**
  266.        *  @brief  Return a reference to an array subset.
  267.        *
  268.        *  Returns a new valarray containing the elements of the array
  269.        *  indicated by the gslice argument.  The new valarray is
  270.        *  the size of the input gslice.  @see gslice.
  271.        *
  272.        *  @param  s  The source gslice.
  273.        *  @return  New valarray containing elements in @a s.
  274.        */
  275.       gslice_array<_Tp>   operator[](const gslice&);
  276.  
  277.       /**
  278.        *  @brief  Return an array subset.
  279.        *
  280.        *  Returns a new valarray containing the elements of the array
  281.        *  indicated by the argument.  The input is a valarray of bool which
  282.        *  represents a bitmask indicating which elements should be copied into
  283.        *  the new valarray.  Each element of the array is added to the return
  284.        *  valarray if the corresponding element of the argument is true.
  285.        *
  286.        *  @param  m  The valarray bitmask.
  287.        *  @return  New valarray containing elements indicated by @a m.
  288.        */
  289.       valarray<_Tp>          operator[](const valarray<bool>&) const;
  290.  
  291.       /**
  292.        *  @brief  Return a reference to an array subset.
  293.        *
  294.        *  Returns a new mask_array referencing the elements of the array
  295.        *  indicated by the argument.  The input is a valarray of bool which
  296.        *  represents a bitmask indicating which elements are part of the
  297.        *  subset.  Elements of the array are part of the subset if the
  298.        *  corresponding element of the argument is true.
  299.        *
  300.        *  @param  m  The valarray bitmask.
  301.        *  @return  New valarray containing elements indicated by @a m.
  302.        */
  303.       mask_array<_Tp>     operator[](const valarray<bool>&);
  304.  
  305.       /**
  306.        *  @brief  Return an array subset.
  307.        *
  308.        *  Returns a new valarray containing the elements of the array
  309.        *  indicated by the argument.  The elements in the argument are
  310.        *  interpreted as the indices of elements of this valarray to copy to
  311.        *  the return valarray.
  312.        *
  313.        *  @param  i  The valarray element index list.
  314.        *  @return  New valarray containing elements in @a s.
  315.        */
  316.       _Expr<_IClos<_ValArray, _Tp>, _Tp>
  317.         operator[](const valarray<size_t>&) const;
  318.  
  319.       /**
  320.        *  @brief  Return a reference to an array subset.
  321.        *
  322.        *  Returns an indirect_array referencing the elements of the array
  323.        *  indicated by the argument.  The elements in the argument are
  324.        *  interpreted as the indices of elements of this valarray to include
  325.        *  in the subset.  The returned indirect_array refers to these
  326.        *  elements.
  327.        *
  328.        *  @param  i  The valarray element index list.
  329.        *  @return  Indirect_array referencing elements in @a i.
  330.        */
  331.       indirect_array<_Tp> operator[](const valarray<size_t>&);
  332.  
  333.       // _lib.valarray.unary_ unary operators:
  334.       ///  Return a new valarray by applying unary + to each element.
  335.       typename _UnaryOp<__unary_plus>::_Rt  operator+() const;
  336.  
  337.       ///  Return a new valarray by applying unary - to each element.
  338.       typename _UnaryOp<__negate>::_Rt      operator-() const;
  339.  
  340.       ///  Return a new valarray by applying unary ~ to each element.
  341.       typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
  342.  
  343.       ///  Return a new valarray by applying unary ! to each element.
  344.       typename _UnaryOp<__logical_not>::_Rt operator!() const;
  345.  
  346.       // _lib.valarray.cassign_ computed assignment:
  347.       ///  Multiply each element of array by @a t.
  348.       valarray<_Tp>& operator*=(const _Tp&);
  349.  
  350.       ///  Divide each element of array by @a t.
  351.       valarray<_Tp>& operator/=(const _Tp&);
  352.  
  353.       ///  Set each element e of array to e % @a t.
  354.       valarray<_Tp>& operator%=(const _Tp&);
  355.  
  356.       ///  Add @a t to each element of array.
  357.       valarray<_Tp>& operator+=(const _Tp&);
  358.  
  359.       ///  Subtract @a t to each element of array.
  360.       valarray<_Tp>& operator-=(const _Tp&);
  361.  
  362.       ///  Set each element e of array to e ^ @a t.
  363.       valarray<_Tp>& operator^=(const _Tp&);
  364.  
  365.       ///  Set each element e of array to e & @a t.
  366.       valarray<_Tp>& operator&=(const _Tp&);
  367.  
  368.       ///  Set each element e of array to e | @a t.
  369.       valarray<_Tp>& operator|=(const _Tp&);
  370.  
  371.       ///  Left shift each element e of array by @a t bits.
  372.       valarray<_Tp>& operator<<=(const _Tp&);
  373.  
  374.       ///  Right shift each element e of array by @a t bits.
  375.       valarray<_Tp>& operator>>=(const _Tp&);
  376.  
  377.       ///  Multiply elements of array by corresponding elements of @a v.
  378.       valarray<_Tp>& operator*=(const valarray<_Tp>&);
  379.  
  380.       ///  Divide elements of array by corresponding elements of @a v.
  381.       valarray<_Tp>& operator/=(const valarray<_Tp>&);
  382.  
  383.       ///  Modulo elements of array by corresponding elements of @a v.
  384.       valarray<_Tp>& operator%=(const valarray<_Tp>&);
  385.  
  386.       ///  Add corresponding elements of @a v to elements of array.
  387.       valarray<_Tp>& operator+=(const valarray<_Tp>&);
  388.  
  389.       ///  Subtract corresponding elements of @a v from elements of array.
  390.       valarray<_Tp>& operator-=(const valarray<_Tp>&);
  391.  
  392.       ///  Logical xor corresponding elements of @a v with elements of array.
  393.       valarray<_Tp>& operator^=(const valarray<_Tp>&);
  394.  
  395.       ///  Logical or corresponding elements of @a v with elements of array.
  396.       valarray<_Tp>& operator|=(const valarray<_Tp>&);
  397.  
  398.       ///  Logical and corresponding elements of @a v with elements of array.
  399.       valarray<_Tp>& operator&=(const valarray<_Tp>&);
  400.  
  401.       ///  Left shift elements of array by corresponding elements of @a v.
  402.       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
  403.  
  404.       ///  Right shift elements of array by corresponding elements of @a v.
  405.       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
  406.  
  407.       template<class _Dom>
  408.     valarray<_Tp>& operator*=(const _Expr<_Dom,_Tp>&);
  409.       template<class _Dom>
  410.     valarray<_Tp>& operator/=(const _Expr<_Dom,_Tp>&);
  411.       template<class _Dom>
  412.     valarray<_Tp>& operator%=(const _Expr<_Dom,_Tp>&);
  413.       template<class _Dom>
  414.     valarray<_Tp>& operator+=(const _Expr<_Dom,_Tp>&);
  415.       template<class _Dom>
  416.     valarray<_Tp>& operator-=(const _Expr<_Dom,_Tp>&);
  417.       template<class _Dom>
  418.     valarray<_Tp>& operator^=(const _Expr<_Dom,_Tp>&);
  419.       template<class _Dom>
  420.     valarray<_Tp>& operator|=(const _Expr<_Dom,_Tp>&);
  421.       template<class _Dom>
  422.     valarray<_Tp>& operator&=(const _Expr<_Dom,_Tp>&);
  423.       template<class _Dom>
  424.       valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
  425.       template<class _Dom>
  426.     valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
  427.  
  428.  
  429.       // _lib.valarray.members_ member functions:
  430.       ///  Return the number of elements in array.
  431.       size_t size() const;
  432.  
  433.       /**
  434.        *  @brief  Return the sum of all elements in the array.
  435.        *
  436.        *  Accumulates the sum of all elements into a Tp using +=.  The order
  437.        *  of adding the elements is unspecified.
  438.        */
  439.       _Tp    sum() const;
  440.  
  441.       ///  Return the minimum element using operator<().
  442.       _Tp    min() const;    
  443.  
  444.       ///  Return the maximum element using operator<().
  445.       _Tp    max() const;    
  446.  
  447.   //           // FIXME: Extension
  448.   //       _Tp    product () const;
  449.  
  450.       /**
  451.        *  @brief  Return a shifted array.
  452.        *
  453.        *  A new valarray is constructed as a copy of this array with elements
  454.        *  in shifted positions.  For an element with index i, the new position
  455.        *  is i - n.  The new valarray is the same size as the current one.
  456.        *  New elements without a value are set to 0.  Elements whos new
  457.        *  position is outside the bounds of the array are discarded.
  458.        *
  459.        *  Positive arguments shift toward index 0, discarding elements [0, n).
  460.        *  Negative arguments discard elements from the top of the array.
  461.        *
  462.        *  @param  n  Number of element positions to shift.
  463.        *  @return  New valarray with elements in shifted positions.
  464.        */
  465.       valarray<_Tp> shift (int) const;
  466.  
  467.       /**
  468.        *  @brief  Return a rotated array.
  469.        *
  470.        *  A new valarray is constructed as a copy of this array with elements
  471.        *  in shifted positions.  For an element with index i, the new position
  472.        *  is (i - n) % size().  The new valarray is the same size as the
  473.        *  current one.  Elements that are shifted beyond the array bounds are
  474.        *  shifted into the other end of the array.  No elements are lost.
  475.        *
  476.        *  Positive arguments shift toward index 0, wrapping around the top.
  477.        *  Negative arguments shift towards the top, wrapping around to 0.
  478.        *
  479.        *  @param  n  Number of element positions to rotate.
  480.        *  @return  New valarray with elements in shifted positions.
  481.        */
  482.       valarray<_Tp> cshift(int) const;
  483.  
  484.       /**
  485.        *  @brief  Apply a function to the array.
  486.        *
  487.        *  Returns a new valarray with elements assigned to the result of
  488.        *  applying func to the corresponding element of this array.  The new
  489.        *  array is the same size as this one.
  490.        *
  491.        *  @param  func  Function of Tp returning Tp to apply.
  492.        *  @return  New valarray with transformed elements.
  493.        */
  494.       _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
  495.  
  496.       /**
  497.        *  @brief  Apply a function to the array.
  498.        *
  499.        *  Returns a new valarray with elements assigned to the result of
  500.        *  applying func to the corresponding element of this array.  The new
  501.        *  array is the same size as this one.
  502.        *
  503.        *  @param  func  Function of const Tp& returning Tp to apply.
  504.        *  @return  New valarray with transformed elements.
  505.        */
  506.       _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
  507.  
  508.       /**
  509.        *  @brief  Resize array.
  510.        *
  511.        *  Resize this array to be @a size and set all elements to @a c.  All
  512.        *  references and iterators are invalidated.
  513.        *
  514.        *  @param  size  New array size.
  515.        *  @param  c  New value for all elements.
  516.        */
  517.       void resize(size_t __size, _Tp __c = _Tp());
  518.  
  519.     private:
  520.       size_t _M_size;
  521.       _Tp* __restrict__ _M_data;
  522.       
  523.       friend class _Array<_Tp>;
  524.     };
  525.   
  526.   template<typename _Tp>
  527.     inline const _Tp&
  528.     valarray<_Tp>::operator[](size_t __i) const
  529.     { 
  530.       __glibcxx_requires_subscript(__i);
  531.       return _M_data[__i]; 
  532.     }
  533.  
  534.   template<typename _Tp>
  535.     inline _Tp&
  536.     valarray<_Tp>::operator[](size_t __i)
  537.     { 
  538.       __glibcxx_requires_subscript(__i);
  539.       return _M_data[__i]; 
  540.     }
  541.  
  542. } // std::
  543.  
  544. #include <bits/valarray_after.h>
  545.  
  546. #include <bits/slice_array.h>
  547. #include <bits/gslice.h>
  548. #include <bits/gslice_array.h>
  549. #include <bits/mask_array.h>
  550. #include <bits/indirect_array.h>
  551.  
  552. namespace std
  553. {
  554.   template<typename _Tp>
  555.     inline
  556.     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
  557.  
  558.   template<typename _Tp>
  559.     inline 
  560.     valarray<_Tp>::valarray(size_t __n) 
  561.     : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  562.     { std::__valarray_default_construct(_M_data, _M_data + __n); }
  563.  
  564.   template<typename _Tp>
  565.     inline
  566.     valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
  567.       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  568.     { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
  569.  
  570.   template<typename _Tp>
  571.     inline
  572.     valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
  573.       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
  574.     { 
  575.       _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
  576.       std::__valarray_copy_construct(__p, __p + __n, _M_data); 
  577.     }
  578.  
  579.   template<typename _Tp>
  580.     inline
  581.     valarray<_Tp>::valarray(const valarray<_Tp>& __v)
  582.       : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
  583.     { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); }
  584.  
  585.   template<typename _Tp>
  586.     inline
  587.     valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
  588.       : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
  589.     {
  590.       std::__valarray_copy
  591.     (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
  592.     }
  593.  
  594.   template<typename _Tp>
  595.     inline
  596.     valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
  597.       : _M_size(__ga._M_index.size()),
  598.     _M_data(__valarray_get_storage<_Tp>(_M_size))
  599.     {
  600.       std::__valarray_copy
  601.     (__ga._M_array, _Array<size_t>(__ga._M_index),
  602.      _Array<_Tp>(_M_data), _M_size);
  603.     }
  604.  
  605.   template<typename _Tp>
  606.     inline
  607.     valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
  608.       : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
  609.     {
  610.       std::__valarray_copy
  611.     (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
  612.     }
  613.  
  614.   template<typename _Tp>
  615.     inline
  616.     valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
  617.       : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
  618.     {
  619.       std::__valarray_copy
  620.     (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
  621.     }
  622.  
  623.   template<typename _Tp> template<class _Dom>
  624.     inline
  625.     valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
  626.       : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
  627.     { std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); }
  628.  
  629.   template<typename _Tp>
  630.     inline
  631.     valarray<_Tp>::~valarray()
  632.     {
  633.       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  634.       std::__valarray_release_memory(_M_data);
  635.     }
  636.  
  637.   template<typename _Tp>
  638.     inline valarray<_Tp>&
  639.     valarray<_Tp>::operator=(const valarray<_Tp>& __v)
  640.     {
  641.       _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);
  642.       std::__valarray_copy(__v._M_data, _M_size, _M_data);
  643.       return *this;
  644.     }
  645.  
  646.   template<typename _Tp>
  647.     inline valarray<_Tp>&
  648.     valarray<_Tp>::operator=(const _Tp& __t)
  649.     {
  650.       std::__valarray_fill(_M_data, _M_size, __t);
  651.       return *this;
  652.     }
  653.  
  654.   template<typename _Tp>
  655.     inline valarray<_Tp>&
  656.     valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
  657.     {
  658.       _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
  659.       std::__valarray_copy(__sa._M_array, __sa._M_sz,
  660.                __sa._M_stride, _Array<_Tp>(_M_data));
  661.       return *this;
  662.     }
  663.  
  664.   template<typename _Tp>
  665.     inline valarray<_Tp>&
  666.     valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
  667.     {
  668.       _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
  669.       std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
  670.                _Array<_Tp>(_M_data), _M_size);
  671.       return *this;
  672.     }
  673.  
  674.   template<typename _Tp>
  675.     inline valarray<_Tp>&
  676.     valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
  677.     {
  678.       _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
  679.       std::__valarray_copy(__ma._M_array, __ma._M_mask,
  680.                _Array<_Tp>(_M_data), _M_size);
  681.       return *this;
  682.     }
  683.  
  684.   template<typename _Tp>
  685.     inline valarray<_Tp>&
  686.     valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
  687.     {
  688.       _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
  689.       std::__valarray_copy(__ia._M_array, __ia._M_index,
  690.                _Array<_Tp>(_M_data), _M_size);
  691.       return *this;
  692.     }
  693.  
  694.   template<typename _Tp> template<class _Dom>
  695.     inline valarray<_Tp>&
  696.     valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
  697.     {
  698.       _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
  699.       std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
  700.       return *this;
  701.     }
  702.  
  703.   template<typename _Tp>
  704.     inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
  705.     valarray<_Tp>::operator[](slice __s) const
  706.     {
  707.       typedef _SClos<_ValArray,_Tp> _Closure;
  708.       return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
  709.     }
  710.  
  711.   template<typename _Tp>
  712.     inline slice_array<_Tp>
  713.     valarray<_Tp>::operator[](slice __s)
  714.     {
  715.       return slice_array<_Tp>(_Array<_Tp>(_M_data), __s);
  716.     }
  717.  
  718.   template<typename _Tp>
  719.     inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
  720.     valarray<_Tp>::operator[](const gslice& __gs) const
  721.     {
  722.       typedef _GClos<_ValArray,_Tp> _Closure;
  723.       return _Expr<_Closure, _Tp>
  724.     (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
  725.     }
  726.  
  727.   template<typename _Tp>
  728.     inline gslice_array<_Tp>
  729.     valarray<_Tp>::operator[](const gslice& __gs)
  730.     {
  731.       return gslice_array<_Tp>
  732.     (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
  733.     }
  734.  
  735.   template<typename _Tp>
  736.     inline valarray<_Tp>
  737.     valarray<_Tp>::operator[](const valarray<bool>& __m) const
  738.     {
  739.       size_t __s = 0;
  740.       size_t __e = __m.size();
  741.       for (size_t __i=0; __i<__e; ++__i)
  742.     if (__m[__i]) ++__s;
  743.       return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
  744.                        _Array<bool> (__m)));
  745.     }
  746.  
  747.   template<typename _Tp>
  748.     inline mask_array<_Tp>
  749.     valarray<_Tp>::operator[](const valarray<bool>& __m)
  750.     {
  751.       size_t __s = 0;
  752.       size_t __e = __m.size();
  753.       for (size_t __i=0; __i<__e; ++__i)
  754.     if (__m[__i]) ++__s;
  755.       return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
  756.     }
  757.  
  758.   template<typename _Tp>
  759.     inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
  760.     valarray<_Tp>::operator[](const valarray<size_t>& __i) const
  761.     {
  762.       typedef _IClos<_ValArray,_Tp> _Closure;
  763.       return _Expr<_Closure, _Tp>(_Closure(*this, __i));
  764.     }
  765.  
  766.   template<typename _Tp>
  767.     inline indirect_array<_Tp>
  768.     valarray<_Tp>::operator[](const valarray<size_t>& __i)
  769.     {
  770.       return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
  771.                  _Array<size_t>(__i));
  772.     }
  773.  
  774.   template<class _Tp>
  775.     inline size_t 
  776.     valarray<_Tp>::size() const
  777.     { return _M_size; }
  778.  
  779.   template<class _Tp>
  780.     inline _Tp
  781.     valarray<_Tp>::sum() const
  782.     {
  783.       _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
  784.       return std::__valarray_sum(_M_data, _M_data + _M_size);
  785.     }
  786.  
  787. //   template<typename _Tp>
  788. //   inline _Tp
  789. //   valarray<_Tp>::product () const
  790. //   {
  791. //       return __valarray_product(_M_data, _M_data + _M_size);
  792. //   }
  793.  
  794.   template <class _Tp>
  795.      inline valarray<_Tp>
  796.      valarray<_Tp>::shift(int __n) const
  797.      {
  798.        _Tp* const __a = static_cast<_Tp*>
  799.          (__builtin_alloca(sizeof(_Tp) * _M_size));
  800.        if (__n == 0)                          // no shift
  801.          std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
  802.        else if (__n > 0)         // __n > 0: shift left
  803.          {                 
  804.            if (size_t(__n) > _M_size)
  805.              std::__valarray_default_construct(__a, __a + __n);
  806.            else
  807.              {
  808.                std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
  809.                std::__valarray_default_construct(__a+_M_size-__n, __a + _M_size);
  810.              }
  811.          }
  812.        else                        // __n < 0: shift right
  813.          {                          
  814.            std::__valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
  815.            std::__valarray_default_construct(__a, __a - __n);
  816.          }
  817.        return valarray<_Tp> (__a, _M_size);
  818.      }
  819.  
  820.   template <class _Tp>
  821.      inline valarray<_Tp>
  822.      valarray<_Tp>::cshift (int __n) const
  823.      {
  824.        _Tp* const __a = static_cast<_Tp*>
  825.          (__builtin_alloca (sizeof(_Tp) * _M_size));
  826.        if (__n == 0)               // no cshift
  827.          std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
  828.        else if (__n > 0)           // cshift left
  829.          {               
  830.            std::__valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
  831.            std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
  832.          }
  833.        else                        // cshift right
  834.          {                       
  835.            std::__valarray_copy_construct
  836.              (_M_data + _M_size+__n, _M_data + _M_size, __a);
  837.            std::__valarray_copy_construct
  838.              (_M_data, _M_data + _M_size+__n, __a - __n);
  839.          }
  840.        return valarray<_Tp>(__a, _M_size);
  841.      }
  842.  
  843.   template <class _Tp>
  844.     inline void
  845.     valarray<_Tp>::resize (size_t __n, _Tp __c)
  846.     {
  847.       // This complication is so to make valarray<valarray<T> > work
  848.       // even though it is not required by the standard.  Nobody should
  849.       // be saying valarray<valarray<T> > anyway.  See the specs.
  850.       std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
  851.       if (_M_size != __n)
  852.     {
  853.       std::__valarray_release_memory(_M_data);
  854.       _M_size = __n;
  855.       _M_data = __valarray_get_storage<_Tp>(__n);
  856.     }
  857.       std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
  858.     }
  859.     
  860.   template<typename _Tp>
  861.     inline _Tp
  862.     valarray<_Tp>::min() const
  863.     {
  864.       _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
  865.       return *std::min_element (_M_data, _M_data+_M_size);
  866.     }
  867.  
  868.   template<typename _Tp>
  869.     inline _Tp
  870.     valarray<_Tp>::max() const
  871.     {
  872.       _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
  873.       return *std::max_element (_M_data, _M_data+_M_size);
  874.     }
  875.   
  876.   template<class _Tp>
  877.     inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
  878.     valarray<_Tp>::apply(_Tp func(_Tp)) const
  879.     {
  880.       typedef _ValFunClos<_ValArray,_Tp> _Closure;
  881.       return _Expr<_Closure,_Tp>(_Closure(*this, func));
  882.     }
  883.  
  884.   template<class _Tp>
  885.     inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
  886.     valarray<_Tp>::apply(_Tp func(const _Tp &)) const
  887.     {
  888.       typedef _RefFunClos<_ValArray,_Tp> _Closure;
  889.       return _Expr<_Closure,_Tp>(_Closure(*this, func));
  890.     }
  891.  
  892. #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
  893.   template<typename _Tp>                        \
  894.   inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt             \
  895.   valarray<_Tp>::operator _Op() const                    \
  896.   {                                    \
  897.     typedef _UnClos<_Name,_ValArray,_Tp> _Closure;                    \
  898.     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
  899.     return _Expr<_Closure, _Rt>(_Closure(*this));            \
  900.   }
  901.  
  902.     _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
  903.     _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
  904.     _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
  905.     _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
  906.  
  907. #undef _DEFINE_VALARRAY_UNARY_OPERATOR
  908.  
  909. #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
  910.   template<class _Tp>                            \
  911.     inline valarray<_Tp>&                        \
  912.     valarray<_Tp>::operator _Op##=(const _Tp &__t)            \
  913.     {                                    \
  914.       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t);    \
  915.       return *this;                            \
  916.     }                                    \
  917.                                     \
  918.   template<class _Tp>                            \
  919.     inline valarray<_Tp>&                        \
  920.     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)        \
  921.     {                                    \
  922.       _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);                    \
  923.       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size,         \
  924.                    _Array<_Tp>(__v._M_data));        \
  925.       return *this;                            \
  926.     }
  927.  
  928. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
  929. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
  930. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
  931. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
  932. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
  933. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
  934. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
  935. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
  936. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
  937. _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
  938.  
  939. #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
  940.  
  941. #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
  942.   template<class _Tp> template<class _Dom>                \
  943.     inline valarray<_Tp>&                        \
  944.     valarray<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e)        \
  945.     {                                    \
  946.       _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size);    \
  947.       return *this;                            \
  948.     }
  949.  
  950. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
  951. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
  952. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
  953. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
  954. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
  955. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
  956. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
  957. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
  958. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
  959. _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
  960.  
  961. #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
  962.     
  963.  
  964. #define _DEFINE_BINARY_OPERATOR(_Op, _Name)                \
  965.   template<typename _Tp>                        \
  966.     inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,           \
  967.                  typename __fun<_Name, _Tp>::result_type>               \
  968.     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \
  969.     {                                    \
  970.       _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size());                  \
  971.       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
  972.       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
  973.       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
  974.     }                                    \
  975.                                     \
  976.   template<typename _Tp>                        \
  977.   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,             \
  978.                typename __fun<_Name, _Tp>::result_type>                 \
  979.   operator _Op(const valarray<_Tp>& __v, const _Tp& __t)        \
  980.   {                                    \
  981.     typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;    \
  982.     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
  983.     return _Expr<_Closure, _Rt>(_Closure(__v, __t));                    \
  984.   }                                    \
  985.                                     \
  986.   template<typename _Tp>                        \
  987.   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,             \
  988.                typename __fun<_Name, _Tp>::result_type>                 \
  989.   operator _Op(const _Tp& __t, const valarray<_Tp>& __v)        \
  990.   {                                    \
  991.     typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;       \
  992.     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
  993.     return _Expr<_Closure, _Tp>(_Closure(__t, __v));                    \
  994.   }
  995.  
  996. _DEFINE_BINARY_OPERATOR(+, __plus)
  997. _DEFINE_BINARY_OPERATOR(-, __minus)
  998. _DEFINE_BINARY_OPERATOR(*, __multiplies)
  999. _DEFINE_BINARY_OPERATOR(/, __divides)
  1000. _DEFINE_BINARY_OPERATOR(%, __modulus)
  1001. _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
  1002. _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
  1003. _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
  1004. _DEFINE_BINARY_OPERATOR(<<, __shift_left)
  1005. _DEFINE_BINARY_OPERATOR(>>, __shift_right)
  1006. _DEFINE_BINARY_OPERATOR(&&, __logical_and)
  1007. _DEFINE_BINARY_OPERATOR(||, __logical_or)
  1008. _DEFINE_BINARY_OPERATOR(==, __equal_to)
  1009. _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
  1010. _DEFINE_BINARY_OPERATOR(<, __less)
  1011. _DEFINE_BINARY_OPERATOR(>, __greater)
  1012. _DEFINE_BINARY_OPERATOR(<=, __less_equal)
  1013. _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
  1014.  
  1015. } // namespace std
  1016.  
  1017. #endif /* _GLIBCXX_VALARRAY */
  1018.