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