xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/valarray (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
14fee23f9Smrg// The template and inlines for the -*- C++ -*- valarray class.
24fee23f9Smrg
3b1e83836Smrg// Copyright (C) 1997-2022 Free Software Foundation, Inc.
44fee23f9Smrg//
54fee23f9Smrg// This file is part of the GNU ISO C++ Library.  This library is free
64fee23f9Smrg// software; you can redistribute it and/or modify it under the
74fee23f9Smrg// terms of the GNU General Public License as published by the
84fee23f9Smrg// Free Software Foundation; either version 3, or (at your option)
94fee23f9Smrg// any later version.
104fee23f9Smrg
114fee23f9Smrg// This library is distributed in the hope that it will be useful,
124fee23f9Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144fee23f9Smrg// GNU General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg// Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg// permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg// 3.1, as published by the Free Software Foundation.
194fee23f9Smrg
204fee23f9Smrg// You should have received a copy of the GNU General Public License and
214fee23f9Smrg// a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
234fee23f9Smrg// <http://www.gnu.org/licenses/>.
244fee23f9Smrg
2548fb7bfaSmrg/** @file include/valarray
264fee23f9Smrg *  This is a Standard C++ Library header.
274fee23f9Smrg */
284fee23f9Smrg
294fee23f9Smrg// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
304fee23f9Smrg
314fee23f9Smrg#ifndef _GLIBCXX_VALARRAY
324fee23f9Smrg#define _GLIBCXX_VALARRAY 1
334fee23f9Smrg
344fee23f9Smrg#pragma GCC system_header
354fee23f9Smrg
364fee23f9Smrg#include <bits/c++config.h>
374fee23f9Smrg#include <cmath>
384fee23f9Smrg#include <algorithm>
394fee23f9Smrg#include <debug/debug.h>
4048fb7bfaSmrg#if __cplusplus >= 201103L
414fee23f9Smrg#include <initializer_list>
4248fb7bfaSmrg#endif
434fee23f9Smrg
4448fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default)
4548fb7bfaSmrg{
4648fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
474fee23f9Smrg
484fee23f9Smrg  template<class _Clos, typename _Tp>
494fee23f9Smrg    class _Expr;
504fee23f9Smrg
514fee23f9Smrg  template<typename _Tp1, typename _Tp2>
524fee23f9Smrg    class _ValArray;
534fee23f9Smrg
54181254a7Smrgnamespace __detail
55181254a7Smrg{
564fee23f9Smrg  template<class _Oper, template<class, class> class _Meta, class _Dom>
574fee23f9Smrg    struct _UnClos;
584fee23f9Smrg
594fee23f9Smrg  template<class _Oper,
604fee23f9Smrg        template<class, class> class _Meta1,
614fee23f9Smrg        template<class, class> class _Meta2,
624fee23f9Smrg        class _Dom1, class _Dom2>
63*0a307195Smrg    struct _BinClos;
644fee23f9Smrg
654fee23f9Smrg  template<template<class, class> class _Meta, class _Dom>
66*0a307195Smrg    struct _SClos;
674fee23f9Smrg
684fee23f9Smrg  template<template<class, class> class _Meta, class _Dom>
69*0a307195Smrg    struct _GClos;
704fee23f9Smrg
714fee23f9Smrg  template<template<class, class> class _Meta, class _Dom>
72*0a307195Smrg    struct _IClos;
734fee23f9Smrg
744fee23f9Smrg  template<template<class, class> class _Meta, class _Dom>
75*0a307195Smrg    struct _ValFunClos;
764fee23f9Smrg
774fee23f9Smrg  template<template<class, class> class _Meta, class _Dom>
78*0a307195Smrg    struct _RefFunClos;
79181254a7Smrg} // namespace __detail
80181254a7Smrg
81181254a7Smrg  using __detail::_UnClos;
82181254a7Smrg  using __detail::_BinClos;
83181254a7Smrg  using __detail::_SClos;
84181254a7Smrg  using __detail::_GClos;
85181254a7Smrg  using __detail::_IClos;
86181254a7Smrg  using __detail::_ValFunClos;
87181254a7Smrg  using __detail::_RefFunClos;
884fee23f9Smrg
894fee23f9Smrg  template<class _Tp> class valarray;   // An array of type _Tp
904fee23f9Smrg  class slice;                          // BLAS-like slice out of an array
914fee23f9Smrg  template<class _Tp> class slice_array;
924fee23f9Smrg  class gslice;                         // generalized slice out of an array
934fee23f9Smrg  template<class _Tp> class gslice_array;
944fee23f9Smrg  template<class _Tp> class mask_array;     // masked array
954fee23f9Smrg  template<class _Tp> class indirect_array; // indirected array
964fee23f9Smrg
9748fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION
9848fb7bfaSmrg} // namespace
994fee23f9Smrg
1004fee23f9Smrg#include <bits/valarray_array.h>
1014fee23f9Smrg#include <bits/valarray_before.h>
1024fee23f9Smrg
10348fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default)
10448fb7bfaSmrg{
10548fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
1064fee23f9Smrg
1074fee23f9Smrg  /**
1084fee23f9Smrg   * @defgroup numeric_arrays Numeric Arrays
1094fee23f9Smrg   * @ingroup numerics
1104fee23f9Smrg   *
1114fee23f9Smrg   * Classes and functions for representing and manipulating arrays of elements.
1124fee23f9Smrg   * @{
1134fee23f9Smrg   */
1144fee23f9Smrg
1154fee23f9Smrg  /**
1164fee23f9Smrg   *  @brief  Smart array designed to support numeric processing.
1174fee23f9Smrg   *
1184fee23f9Smrg   *  A valarray is an array that provides constraints intended to allow for
1194fee23f9Smrg   *  effective optimization of numeric array processing by reducing the
1204fee23f9Smrg   *  aliasing that can result from pointer representations.  It represents a
1214fee23f9Smrg   *  one-dimensional array from which different multidimensional subsets can
1224fee23f9Smrg   *  be accessed and modified.
1234fee23f9Smrg   *
12448fb7bfaSmrg   *  @tparam  _Tp  Type of object in the array.
1254fee23f9Smrg   */
1264fee23f9Smrg  template<class _Tp>
1274fee23f9Smrg    class valarray
1284fee23f9Smrg    {
1294fee23f9Smrg      template<class _Op>
1304fee23f9Smrg	struct _UnaryOp
1314fee23f9Smrg	{
1324fee23f9Smrg	  typedef typename __fun<_Op, _Tp>::result_type __rt;
1334fee23f9Smrg	  typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
1344fee23f9Smrg	};
1354fee23f9Smrg    public:
1364fee23f9Smrg      typedef _Tp value_type;
1374fee23f9Smrg
1384fee23f9Smrg	// _lib.valarray.cons_ construct/destroy:
1394fee23f9Smrg      ///  Construct an empty array.
140b1e83836Smrg      valarray() _GLIBCXX_NOTHROW;
1414fee23f9Smrg
1424fee23f9Smrg      ///  Construct an array with @a n elements.
1434fee23f9Smrg      explicit valarray(size_t);
1444fee23f9Smrg
1454fee23f9Smrg      ///  Construct an array with @a n elements initialized to @a t.
1464fee23f9Smrg      valarray(const _Tp&, size_t);
1474fee23f9Smrg
1484fee23f9Smrg      ///  Construct an array initialized to the first @a n elements of @a t.
1494fee23f9Smrg      valarray(const _Tp* __restrict__, size_t);
1504fee23f9Smrg
1514fee23f9Smrg      ///  Copy constructor.
1524fee23f9Smrg      valarray(const valarray&);
1534fee23f9Smrg
15448fb7bfaSmrg#if __cplusplus >= 201103L
15548fb7bfaSmrg      ///  Move constructor.
15648fb7bfaSmrg      valarray(valarray&&) noexcept;
15748fb7bfaSmrg#endif
15848fb7bfaSmrg
1594fee23f9Smrg      ///  Construct an array with the same size and values in @a sa.
1604fee23f9Smrg      valarray(const slice_array<_Tp>&);
1614fee23f9Smrg
1624fee23f9Smrg      ///  Construct an array with the same size and values in @a ga.
1634fee23f9Smrg      valarray(const gslice_array<_Tp>&);
1644fee23f9Smrg
1654fee23f9Smrg      ///  Construct an array with the same size and values in @a ma.
1664fee23f9Smrg      valarray(const mask_array<_Tp>&);
1674fee23f9Smrg
1684fee23f9Smrg      ///  Construct an array with the same size and values in @a ia.
1694fee23f9Smrg      valarray(const indirect_array<_Tp>&);
1704fee23f9Smrg
17148fb7bfaSmrg#if __cplusplus >= 201103L
1724fee23f9Smrg      ///  Construct an array with an initializer_list of values.
1734fee23f9Smrg      valarray(initializer_list<_Tp>);
1744fee23f9Smrg#endif
1754fee23f9Smrg
1764fee23f9Smrg      template<class _Dom>
1774fee23f9Smrg	valarray(const _Expr<_Dom, _Tp>& __e);
1784fee23f9Smrg
17948fb7bfaSmrg      ~valarray() _GLIBCXX_NOEXCEPT;
1804fee23f9Smrg
1814fee23f9Smrg      // _lib.valarray.assign_ assignment:
1824fee23f9Smrg      /**
1834fee23f9Smrg       *  @brief  Assign elements to an array.
1844fee23f9Smrg       *
18548fb7bfaSmrg       *  Assign elements of array to values in @a v.
1864fee23f9Smrg       *
18748fb7bfaSmrg       *  @param  __v  Valarray to get values from.
1884fee23f9Smrg       */
18948fb7bfaSmrg      valarray<_Tp>& operator=(const valarray<_Tp>& __v);
19048fb7bfaSmrg
19148fb7bfaSmrg#if __cplusplus >= 201103L
19248fb7bfaSmrg      /**
19348fb7bfaSmrg       *  @brief  Move assign elements to an array.
19448fb7bfaSmrg       *
19548fb7bfaSmrg       *  Move assign elements of array to values in @a v.
19648fb7bfaSmrg       *
19748fb7bfaSmrg       *  @param  __v  Valarray to get values from.
19848fb7bfaSmrg       */
19948fb7bfaSmrg      valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept;
20048fb7bfaSmrg#endif
2014fee23f9Smrg
2024fee23f9Smrg      /**
2034fee23f9Smrg       *  @brief  Assign elements to a value.
2044fee23f9Smrg       *
2054fee23f9Smrg       *  Assign all elements of array to @a t.
2064fee23f9Smrg       *
20748fb7bfaSmrg       *  @param  __t  Value for elements.
2084fee23f9Smrg       */
20948fb7bfaSmrg      valarray<_Tp>& operator=(const _Tp& __t);
2104fee23f9Smrg
2114fee23f9Smrg      /**
2124fee23f9Smrg       *  @brief  Assign elements to an array subset.
2134fee23f9Smrg       *
2144fee23f9Smrg       *  Assign elements of array to values in @a sa.  Results are undefined
2154fee23f9Smrg       *  if @a sa does not have the same size as this array.
2164fee23f9Smrg       *
21748fb7bfaSmrg       *  @param  __sa  Array slice to get values from.
2184fee23f9Smrg       */
21948fb7bfaSmrg      valarray<_Tp>& operator=(const slice_array<_Tp>& __sa);
2204fee23f9Smrg
2214fee23f9Smrg      /**
2224fee23f9Smrg       *  @brief  Assign elements to an array subset.
2234fee23f9Smrg       *
2244fee23f9Smrg       *  Assign elements of array to values in @a ga.  Results are undefined
2254fee23f9Smrg       *  if @a ga does not have the same size as this array.
2264fee23f9Smrg       *
22748fb7bfaSmrg       *  @param  __ga  Array slice to get values from.
2284fee23f9Smrg       */
22948fb7bfaSmrg      valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga);
2304fee23f9Smrg
2314fee23f9Smrg      /**
2324fee23f9Smrg       *  @brief  Assign elements to an array subset.
2334fee23f9Smrg       *
2344fee23f9Smrg       *  Assign elements of array to values in @a ma.  Results are undefined
2354fee23f9Smrg       *  if @a ma does not have the same size as this array.
2364fee23f9Smrg       *
23748fb7bfaSmrg       *  @param  __ma  Array slice to get values from.
2384fee23f9Smrg       */
23948fb7bfaSmrg      valarray<_Tp>& operator=(const mask_array<_Tp>& __ma);
2404fee23f9Smrg
2414fee23f9Smrg      /**
2424fee23f9Smrg       *  @brief  Assign elements to an array subset.
2434fee23f9Smrg       *
2444fee23f9Smrg       *  Assign elements of array to values in @a ia.  Results are undefined
2454fee23f9Smrg       *  if @a ia does not have the same size as this array.
2464fee23f9Smrg       *
24748fb7bfaSmrg       *  @param  __ia  Array slice to get values from.
2484fee23f9Smrg       */
24948fb7bfaSmrg      valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia);
2504fee23f9Smrg
25148fb7bfaSmrg#if __cplusplus >= 201103L
2524fee23f9Smrg      /**
2534fee23f9Smrg       *  @brief  Assign elements to an initializer_list.
2544fee23f9Smrg       *
25548fb7bfaSmrg       *  Assign elements of array to values in @a __l.  Results are undefined
25648fb7bfaSmrg       *  if @a __l does not have the same size as this array.
2574fee23f9Smrg       *
25848fb7bfaSmrg       *  @param  __l  initializer_list to get values from.
2594fee23f9Smrg       */
26048fb7bfaSmrg      valarray& operator=(initializer_list<_Tp> __l);
2614fee23f9Smrg#endif
2624fee23f9Smrg
2634fee23f9Smrg      template<class _Dom> valarray<_Tp>&
2644fee23f9Smrg	operator= (const _Expr<_Dom, _Tp>&);
2654fee23f9Smrg
2664fee23f9Smrg      // _lib.valarray.access_ element access:
2674fee23f9Smrg      /**
2684fee23f9Smrg       *  Return a reference to the i'th array element.
2694fee23f9Smrg       *
27048fb7bfaSmrg       *  @param  __i  Index of element to return.
2714fee23f9Smrg       *  @return  Reference to the i'th element.
2724fee23f9Smrg       */
273b1e83836Smrg      _Tp&                operator[](size_t __i) _GLIBCXX_NOTHROW;
2744fee23f9Smrg
2754fee23f9Smrg      // _GLIBCXX_RESOLVE_LIB_DEFECTS
2764fee23f9Smrg      // 389. Const overload of valarray::operator[] returns by value.
277b1e83836Smrg      const _Tp&          operator[](size_t) const _GLIBCXX_NOTHROW;
2784fee23f9Smrg
2794fee23f9Smrg      // _lib.valarray.sub_ subset operations:
2804fee23f9Smrg      /**
2814fee23f9Smrg       *  @brief  Return an array subset.
2824fee23f9Smrg       *
2834fee23f9Smrg       *  Returns a new valarray containing the elements of the array
2844fee23f9Smrg       *  indicated by the slice argument.  The new valarray has the same size
2854fee23f9Smrg       *  as the input slice.  @see slice.
2864fee23f9Smrg       *
28748fb7bfaSmrg       *  @param  __s  The source slice.
28848fb7bfaSmrg       *  @return  New valarray containing elements in @a __s.
2894fee23f9Smrg       */
29048fb7bfaSmrg      _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const;
2914fee23f9Smrg
2924fee23f9Smrg      /**
2934fee23f9Smrg       *  @brief  Return a reference to an array subset.
2944fee23f9Smrg       *
2954fee23f9Smrg       *  Returns a new valarray containing the elements of the array
2964fee23f9Smrg       *  indicated by the slice argument.  The new valarray has the same size
2974fee23f9Smrg       *  as the input slice.  @see slice.
2984fee23f9Smrg       *
29948fb7bfaSmrg       *  @param  __s  The source slice.
30048fb7bfaSmrg       *  @return  New valarray containing elements in @a __s.
3014fee23f9Smrg       */
30248fb7bfaSmrg      slice_array<_Tp>    operator[](slice __s);
3034fee23f9Smrg
3044fee23f9Smrg      /**
3054fee23f9Smrg       *  @brief  Return an array subset.
3064fee23f9Smrg       *
3074fee23f9Smrg       *  Returns a slice_array referencing the elements of the array
3084fee23f9Smrg       *  indicated by the slice argument.  @see gslice.
3094fee23f9Smrg       *
31048fb7bfaSmrg       *  @param  __s  The source slice.
31148fb7bfaSmrg       *  @return  Slice_array referencing elements indicated by @a __s.
3124fee23f9Smrg       */
31348fb7bfaSmrg      _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const;
3144fee23f9Smrg
3154fee23f9Smrg      /**
3164fee23f9Smrg       *  @brief  Return a reference to an array subset.
3174fee23f9Smrg       *
3184fee23f9Smrg       *  Returns a new valarray containing the elements of the array
3194fee23f9Smrg       *  indicated by the gslice argument.  The new valarray has
3204fee23f9Smrg       *  the same size as the input gslice.  @see gslice.
3214fee23f9Smrg       *
32248fb7bfaSmrg       *  @param  __s  The source gslice.
32348fb7bfaSmrg       *  @return  New valarray containing elements in @a __s.
3244fee23f9Smrg       */
32548fb7bfaSmrg      gslice_array<_Tp>   operator[](const gslice& __s);
3264fee23f9Smrg
3274fee23f9Smrg      /**
3284fee23f9Smrg       *  @brief  Return an array subset.
3294fee23f9Smrg       *
3304fee23f9Smrg       *  Returns a new valarray containing the elements of the array
3314fee23f9Smrg       *  indicated by the argument.  The input is a valarray of bool which
3324fee23f9Smrg       *  represents a bitmask indicating which elements should be copied into
3334fee23f9Smrg       *  the new valarray.  Each element of the array is added to the return
3344fee23f9Smrg       *  valarray if the corresponding element of the argument is true.
3354fee23f9Smrg       *
33648fb7bfaSmrg       *  @param  __m  The valarray bitmask.
33748fb7bfaSmrg       *  @return  New valarray containing elements indicated by @a __m.
3384fee23f9Smrg       */
33948fb7bfaSmrg      valarray<_Tp>       operator[](const valarray<bool>& __m) const;
3404fee23f9Smrg
3414fee23f9Smrg      /**
3424fee23f9Smrg       *  @brief  Return a reference to an array subset.
3434fee23f9Smrg       *
3444fee23f9Smrg       *  Returns a new mask_array referencing the elements of the array
3454fee23f9Smrg       *  indicated by the argument.  The input is a valarray of bool which
3464fee23f9Smrg       *  represents a bitmask indicating which elements are part of the
3474fee23f9Smrg       *  subset.  Elements of the array are part of the subset if the
3484fee23f9Smrg       *  corresponding element of the argument is true.
3494fee23f9Smrg       *
35048fb7bfaSmrg       *  @param  __m  The valarray bitmask.
35148fb7bfaSmrg       *  @return  New valarray containing elements indicated by @a __m.
3524fee23f9Smrg       */
35348fb7bfaSmrg      mask_array<_Tp>     operator[](const valarray<bool>& __m);
3544fee23f9Smrg
3554fee23f9Smrg      /**
3564fee23f9Smrg       *  @brief  Return an array subset.
3574fee23f9Smrg       *
3584fee23f9Smrg       *  Returns a new valarray containing the elements of the array
3594fee23f9Smrg       *  indicated by the argument.  The elements in the argument are
3604fee23f9Smrg       *  interpreted as the indices of elements of this valarray to copy to
3614fee23f9Smrg       *  the return valarray.
3624fee23f9Smrg       *
36348fb7bfaSmrg       *  @param  __i  The valarray element index list.
36448fb7bfaSmrg       *  @return  New valarray containing elements in @a __s.
3654fee23f9Smrg       */
3664fee23f9Smrg      _Expr<_IClos<_ValArray, _Tp>, _Tp>
36748fb7bfaSmrg        operator[](const valarray<size_t>& __i) const;
3684fee23f9Smrg
3694fee23f9Smrg      /**
3704fee23f9Smrg       *  @brief  Return a reference to an array subset.
3714fee23f9Smrg       *
3724fee23f9Smrg       *  Returns an indirect_array referencing the elements of the array
3734fee23f9Smrg       *  indicated by the argument.  The elements in the argument are
3744fee23f9Smrg       *  interpreted as the indices of elements of this valarray to include
3754fee23f9Smrg       *  in the subset.  The returned indirect_array refers to these
3764fee23f9Smrg       *  elements.
3774fee23f9Smrg       *
37848fb7bfaSmrg       *  @param  __i  The valarray element index list.
37948fb7bfaSmrg       *  @return  Indirect_array referencing elements in @a __i.
3804fee23f9Smrg       */
38148fb7bfaSmrg      indirect_array<_Tp> operator[](const valarray<size_t>& __i);
3824fee23f9Smrg
3834fee23f9Smrg      // _lib.valarray.unary_ unary operators:
3844fee23f9Smrg      ///  Return a new valarray by applying unary + to each element.
3854fee23f9Smrg      typename _UnaryOp<__unary_plus>::_Rt  operator+() const;
3864fee23f9Smrg
3874fee23f9Smrg      ///  Return a new valarray by applying unary - to each element.
3884fee23f9Smrg      typename _UnaryOp<__negate>::_Rt      operator-() const;
3894fee23f9Smrg
3904fee23f9Smrg      ///  Return a new valarray by applying unary ~ to each element.
3914fee23f9Smrg      typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
3924fee23f9Smrg
3934fee23f9Smrg      ///  Return a new valarray by applying unary ! to each element.
3944fee23f9Smrg      typename _UnaryOp<__logical_not>::_Rt operator!() const;
3954fee23f9Smrg
3964fee23f9Smrg      // _lib.valarray.cassign_ computed assignment:
3974fee23f9Smrg      ///  Multiply each element of array by @a t.
3984fee23f9Smrg      valarray<_Tp>& operator*=(const _Tp&);
3994fee23f9Smrg
4004fee23f9Smrg      ///  Divide each element of array by @a t.
4014fee23f9Smrg      valarray<_Tp>& operator/=(const _Tp&);
4024fee23f9Smrg
4034fee23f9Smrg      ///  Set each element e of array to e % @a t.
4044fee23f9Smrg      valarray<_Tp>& operator%=(const _Tp&);
4054fee23f9Smrg
4064fee23f9Smrg      ///  Add @a t to each element of array.
4074fee23f9Smrg      valarray<_Tp>& operator+=(const _Tp&);
4084fee23f9Smrg
4094fee23f9Smrg      ///  Subtract @a t to each element of array.
4104fee23f9Smrg      valarray<_Tp>& operator-=(const _Tp&);
4114fee23f9Smrg
4124fee23f9Smrg      ///  Set each element e of array to e ^ @a t.
4134fee23f9Smrg      valarray<_Tp>& operator^=(const _Tp&);
4144fee23f9Smrg
4154fee23f9Smrg      ///  Set each element e of array to e & @a t.
4164fee23f9Smrg      valarray<_Tp>& operator&=(const _Tp&);
4174fee23f9Smrg
4184fee23f9Smrg      ///  Set each element e of array to e | @a t.
4194fee23f9Smrg      valarray<_Tp>& operator|=(const _Tp&);
4204fee23f9Smrg
4214fee23f9Smrg      ///  Left shift each element e of array by @a t bits.
4224fee23f9Smrg      valarray<_Tp>& operator<<=(const _Tp&);
4234fee23f9Smrg
4244fee23f9Smrg      ///  Right shift each element e of array by @a t bits.
4254fee23f9Smrg      valarray<_Tp>& operator>>=(const _Tp&);
4264fee23f9Smrg
4274fee23f9Smrg      ///  Multiply elements of array by corresponding elements of @a v.
4284fee23f9Smrg      valarray<_Tp>& operator*=(const valarray<_Tp>&);
4294fee23f9Smrg
4304fee23f9Smrg      ///  Divide elements of array by corresponding elements of @a v.
4314fee23f9Smrg      valarray<_Tp>& operator/=(const valarray<_Tp>&);
4324fee23f9Smrg
4334fee23f9Smrg      ///  Modulo elements of array by corresponding elements of @a v.
4344fee23f9Smrg      valarray<_Tp>& operator%=(const valarray<_Tp>&);
4354fee23f9Smrg
4364fee23f9Smrg      ///  Add corresponding elements of @a v to elements of array.
4374fee23f9Smrg      valarray<_Tp>& operator+=(const valarray<_Tp>&);
4384fee23f9Smrg
4394fee23f9Smrg      ///  Subtract corresponding elements of @a v from elements of array.
4404fee23f9Smrg      valarray<_Tp>& operator-=(const valarray<_Tp>&);
4414fee23f9Smrg
4424fee23f9Smrg      ///  Logical xor corresponding elements of @a v with elements of array.
4434fee23f9Smrg      valarray<_Tp>& operator^=(const valarray<_Tp>&);
4444fee23f9Smrg
4454fee23f9Smrg      ///  Logical or corresponding elements of @a v with elements of array.
4464fee23f9Smrg      valarray<_Tp>& operator|=(const valarray<_Tp>&);
4474fee23f9Smrg
4484fee23f9Smrg      ///  Logical and corresponding elements of @a v with elements of array.
4494fee23f9Smrg      valarray<_Tp>& operator&=(const valarray<_Tp>&);
4504fee23f9Smrg
4514fee23f9Smrg      ///  Left shift elements of array by corresponding elements of @a v.
4524fee23f9Smrg      valarray<_Tp>& operator<<=(const valarray<_Tp>&);
4534fee23f9Smrg
4544fee23f9Smrg      ///  Right shift elements of array by corresponding elements of @a v.
4554fee23f9Smrg      valarray<_Tp>& operator>>=(const valarray<_Tp>&);
4564fee23f9Smrg
4574fee23f9Smrg      template<class _Dom>
4584fee23f9Smrg	valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&);
4594fee23f9Smrg      template<class _Dom>
4604fee23f9Smrg	valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&);
4614fee23f9Smrg      template<class _Dom>
4624fee23f9Smrg	valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&);
4634fee23f9Smrg      template<class _Dom>
4644fee23f9Smrg	valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&);
4654fee23f9Smrg      template<class _Dom>
4664fee23f9Smrg	valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&);
4674fee23f9Smrg      template<class _Dom>
4684fee23f9Smrg	valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&);
4694fee23f9Smrg      template<class _Dom>
4704fee23f9Smrg	valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&);
4714fee23f9Smrg      template<class _Dom>
4724fee23f9Smrg	valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&);
4734fee23f9Smrg      template<class _Dom>
4744fee23f9Smrg        valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&);
4754fee23f9Smrg      template<class _Dom>
4764fee23f9Smrg	valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
4774fee23f9Smrg
4784fee23f9Smrg      // _lib.valarray.members_ member functions:
47948fb7bfaSmrg#if __cplusplus >= 201103L
48048fb7bfaSmrg      ///  Swap.
48148fb7bfaSmrg      void swap(valarray<_Tp>& __v) noexcept;
48248fb7bfaSmrg#endif
48348fb7bfaSmrg
4844fee23f9Smrg      ///  Return the number of elements in array.
4854fee23f9Smrg      size_t size() const;
4864fee23f9Smrg
4874fee23f9Smrg      /**
4884fee23f9Smrg       *  @brief  Return the sum of all elements in the array.
4894fee23f9Smrg       *
4904fee23f9Smrg       *  Accumulates the sum of all elements into a Tp using +=.  The order
4914fee23f9Smrg       *  of adding the elements is unspecified.
4924fee23f9Smrg       */
4934fee23f9Smrg      _Tp    sum() const;
4944fee23f9Smrg
4954fee23f9Smrg      ///  Return the minimum element using operator<().
4964fee23f9Smrg      _Tp    min() const;
4974fee23f9Smrg
4984fee23f9Smrg      ///  Return the maximum element using operator<().
4994fee23f9Smrg      _Tp    max() const;
5004fee23f9Smrg
5014fee23f9Smrg      /**
5024fee23f9Smrg       *  @brief  Return a shifted array.
5034fee23f9Smrg       *
5044fee23f9Smrg       *  A new valarray is constructed as a copy of this array with elements
5054fee23f9Smrg       *  in shifted positions.  For an element with index i, the new position
5064fee23f9Smrg       *  is i - n.  The new valarray has the same size as the current one.
5074fee23f9Smrg       *  New elements without a value are set to 0.  Elements whose new
5084fee23f9Smrg       *  position is outside the bounds of the array are discarded.
5094fee23f9Smrg       *
5104fee23f9Smrg       *  Positive arguments shift toward index 0, discarding elements [0, n).
5114fee23f9Smrg       *  Negative arguments discard elements from the top of the array.
5124fee23f9Smrg       *
51348fb7bfaSmrg       *  @param  __n  Number of element positions to shift.
5144fee23f9Smrg       *  @return  New valarray with elements in shifted positions.
5154fee23f9Smrg       */
51648fb7bfaSmrg      valarray<_Tp> shift (int __n) const;
5174fee23f9Smrg
5184fee23f9Smrg      /**
5194fee23f9Smrg       *  @brief  Return a rotated array.
5204fee23f9Smrg       *
5214fee23f9Smrg       *  A new valarray is constructed as a copy of this array with elements
5224fee23f9Smrg       *  in shifted positions.  For an element with index i, the new position
5234fee23f9Smrg       *  is (i - n) % size().  The new valarray has the same size as the
5244fee23f9Smrg       *  current one.  Elements that are shifted beyond the array bounds are
5254fee23f9Smrg       *  shifted into the other end of the array.  No elements are lost.
5264fee23f9Smrg       *
5274fee23f9Smrg       *  Positive arguments shift toward index 0, wrapping around the top.
5284fee23f9Smrg       *  Negative arguments shift towards the top, wrapping around to 0.
5294fee23f9Smrg       *
53048fb7bfaSmrg       *  @param  __n  Number of element positions to rotate.
5314fee23f9Smrg       *  @return  New valarray with elements in shifted positions.
5324fee23f9Smrg       */
53348fb7bfaSmrg      valarray<_Tp> cshift(int __n) const;
5344fee23f9Smrg
5354fee23f9Smrg      /**
5364fee23f9Smrg       *  @brief  Apply a function to the array.
5374fee23f9Smrg       *
5384fee23f9Smrg       *  Returns a new valarray with elements assigned to the result of
539b1e83836Smrg       *  applying __func to the corresponding element of this array.  The new
5404fee23f9Smrg       *  array has the same size as this one.
5414fee23f9Smrg       *
542b1e83836Smrg       *  @param  __func  Function of Tp returning Tp to apply.
5434fee23f9Smrg       *  @return  New valarray with transformed elements.
5444fee23f9Smrg       */
545b1e83836Smrg      _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(_Tp)) const;
5464fee23f9Smrg
5474fee23f9Smrg      /**
5484fee23f9Smrg       *  @brief  Apply a function to the array.
5494fee23f9Smrg       *
5504fee23f9Smrg       *  Returns a new valarray with elements assigned to the result of
551b1e83836Smrg       *  applying __func to the corresponding element of this array.  The new
5524fee23f9Smrg       *  array has the same size as this one.
5534fee23f9Smrg       *
554b1e83836Smrg       *  @param  __func  Function of const Tp& returning Tp to apply.
5554fee23f9Smrg       *  @return  New valarray with transformed elements.
5564fee23f9Smrg       */
557b1e83836Smrg      _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(const _Tp&)) const;
5584fee23f9Smrg
5594fee23f9Smrg      /**
5604fee23f9Smrg       *  @brief  Resize array.
5614fee23f9Smrg       *
5624fee23f9Smrg       *  Resize this array to @a size and set all elements to @a c.  All
5634fee23f9Smrg       *  references and iterators are invalidated.
5644fee23f9Smrg       *
56548fb7bfaSmrg       *  @param  __size  New array size.
56648fb7bfaSmrg       *  @param  __c  New value for all elements.
5674fee23f9Smrg       */
5684fee23f9Smrg      void resize(size_t __size, _Tp __c = _Tp());
5694fee23f9Smrg
5704fee23f9Smrg    private:
5714fee23f9Smrg      size_t _M_size;
5724fee23f9Smrg      _Tp* __restrict__ _M_data;
5734fee23f9Smrg
574b1e83836Smrg      friend struct _Array<_Tp>;
5754fee23f9Smrg    };
5764fee23f9Smrg
577b17d1066Smrg#if __cpp_deduction_guides >= 201606
578b17d1066Smrg  template<typename _Tp, size_t _Nm>
579b17d1066Smrg    valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>;
580b17d1066Smrg#endif
581b17d1066Smrg
5824fee23f9Smrg  template<typename _Tp>
5834fee23f9Smrg    inline const _Tp&
584b1e83836Smrg    valarray<_Tp>::operator[](size_t __i) const _GLIBCXX_NOTHROW
5854fee23f9Smrg    {
5864fee23f9Smrg      __glibcxx_requires_subscript(__i);
5874fee23f9Smrg      return _M_data[__i];
5884fee23f9Smrg    }
5894fee23f9Smrg
5904fee23f9Smrg  template<typename _Tp>
5914fee23f9Smrg    inline _Tp&
592b1e83836Smrg    valarray<_Tp>::operator[](size_t __i) _GLIBCXX_NOTHROW
5934fee23f9Smrg    {
5944fee23f9Smrg      __glibcxx_requires_subscript(__i);
5954fee23f9Smrg      return _M_data[__i];
5964fee23f9Smrg    }
5974fee23f9Smrg
598a448f87cSmrg  /// @} group numeric_arrays
5994fee23f9Smrg
60048fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION
60148fb7bfaSmrg} // namespace
6024fee23f9Smrg
6034fee23f9Smrg#include <bits/valarray_after.h>
6044fee23f9Smrg#include <bits/slice_array.h>
6054fee23f9Smrg#include <bits/gslice.h>
6064fee23f9Smrg#include <bits/gslice_array.h>
6074fee23f9Smrg#include <bits/mask_array.h>
6084fee23f9Smrg#include <bits/indirect_array.h>
6094fee23f9Smrg
61048fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default)
61148fb7bfaSmrg{
61248fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
6134fee23f9Smrg
6144fee23f9Smrg  /**
6154fee23f9Smrg   * @addtogroup numeric_arrays
6164fee23f9Smrg   * @{
6174fee23f9Smrg   */
6184fee23f9Smrg
6194fee23f9Smrg  template<typename _Tp>
6204fee23f9Smrg    inline
621b1e83836Smrg    valarray<_Tp>::valarray() _GLIBCXX_NOTHROW : _M_size(0), _M_data(0) {}
6224fee23f9Smrg
6234fee23f9Smrg  template<typename _Tp>
6244fee23f9Smrg    inline
6254fee23f9Smrg    valarray<_Tp>::valarray(size_t __n)
6264fee23f9Smrg    : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
6274fee23f9Smrg    { std::__valarray_default_construct(_M_data, _M_data + __n); }
6284fee23f9Smrg
6294fee23f9Smrg  template<typename _Tp>
6304fee23f9Smrg    inline
6314fee23f9Smrg    valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
6324fee23f9Smrg    : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
6334fee23f9Smrg    { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
6344fee23f9Smrg
6354fee23f9Smrg  template<typename _Tp>
6364fee23f9Smrg    inline
6374fee23f9Smrg    valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
6384fee23f9Smrg    : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
6394fee23f9Smrg    {
640f9a78e0eSmrg      __glibcxx_assert(__p != 0 || __n == 0);
6414fee23f9Smrg      std::__valarray_copy_construct(__p, __p + __n, _M_data);
6424fee23f9Smrg    }
6434fee23f9Smrg
6444fee23f9Smrg  template<typename _Tp>
6454fee23f9Smrg    inline
6464fee23f9Smrg    valarray<_Tp>::valarray(const valarray<_Tp>& __v)
6474fee23f9Smrg    : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
6484fee23f9Smrg    { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
6494fee23f9Smrg				     _M_data); }
6504fee23f9Smrg
65148fb7bfaSmrg#if __cplusplus >= 201103L
65248fb7bfaSmrg  template<typename _Tp>
65348fb7bfaSmrg    inline
65448fb7bfaSmrg    valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
65548fb7bfaSmrg    : _M_size(__v._M_size), _M_data(__v._M_data)
65648fb7bfaSmrg    {
65748fb7bfaSmrg      __v._M_size = 0;
65848fb7bfaSmrg      __v._M_data = 0;
65948fb7bfaSmrg    }
66048fb7bfaSmrg#endif
66148fb7bfaSmrg
6624fee23f9Smrg  template<typename _Tp>
6634fee23f9Smrg    inline
6644fee23f9Smrg    valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
6654fee23f9Smrg    : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
6664fee23f9Smrg    {
6674fee23f9Smrg      std::__valarray_copy_construct
6684fee23f9Smrg	(__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
6694fee23f9Smrg    }
6704fee23f9Smrg
6714fee23f9Smrg  template<typename _Tp>
6724fee23f9Smrg    inline
6734fee23f9Smrg    valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
6744fee23f9Smrg    : _M_size(__ga._M_index.size()),
6754fee23f9Smrg      _M_data(__valarray_get_storage<_Tp>(_M_size))
6764fee23f9Smrg    {
6774fee23f9Smrg      std::__valarray_copy_construct
6784fee23f9Smrg	(__ga._M_array, _Array<size_t>(__ga._M_index),
6794fee23f9Smrg	 _Array<_Tp>(_M_data), _M_size);
6804fee23f9Smrg    }
6814fee23f9Smrg
6824fee23f9Smrg  template<typename _Tp>
6834fee23f9Smrg    inline
6844fee23f9Smrg    valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
6854fee23f9Smrg    : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
6864fee23f9Smrg    {
6874fee23f9Smrg      std::__valarray_copy_construct
6884fee23f9Smrg	(__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
6894fee23f9Smrg    }
6904fee23f9Smrg
6914fee23f9Smrg  template<typename _Tp>
6924fee23f9Smrg    inline
6934fee23f9Smrg    valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
6944fee23f9Smrg    : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
6954fee23f9Smrg    {
6964fee23f9Smrg      std::__valarray_copy_construct
6974fee23f9Smrg	(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
6984fee23f9Smrg    }
6994fee23f9Smrg
70048fb7bfaSmrg#if __cplusplus >= 201103L
7014fee23f9Smrg  template<typename _Tp>
7024fee23f9Smrg    inline
7034fee23f9Smrg    valarray<_Tp>::valarray(initializer_list<_Tp> __l)
7044fee23f9Smrg    : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
7054fee23f9Smrg    { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
7064fee23f9Smrg#endif
7074fee23f9Smrg
7084fee23f9Smrg  template<typename _Tp> template<class _Dom>
7094fee23f9Smrg    inline
7104fee23f9Smrg    valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
7114fee23f9Smrg    : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
7124fee23f9Smrg    { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
7134fee23f9Smrg
7144fee23f9Smrg  template<typename _Tp>
7154fee23f9Smrg    inline
71648fb7bfaSmrg    valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT
7174fee23f9Smrg    {
7184fee23f9Smrg      std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
7194fee23f9Smrg      std::__valarray_release_memory(_M_data);
7204fee23f9Smrg    }
7214fee23f9Smrg
7224fee23f9Smrg  template<typename _Tp>
7234fee23f9Smrg    inline valarray<_Tp>&
7244fee23f9Smrg    valarray<_Tp>::operator=(const valarray<_Tp>& __v)
7254fee23f9Smrg    {
7264fee23f9Smrg      // _GLIBCXX_RESOLVE_LIB_DEFECTS
7274fee23f9Smrg      // 630. arrays of valarray.
7284fee23f9Smrg      if (_M_size == __v._M_size)
7294fee23f9Smrg	std::__valarray_copy(__v._M_data, _M_size, _M_data);
7304fee23f9Smrg      else
7314fee23f9Smrg	{
7324fee23f9Smrg	  if (_M_data)
7334fee23f9Smrg	    {
7344fee23f9Smrg	      std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
7354fee23f9Smrg	      std::__valarray_release_memory(_M_data);
7364fee23f9Smrg	    }
7374fee23f9Smrg	  _M_size = __v._M_size;
7384fee23f9Smrg	  _M_data = __valarray_get_storage<_Tp>(_M_size);
7394fee23f9Smrg	  std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
7404fee23f9Smrg					 _M_data);
7414fee23f9Smrg	}
7424fee23f9Smrg      return *this;
7434fee23f9Smrg    }
7444fee23f9Smrg
74548fb7bfaSmrg#if __cplusplus >= 201103L
74648fb7bfaSmrg  template<typename _Tp>
74748fb7bfaSmrg    inline valarray<_Tp>&
74848fb7bfaSmrg    valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
74948fb7bfaSmrg    {
75048fb7bfaSmrg      if (_M_data)
75148fb7bfaSmrg	{
75248fb7bfaSmrg	  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
75348fb7bfaSmrg	  std::__valarray_release_memory(_M_data);
75448fb7bfaSmrg	}
75548fb7bfaSmrg      _M_size = __v._M_size;
75648fb7bfaSmrg      _M_data = __v._M_data;
75748fb7bfaSmrg      __v._M_size = 0;
75848fb7bfaSmrg      __v._M_data = 0;
75948fb7bfaSmrg      return *this;
76048fb7bfaSmrg    }
76148fb7bfaSmrg
7624fee23f9Smrg  template<typename _Tp>
7634fee23f9Smrg    inline valarray<_Tp>&
7644fee23f9Smrg    valarray<_Tp>::operator=(initializer_list<_Tp> __l)
7654fee23f9Smrg    {
7664fee23f9Smrg      // _GLIBCXX_RESOLVE_LIB_DEFECTS
7674fee23f9Smrg      // 630. arrays of valarray.
7684fee23f9Smrg      if (_M_size == __l.size())
7694fee23f9Smrg	std::__valarray_copy(__l.begin(), __l.size(), _M_data);
7704fee23f9Smrg      else
7714fee23f9Smrg	{
7724fee23f9Smrg	  if (_M_data)
7734fee23f9Smrg	    {
7744fee23f9Smrg	      std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
7754fee23f9Smrg	      std::__valarray_release_memory(_M_data);
7764fee23f9Smrg	    }
7774fee23f9Smrg	  _M_size = __l.size();
7784fee23f9Smrg	  _M_data = __valarray_get_storage<_Tp>(_M_size);
7794fee23f9Smrg	  std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size,
7804fee23f9Smrg					 _M_data);
7814fee23f9Smrg	}
7824fee23f9Smrg      return *this;
7834fee23f9Smrg    }
7844fee23f9Smrg#endif
7854fee23f9Smrg
7864fee23f9Smrg  template<typename _Tp>
7874fee23f9Smrg    inline valarray<_Tp>&
7884fee23f9Smrg    valarray<_Tp>::operator=(const _Tp& __t)
7894fee23f9Smrg    {
7904fee23f9Smrg      std::__valarray_fill(_M_data, _M_size, __t);
7914fee23f9Smrg      return *this;
7924fee23f9Smrg    }
7934fee23f9Smrg
7944fee23f9Smrg  template<typename _Tp>
7954fee23f9Smrg    inline valarray<_Tp>&
7964fee23f9Smrg    valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
7974fee23f9Smrg    {
798f9a78e0eSmrg      __glibcxx_assert(_M_size == __sa._M_sz);
7994fee23f9Smrg      std::__valarray_copy(__sa._M_array, __sa._M_sz,
8004fee23f9Smrg			   __sa._M_stride, _Array<_Tp>(_M_data));
8014fee23f9Smrg      return *this;
8024fee23f9Smrg    }
8034fee23f9Smrg
8044fee23f9Smrg  template<typename _Tp>
8054fee23f9Smrg    inline valarray<_Tp>&
8064fee23f9Smrg    valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
8074fee23f9Smrg    {
808f9a78e0eSmrg      __glibcxx_assert(_M_size == __ga._M_index.size());
8094fee23f9Smrg      std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
8104fee23f9Smrg			   _Array<_Tp>(_M_data), _M_size);
8114fee23f9Smrg      return *this;
8124fee23f9Smrg    }
8134fee23f9Smrg
8144fee23f9Smrg  template<typename _Tp>
8154fee23f9Smrg    inline valarray<_Tp>&
8164fee23f9Smrg    valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
8174fee23f9Smrg    {
818f9a78e0eSmrg      __glibcxx_assert(_M_size == __ma._M_sz);
8194fee23f9Smrg      std::__valarray_copy(__ma._M_array, __ma._M_mask,
8204fee23f9Smrg			   _Array<_Tp>(_M_data), _M_size);
8214fee23f9Smrg      return *this;
8224fee23f9Smrg    }
8234fee23f9Smrg
8244fee23f9Smrg  template<typename _Tp>
8254fee23f9Smrg    inline valarray<_Tp>&
8264fee23f9Smrg    valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
8274fee23f9Smrg    {
828f9a78e0eSmrg      __glibcxx_assert(_M_size == __ia._M_sz);
8294fee23f9Smrg      std::__valarray_copy(__ia._M_array, __ia._M_index,
8304fee23f9Smrg			   _Array<_Tp>(_M_data), _M_size);
8314fee23f9Smrg      return *this;
8324fee23f9Smrg    }
8334fee23f9Smrg
8344fee23f9Smrg  template<typename _Tp> template<class _Dom>
8354fee23f9Smrg    inline valarray<_Tp>&
8364fee23f9Smrg    valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
8374fee23f9Smrg    {
83848fb7bfaSmrg      // _GLIBCXX_RESOLVE_LIB_DEFECTS
83948fb7bfaSmrg      // 630. arrays of valarray.
84048fb7bfaSmrg      if (_M_size == __e.size())
8414fee23f9Smrg	std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
84248fb7bfaSmrg      else
84348fb7bfaSmrg	{
84448fb7bfaSmrg	  if (_M_data)
84548fb7bfaSmrg	    {
84648fb7bfaSmrg	      std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
84748fb7bfaSmrg	      std::__valarray_release_memory(_M_data);
84848fb7bfaSmrg	    }
84948fb7bfaSmrg	  _M_size = __e.size();
85048fb7bfaSmrg	  _M_data = __valarray_get_storage<_Tp>(_M_size);
85148fb7bfaSmrg	  std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data));
85248fb7bfaSmrg	}
8534fee23f9Smrg      return *this;
8544fee23f9Smrg    }
8554fee23f9Smrg
8564fee23f9Smrg  template<typename _Tp>
8574fee23f9Smrg    inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
8584fee23f9Smrg    valarray<_Tp>::operator[](slice __s) const
8594fee23f9Smrg    {
8604fee23f9Smrg      typedef _SClos<_ValArray,_Tp> _Closure;
8614fee23f9Smrg      return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
8624fee23f9Smrg    }
8634fee23f9Smrg
8644fee23f9Smrg  template<typename _Tp>
8654fee23f9Smrg    inline slice_array<_Tp>
8664fee23f9Smrg    valarray<_Tp>::operator[](slice __s)
8674fee23f9Smrg    { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
8684fee23f9Smrg
8694fee23f9Smrg  template<typename _Tp>
8704fee23f9Smrg    inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
8714fee23f9Smrg    valarray<_Tp>::operator[](const gslice& __gs) const
8724fee23f9Smrg    {
8734fee23f9Smrg      typedef _GClos<_ValArray,_Tp> _Closure;
8744fee23f9Smrg      return _Expr<_Closure, _Tp>
8754fee23f9Smrg	(_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
8764fee23f9Smrg    }
8774fee23f9Smrg
8784fee23f9Smrg  template<typename _Tp>
8794fee23f9Smrg    inline gslice_array<_Tp>
8804fee23f9Smrg    valarray<_Tp>::operator[](const gslice& __gs)
8814fee23f9Smrg    {
8824fee23f9Smrg      return gslice_array<_Tp>
8834fee23f9Smrg	(_Array<_Tp>(_M_data), __gs._M_index->_M_index);
8844fee23f9Smrg    }
8854fee23f9Smrg
8864fee23f9Smrg  template<typename _Tp>
8874fee23f9Smrg    inline valarray<_Tp>
8884fee23f9Smrg    valarray<_Tp>::operator[](const valarray<bool>& __m) const
8894fee23f9Smrg    {
8904fee23f9Smrg      size_t __s = 0;
8914fee23f9Smrg      size_t __e = __m.size();
8924fee23f9Smrg      for (size_t __i=0; __i<__e; ++__i)
8934fee23f9Smrg	if (__m[__i]) ++__s;
8944fee23f9Smrg      return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
8954fee23f9Smrg					   _Array<bool> (__m)));
8964fee23f9Smrg    }
8974fee23f9Smrg
8984fee23f9Smrg  template<typename _Tp>
8994fee23f9Smrg    inline mask_array<_Tp>
9004fee23f9Smrg    valarray<_Tp>::operator[](const valarray<bool>& __m)
9014fee23f9Smrg    {
9024fee23f9Smrg      size_t __s = 0;
9034fee23f9Smrg      size_t __e = __m.size();
9044fee23f9Smrg      for (size_t __i=0; __i<__e; ++__i)
9054fee23f9Smrg	if (__m[__i]) ++__s;
9064fee23f9Smrg      return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
9074fee23f9Smrg    }
9084fee23f9Smrg
9094fee23f9Smrg  template<typename _Tp>
9104fee23f9Smrg    inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
9114fee23f9Smrg    valarray<_Tp>::operator[](const valarray<size_t>& __i) const
9124fee23f9Smrg    {
9134fee23f9Smrg      typedef _IClos<_ValArray,_Tp> _Closure;
9144fee23f9Smrg      return _Expr<_Closure, _Tp>(_Closure(*this, __i));
9154fee23f9Smrg    }
9164fee23f9Smrg
9174fee23f9Smrg  template<typename _Tp>
9184fee23f9Smrg    inline indirect_array<_Tp>
9194fee23f9Smrg    valarray<_Tp>::operator[](const valarray<size_t>& __i)
9204fee23f9Smrg    {
9214fee23f9Smrg      return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
9224fee23f9Smrg				 _Array<size_t>(__i));
9234fee23f9Smrg    }
9244fee23f9Smrg
92548fb7bfaSmrg#if __cplusplus >= 201103L
92648fb7bfaSmrg  template<class _Tp>
92748fb7bfaSmrg    inline void
92848fb7bfaSmrg    valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
92948fb7bfaSmrg    {
93048fb7bfaSmrg      std::swap(_M_size, __v._M_size);
93148fb7bfaSmrg      std::swap(_M_data, __v._M_data);
93248fb7bfaSmrg    }
93348fb7bfaSmrg#endif
93448fb7bfaSmrg
9354fee23f9Smrg  template<class _Tp>
9364fee23f9Smrg    inline size_t
9374fee23f9Smrg    valarray<_Tp>::size() const
9384fee23f9Smrg    { return _M_size; }
9394fee23f9Smrg
9404fee23f9Smrg  template<class _Tp>
9414fee23f9Smrg    inline _Tp
9424fee23f9Smrg    valarray<_Tp>::sum() const
9434fee23f9Smrg    {
944f9a78e0eSmrg      __glibcxx_assert(_M_size > 0);
9454fee23f9Smrg      return std::__valarray_sum(_M_data, _M_data + _M_size);
9464fee23f9Smrg    }
9474fee23f9Smrg
9484fee23f9Smrg  template<class _Tp>
9494fee23f9Smrg     inline valarray<_Tp>
9504fee23f9Smrg     valarray<_Tp>::shift(int __n) const
9514fee23f9Smrg     {
9524fee23f9Smrg       valarray<_Tp> __ret;
9534fee23f9Smrg
9544fee23f9Smrg       if (_M_size == 0)
9554fee23f9Smrg	 return __ret;
9564fee23f9Smrg
9574fee23f9Smrg       _Tp* __restrict__ __tmp_M_data =
9584fee23f9Smrg	 std::__valarray_get_storage<_Tp>(_M_size);
9594fee23f9Smrg
9604fee23f9Smrg       if (__n == 0)
9614fee23f9Smrg	 std::__valarray_copy_construct(_M_data,
9624fee23f9Smrg					_M_data + _M_size, __tmp_M_data);
9634fee23f9Smrg       else if (__n > 0)      // shift left
9644fee23f9Smrg	 {
9654fee23f9Smrg	   if (size_t(__n) > _M_size)
9664fee23f9Smrg	     __n = int(_M_size);
9674fee23f9Smrg
9684fee23f9Smrg	   std::__valarray_copy_construct(_M_data + __n,
9694fee23f9Smrg					  _M_data + _M_size, __tmp_M_data);
9704fee23f9Smrg	   std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
9714fee23f9Smrg					     __tmp_M_data + _M_size);
9724fee23f9Smrg	 }
9734fee23f9Smrg       else                   // shift right
9744fee23f9Smrg	 {
9754fee23f9Smrg	   if (-size_t(__n) > _M_size)
9764fee23f9Smrg	     __n = -int(_M_size);
9774fee23f9Smrg
9784fee23f9Smrg	   std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
9794fee23f9Smrg					  __tmp_M_data - __n);
9804fee23f9Smrg	   std::__valarray_default_construct(__tmp_M_data,
9814fee23f9Smrg					     __tmp_M_data - __n);
9824fee23f9Smrg	 }
9834fee23f9Smrg
9844fee23f9Smrg       __ret._M_size = _M_size;
9854fee23f9Smrg       __ret._M_data = __tmp_M_data;
9864fee23f9Smrg       return __ret;
9874fee23f9Smrg     }
9884fee23f9Smrg
9894fee23f9Smrg  template<class _Tp>
9904fee23f9Smrg     inline valarray<_Tp>
9914fee23f9Smrg     valarray<_Tp>::cshift(int __n) const
9924fee23f9Smrg     {
9934fee23f9Smrg       valarray<_Tp> __ret;
9944fee23f9Smrg
9954fee23f9Smrg       if (_M_size == 0)
9964fee23f9Smrg	 return __ret;
9974fee23f9Smrg
9984fee23f9Smrg       _Tp* __restrict__ __tmp_M_data =
9994fee23f9Smrg	 std::__valarray_get_storage<_Tp>(_M_size);
10004fee23f9Smrg
10014fee23f9Smrg       if (__n == 0)
10024fee23f9Smrg	 std::__valarray_copy_construct(_M_data,
10034fee23f9Smrg					_M_data + _M_size, __tmp_M_data);
10044fee23f9Smrg       else if (__n > 0)      // cshift left
10054fee23f9Smrg	 {
10064fee23f9Smrg	   if (size_t(__n) > _M_size)
10074fee23f9Smrg	     __n = int(__n % _M_size);
10084fee23f9Smrg
10094fee23f9Smrg	   std::__valarray_copy_construct(_M_data, _M_data + __n,
10104fee23f9Smrg					  __tmp_M_data + _M_size - __n);
10114fee23f9Smrg	   std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
10124fee23f9Smrg					  __tmp_M_data);
10134fee23f9Smrg	 }
10144fee23f9Smrg       else                   // cshift right
10154fee23f9Smrg	 {
10164fee23f9Smrg	   if (-size_t(__n) > _M_size)
10174fee23f9Smrg	     __n = -int(-size_t(__n) % _M_size);
10184fee23f9Smrg
10194fee23f9Smrg	   std::__valarray_copy_construct(_M_data + _M_size + __n,
10204fee23f9Smrg					  _M_data + _M_size, __tmp_M_data);
10214fee23f9Smrg	   std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
10224fee23f9Smrg					  __tmp_M_data - __n);
10234fee23f9Smrg	 }
10244fee23f9Smrg
10254fee23f9Smrg       __ret._M_size = _M_size;
10264fee23f9Smrg       __ret._M_data = __tmp_M_data;
10274fee23f9Smrg       return __ret;
10284fee23f9Smrg     }
10294fee23f9Smrg
10304fee23f9Smrg  template<class _Tp>
10314fee23f9Smrg    inline void
10324fee23f9Smrg    valarray<_Tp>::resize(size_t __n, _Tp __c)
10334fee23f9Smrg    {
10344fee23f9Smrg      // This complication is so to make valarray<valarray<T> > work
10354fee23f9Smrg      // even though it is not required by the standard.  Nobody should
10364fee23f9Smrg      // be saying valarray<valarray<T> > anyway.  See the specs.
10374fee23f9Smrg      std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
10384fee23f9Smrg      if (_M_size != __n)
10394fee23f9Smrg	{
10404fee23f9Smrg	  std::__valarray_release_memory(_M_data);
10414fee23f9Smrg	  _M_size = __n;
10424fee23f9Smrg	  _M_data = __valarray_get_storage<_Tp>(__n);
10434fee23f9Smrg	}
10444fee23f9Smrg      std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
10454fee23f9Smrg    }
10464fee23f9Smrg
10474fee23f9Smrg  template<typename _Tp>
10484fee23f9Smrg    inline _Tp
10494fee23f9Smrg    valarray<_Tp>::min() const
10504fee23f9Smrg    {
1051f9a78e0eSmrg      __glibcxx_assert(_M_size > 0);
10524fee23f9Smrg      return *std::min_element(_M_data, _M_data + _M_size);
10534fee23f9Smrg    }
10544fee23f9Smrg
10554fee23f9Smrg  template<typename _Tp>
10564fee23f9Smrg    inline _Tp
10574fee23f9Smrg    valarray<_Tp>::max() const
10584fee23f9Smrg    {
1059f9a78e0eSmrg      __glibcxx_assert(_M_size > 0);
10604fee23f9Smrg      return *std::max_element(_M_data, _M_data + _M_size);
10614fee23f9Smrg    }
10624fee23f9Smrg
10634fee23f9Smrg  template<class _Tp>
10644fee23f9Smrg    inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
1065b1e83836Smrg    valarray<_Tp>::apply(_Tp __func(_Tp)) const
10664fee23f9Smrg    {
10674fee23f9Smrg      typedef _ValFunClos<_ValArray, _Tp> _Closure;
1068b1e83836Smrg      return _Expr<_Closure, _Tp>(_Closure(*this, __func));
10694fee23f9Smrg    }
10704fee23f9Smrg
10714fee23f9Smrg  template<class _Tp>
10724fee23f9Smrg    inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
1073b1e83836Smrg    valarray<_Tp>::apply(_Tp __func(const _Tp &)) const
10744fee23f9Smrg    {
10754fee23f9Smrg      typedef _RefFunClos<_ValArray, _Tp> _Closure;
1076b1e83836Smrg      return _Expr<_Closure, _Tp>(_Closure(*this, __func));
10774fee23f9Smrg    }
10784fee23f9Smrg
10797d4dc15bSmrg  /// @cond undocumented
10804fee23f9Smrg#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
10814fee23f9Smrg  template<typename _Tp>						\
10824fee23f9Smrg    inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt	\
10834fee23f9Smrg    valarray<_Tp>::operator _Op() const					\
10844fee23f9Smrg    {									\
10854fee23f9Smrg      typedef _UnClos<_Name, _ValArray, _Tp> _Closure;			\
10864fee23f9Smrg      typedef typename __fun<_Name, _Tp>::result_type _Rt;		\
10874fee23f9Smrg      return _Expr<_Closure, _Rt>(_Closure(*this));			\
10884fee23f9Smrg    }
10894fee23f9Smrg
10904fee23f9Smrg    _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
10914fee23f9Smrg    _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
10924fee23f9Smrg    _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
10934fee23f9Smrg    _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
10944fee23f9Smrg
10954fee23f9Smrg#undef _DEFINE_VALARRAY_UNARY_OPERATOR
10964fee23f9Smrg
10974fee23f9Smrg#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
10984fee23f9Smrg  template<class _Tp>							\
10994fee23f9Smrg    inline valarray<_Tp>&						\
11004fee23f9Smrg    valarray<_Tp>::operator _Op##=(const _Tp &__t)			\
11014fee23f9Smrg    {									\
11024fee23f9Smrg      _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t);	\
11034fee23f9Smrg      return *this;							\
11044fee23f9Smrg    }									\
11054fee23f9Smrg									\
11064fee23f9Smrg  template<class _Tp>							\
11074fee23f9Smrg    inline valarray<_Tp>&						\
11084fee23f9Smrg    valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)		\
11094fee23f9Smrg    {									\
1110f9a78e0eSmrg      __glibcxx_assert(_M_size == __v._M_size);				\
11114fee23f9Smrg      _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, 		\
11124fee23f9Smrg			       _Array<_Tp>(__v._M_data));		\
11134fee23f9Smrg      return *this;							\
11144fee23f9Smrg    }
11154fee23f9Smrg
11164fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
11174fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
11184fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
11194fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
11204fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
11214fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
11224fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
11234fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
11244fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
11254fee23f9Smrg_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
11264fee23f9Smrg
11274fee23f9Smrg#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
11284fee23f9Smrg
11294fee23f9Smrg#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
11304fee23f9Smrg  template<class _Tp> template<class _Dom>				\
11314fee23f9Smrg    inline valarray<_Tp>&						\
11324fee23f9Smrg    valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e)		\
11334fee23f9Smrg    {									\
11344fee23f9Smrg      _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size);	\
11354fee23f9Smrg      return *this;							\
11364fee23f9Smrg    }
11374fee23f9Smrg
11384fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
11394fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
11404fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
11414fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
11424fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
11434fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
11444fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
11454fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
11464fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
11474fee23f9Smrg_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
11484fee23f9Smrg
11494fee23f9Smrg#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
11504fee23f9Smrg
11514fee23f9Smrg
11524fee23f9Smrg#define _DEFINE_BINARY_OPERATOR(_Op, _Name)				\
11534fee23f9Smrg  template<typename _Tp>						\
11544fee23f9Smrg    inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>,	\
11554fee23f9Smrg		 typename __fun<_Name, _Tp>::result_type>		\
11564fee23f9Smrg    operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)	\
11574fee23f9Smrg    {									\
1158f9a78e0eSmrg      __glibcxx_assert(__v.size() == __w.size());			\
11594fee23f9Smrg      typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure;	\
11604fee23f9Smrg      typedef typename __fun<_Name, _Tp>::result_type _Rt;		\
11614fee23f9Smrg      return _Expr<_Closure, _Rt>(_Closure(__v, __w));			\
11624fee23f9Smrg    }									\
11634fee23f9Smrg									\
11644fee23f9Smrg  template<typename _Tp>						\
11654fee23f9Smrg    inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>,	\
11664fee23f9Smrg		 typename __fun<_Name, _Tp>::result_type>		\
1167181254a7Smrg    operator _Op(const valarray<_Tp>& __v,				\
1168181254a7Smrg		 const typename valarray<_Tp>::value_type& __t)		\
11694fee23f9Smrg    {									\
11704fee23f9Smrg      typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure;	\
11714fee23f9Smrg      typedef typename __fun<_Name, _Tp>::result_type _Rt;		\
11724fee23f9Smrg      return _Expr<_Closure, _Rt>(_Closure(__v, __t));			\
11734fee23f9Smrg    }									\
11744fee23f9Smrg									\
11754fee23f9Smrg  template<typename _Tp>						\
11764fee23f9Smrg    inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>,	\
11774fee23f9Smrg		 typename __fun<_Name, _Tp>::result_type>		\
1178181254a7Smrg    operator _Op(const typename valarray<_Tp>::value_type& __t,		\
1179181254a7Smrg		 const valarray<_Tp>& __v)				\
11804fee23f9Smrg    {									\
11814fee23f9Smrg      typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure;	\
11824fee23f9Smrg      typedef typename __fun<_Name, _Tp>::result_type _Rt;		\
11834fee23f9Smrg      return _Expr<_Closure, _Rt>(_Closure(__t, __v));			\
11844fee23f9Smrg    }
11854fee23f9Smrg
11864fee23f9Smrg_DEFINE_BINARY_OPERATOR(+, __plus)
11874fee23f9Smrg_DEFINE_BINARY_OPERATOR(-, __minus)
11884fee23f9Smrg_DEFINE_BINARY_OPERATOR(*, __multiplies)
11894fee23f9Smrg_DEFINE_BINARY_OPERATOR(/, __divides)
11904fee23f9Smrg_DEFINE_BINARY_OPERATOR(%, __modulus)
11914fee23f9Smrg_DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
11924fee23f9Smrg_DEFINE_BINARY_OPERATOR(&, __bitwise_and)
11934fee23f9Smrg_DEFINE_BINARY_OPERATOR(|, __bitwise_or)
11944fee23f9Smrg_DEFINE_BINARY_OPERATOR(<<, __shift_left)
11954fee23f9Smrg_DEFINE_BINARY_OPERATOR(>>, __shift_right)
11964fee23f9Smrg_DEFINE_BINARY_OPERATOR(&&, __logical_and)
11974fee23f9Smrg_DEFINE_BINARY_OPERATOR(||, __logical_or)
11984fee23f9Smrg_DEFINE_BINARY_OPERATOR(==, __equal_to)
11994fee23f9Smrg_DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
12004fee23f9Smrg_DEFINE_BINARY_OPERATOR(<, __less)
12014fee23f9Smrg_DEFINE_BINARY_OPERATOR(>, __greater)
12024fee23f9Smrg_DEFINE_BINARY_OPERATOR(<=, __less_equal)
12034fee23f9Smrg_DEFINE_BINARY_OPERATOR(>=, __greater_equal)
12044fee23f9Smrg
12054fee23f9Smrg#undef _DEFINE_BINARY_OPERATOR
12067d4dc15bSmrg  /// @endcond
12074fee23f9Smrg
120848fb7bfaSmrg#if __cplusplus >= 201103L
120948fb7bfaSmrg  /**
121048fb7bfaSmrg   *  @brief  Return an iterator pointing to the first element of
121148fb7bfaSmrg   *          the valarray.
121248fb7bfaSmrg   *  @param  __va  valarray.
121348fb7bfaSmrg   */
121448fb7bfaSmrg  template<class _Tp>
1215b1e83836Smrg    [[__nodiscard__]]
121648fb7bfaSmrg    inline _Tp*
1217a448f87cSmrg    begin(valarray<_Tp>& __va) noexcept
1218a448f87cSmrg    { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
121948fb7bfaSmrg
122048fb7bfaSmrg  /**
122148fb7bfaSmrg   *  @brief  Return an iterator pointing to the first element of
122248fb7bfaSmrg   *          the const valarray.
122348fb7bfaSmrg   *  @param  __va  valarray.
122448fb7bfaSmrg   */
122548fb7bfaSmrg  template<class _Tp>
1226b1e83836Smrg    [[__nodiscard__]]
122748fb7bfaSmrg    inline const _Tp*
1228a448f87cSmrg    begin(const valarray<_Tp>& __va) noexcept
1229a448f87cSmrg    { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
123048fb7bfaSmrg
123148fb7bfaSmrg  /**
123248fb7bfaSmrg   *  @brief  Return an iterator pointing to one past the last element of
123348fb7bfaSmrg   *          the valarray.
123448fb7bfaSmrg   *  @param  __va  valarray.
123548fb7bfaSmrg   */
123648fb7bfaSmrg  template<class _Tp>
1237b1e83836Smrg    [[__nodiscard__]]
123848fb7bfaSmrg    inline _Tp*
1239a448f87cSmrg    end(valarray<_Tp>& __va) noexcept
1240a448f87cSmrg    {
1241a448f87cSmrg      if (auto __n = __va.size())
1242a448f87cSmrg	return std::__addressof(__va[0]) + __n;
1243a448f87cSmrg      else
1244a448f87cSmrg	return nullptr;
1245a448f87cSmrg    }
124648fb7bfaSmrg
124748fb7bfaSmrg  /**
124848fb7bfaSmrg   *  @brief  Return an iterator pointing to one past the last element of
124948fb7bfaSmrg   *          the const valarray.
125048fb7bfaSmrg   *  @param  __va  valarray.
125148fb7bfaSmrg   */
125248fb7bfaSmrg  template<class _Tp>
1253b1e83836Smrg    [[__nodiscard__]]
125448fb7bfaSmrg    inline const _Tp*
1255a448f87cSmrg    end(const valarray<_Tp>& __va) noexcept
1256a448f87cSmrg    {
1257a448f87cSmrg      if (auto __n = __va.size())
1258a448f87cSmrg	return std::__addressof(__va[0]) + __n;
1259a448f87cSmrg      else
1260a448f87cSmrg	return nullptr;
1261a448f87cSmrg    }
126248fb7bfaSmrg#endif // C++11
126348fb7bfaSmrg
1264a448f87cSmrg  /// @} group numeric_arrays
12654fee23f9Smrg
126648fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION
126748fb7bfaSmrg} // namespace
12684fee23f9Smrg
12694fee23f9Smrg#endif /* _GLIBCXX_VALARRAY */
1270