197403Sobrien// The template and inlines for the -*- C++ -*- valarray class. 297403Sobrien 3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 497403Sobrien// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien/** @file valarray 32169691Skan * This is a Standard C++ Library header. 3397403Sobrien */ 3497403Sobrien 35169691Skan// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> 36169691Skan 37132720Skan#ifndef _GLIBCXX_VALARRAY 38132720Skan#define _GLIBCXX_VALARRAY 1 3997403Sobrien 4097403Sobrien#pragma GCC system_header 4197403Sobrien 4297403Sobrien#include <bits/c++config.h> 4397403Sobrien#include <cstddef> 4497403Sobrien#include <cmath> 4597403Sobrien#include <cstdlib> 4697403Sobrien#include <numeric> 4797403Sobrien#include <algorithm> 48132720Skan#include <debug/debug.h> 4997403Sobrien 50169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 51169691Skan 52117397Skan template<class _Clos, typename _Tp> 53117397Skan class _Expr; 5497403Sobrien 55117397Skan template<typename _Tp1, typename _Tp2> 56117397Skan class _ValArray; 5797403Sobrien 58117397Skan template<class _Oper, template<class, class> class _Meta, class _Dom> 59117397Skan struct _UnClos; 6097403Sobrien 61117397Skan template<class _Oper, 6297403Sobrien template<class, class> class _Meta1, 6397403Sobrien template<class, class> class _Meta2, 64117397Skan class _Dom1, class _Dom2> 65117397Skan class _BinClos; 6697403Sobrien 67117397Skan template<template<class, class> class _Meta, class _Dom> 68117397Skan class _SClos; 6997403Sobrien 70117397Skan template<template<class, class> class _Meta, class _Dom> 71117397Skan class _GClos; 7297403Sobrien 73117397Skan template<template<class, class> class _Meta, class _Dom> 74117397Skan class _IClos; 7597403Sobrien 76117397Skan template<template<class, class> class _Meta, class _Dom> 77117397Skan class _ValFunClos; 78117397Skan 79117397Skan template<template<class, class> class _Meta, class _Dom> 80117397Skan class _RefFunClos; 8197403Sobrien 82117397Skan template<class _Tp> class valarray; // An array of type _Tp 83117397Skan class slice; // BLAS-like slice out of an array 84117397Skan template<class _Tp> class slice_array; 85117397Skan class gslice; // generalized slice out of an array 86117397Skan template<class _Tp> class gslice_array; 87117397Skan template<class _Tp> class mask_array; // masked array 88117397Skan template<class _Tp> class indirect_array; // indirected array 8997403Sobrien 90169691Skan_GLIBCXX_END_NAMESPACE 9197403Sobrien 9297403Sobrien#include <bits/valarray_array.h> 93132720Skan#include <bits/valarray_before.h> 9497403Sobrien 95169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 96169691Skan 97132720Skan /** 98132720Skan * @brief Smart array designed to support numeric processing. 99132720Skan * 100132720Skan * A valarray is an array that provides constraints intended to allow for 101132720Skan * effective optimization of numeric array processing by reducing the 102132720Skan * aliasing that can result from pointer representations. It represents a 103132720Skan * one-dimensional array from which different multidimensional subsets can 104132720Skan * be accessed and modified. 105132720Skan * 106132720Skan * @param Tp Type of object in the array. 107132720Skan */ 108117397Skan template<class _Tp> 109117397Skan class valarray 110117397Skan { 111117397Skan template<class _Op> 112117397Skan struct _UnaryOp 113117397Skan { 114117397Skan typedef typename __fun<_Op, _Tp>::result_type __rt; 115117397Skan typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; 116117397Skan }; 117117397Skan public: 11897403Sobrien typedef _Tp value_type; 119117397Skan 120117397Skan // _lib.valarray.cons_ construct/destroy: 121132720Skan /// Construct an empty array. 12297403Sobrien valarray(); 123132720Skan 124132720Skan /// Construct an array with @a n elements. 12597403Sobrien explicit valarray(size_t); 126132720Skan 127132720Skan /// Construct an array with @a n elements initialized to @a t. 12897403Sobrien valarray(const _Tp&, size_t); 129132720Skan 130132720Skan /// Construct an array initialized to the first @a n elements of @a t. 13197403Sobrien valarray(const _Tp* __restrict__, size_t); 132132720Skan 133132720Skan /// Copy constructor. 13497403Sobrien valarray(const valarray&); 135132720Skan 136132720Skan /// Construct an array with the same size and values in @a sa. 13797403Sobrien valarray(const slice_array<_Tp>&); 138132720Skan 139132720Skan /// Construct an array with the same size and values in @a ga. 14097403Sobrien valarray(const gslice_array<_Tp>&); 141132720Skan 142132720Skan /// Construct an array with the same size and values in @a ma. 14397403Sobrien valarray(const mask_array<_Tp>&); 144132720Skan 145132720Skan /// Construct an array with the same size and values in @a ia. 14697403Sobrien valarray(const indirect_array<_Tp>&); 147132720Skan 14897403Sobrien template<class _Dom> 149169691Skan valarray(const _Expr<_Dom, _Tp>& __e); 150169691Skan 151117397Skan ~valarray(); 15297403Sobrien 15397403Sobrien // _lib.valarray.assign_ assignment: 154132720Skan /** 155132720Skan * @brief Assign elements to an array. 156132720Skan * 157132720Skan * Assign elements of array to values in @a v. Results are undefined 158169691Skan * if @a v does not have the same size as this array. 159132720Skan * 160132720Skan * @param v Valarray to get values from. 161132720Skan */ 16297403Sobrien valarray<_Tp>& operator=(const valarray<_Tp>&); 163132720Skan 164132720Skan /** 165132720Skan * @brief Assign elements to a value. 166132720Skan * 167132720Skan * Assign all elements of array to @a t. 168132720Skan * 169132720Skan * @param t Value for elements. 170132720Skan */ 17197403Sobrien valarray<_Tp>& operator=(const _Tp&); 172132720Skan 173132720Skan /** 174132720Skan * @brief Assign elements to an array subset. 175132720Skan * 176132720Skan * Assign elements of array to values in @a sa. Results are undefined 177169691Skan * if @a sa does not have the same size as this array. 178132720Skan * 179132720Skan * @param sa Array slice to get values from. 180132720Skan */ 18197403Sobrien valarray<_Tp>& operator=(const slice_array<_Tp>&); 182132720Skan 183132720Skan /** 184132720Skan * @brief Assign elements to an array subset. 185132720Skan * 186132720Skan * Assign elements of array to values in @a ga. Results are undefined 187169691Skan * if @a ga does not have the same size as this array. 188132720Skan * 189132720Skan * @param ga Array slice to get values from. 190132720Skan */ 19197403Sobrien valarray<_Tp>& operator=(const gslice_array<_Tp>&); 192132720Skan 193132720Skan /** 194132720Skan * @brief Assign elements to an array subset. 195132720Skan * 196132720Skan * Assign elements of array to values in @a ma. Results are undefined 197169691Skan * if @a ma does not have the same size as this array. 198132720Skan * 199132720Skan * @param ma Array slice to get values from. 200132720Skan */ 20197403Sobrien valarray<_Tp>& operator=(const mask_array<_Tp>&); 202132720Skan 203132720Skan /** 204132720Skan * @brief Assign elements to an array subset. 205132720Skan * 206132720Skan * Assign elements of array to values in @a ia. Results are undefined 207169691Skan * if @a ia does not have the same size as this array. 208132720Skan * 209132720Skan * @param ia Array slice to get values from. 210132720Skan */ 21197403Sobrien valarray<_Tp>& operator=(const indirect_array<_Tp>&); 21297403Sobrien 21397403Sobrien template<class _Dom> valarray<_Tp>& 214169691Skan operator= (const _Expr<_Dom, _Tp>&); 21597403Sobrien 21697403Sobrien // _lib.valarray.access_ element access: 217132720Skan /** 218132720Skan * Return a reference to the i'th array element. 219132720Skan * 220132720Skan * @param i Index of element to return. 221132720Skan * @return Reference to the i'th element. 222132720Skan */ 223132720Skan _Tp& operator[](size_t); 224132720Skan 225132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 226132720Skan // 389. Const overload of valarray::operator[] returns by value. 227132720Skan const _Tp& operator[](size_t) const; 228132720Skan 22997403Sobrien // _lib.valarray.sub_ subset operations: 230132720Skan /** 231132720Skan * @brief Return an array subset. 232132720Skan * 233132720Skan * Returns a new valarray containing the elements of the array 234169691Skan * indicated by the slice argument. The new valarray has the same size 235169691Skan * as the input slice. @see slice. 236132720Skan * 237132720Skan * @param s The source slice. 238132720Skan * @return New valarray containing elements in @a s. 239132720Skan */ 240169691Skan _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice) const; 241132720Skan 242132720Skan /** 243132720Skan * @brief Return a reference to an array subset. 244132720Skan * 245132720Skan * Returns a new valarray containing the elements of the array 246169691Skan * indicated by the slice argument. The new valarray has the same size 247169691Skan * as the input slice. @see slice. 248132720Skan * 249132720Skan * @param s The source slice. 250132720Skan * @return New valarray containing elements in @a s. 251132720Skan */ 25297403Sobrien slice_array<_Tp> operator[](slice); 253132720Skan 254132720Skan /** 255132720Skan * @brief Return an array subset. 256132720Skan * 257132720Skan * Returns a slice_array referencing the elements of the array 258132720Skan * indicated by the slice argument. @see gslice. 259132720Skan * 260132720Skan * @param s The source slice. 261132720Skan * @return Slice_array referencing elements indicated by @a s. 262132720Skan */ 263169691Skan _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice&) const; 264132720Skan 265132720Skan /** 266132720Skan * @brief Return a reference to an array subset. 267132720Skan * 268132720Skan * Returns a new valarray containing the elements of the array 269169691Skan * indicated by the gslice argument. The new valarray has 270169691Skan * the same size as the input gslice. @see gslice. 271132720Skan * 272132720Skan * @param s The source gslice. 273132720Skan * @return New valarray containing elements in @a s. 274132720Skan */ 27597403Sobrien gslice_array<_Tp> operator[](const gslice&); 276132720Skan 277132720Skan /** 278132720Skan * @brief Return an array subset. 279132720Skan * 280132720Skan * Returns a new valarray containing the elements of the array 281132720Skan * indicated by the argument. The input is a valarray of bool which 282132720Skan * represents a bitmask indicating which elements should be copied into 283132720Skan * the new valarray. Each element of the array is added to the return 284132720Skan * valarray if the corresponding element of the argument is true. 285132720Skan * 286132720Skan * @param m The valarray bitmask. 287132720Skan * @return New valarray containing elements indicated by @a m. 288132720Skan */ 289169691Skan valarray<_Tp> operator[](const valarray<bool>&) const; 290132720Skan 291132720Skan /** 292132720Skan * @brief Return a reference to an array subset. 293132720Skan * 294132720Skan * Returns a new mask_array referencing the elements of the array 295132720Skan * indicated by the argument. The input is a valarray of bool which 296132720Skan * represents a bitmask indicating which elements are part of the 297132720Skan * subset. Elements of the array are part of the subset if the 298132720Skan * corresponding element of the argument is true. 299132720Skan * 300132720Skan * @param m The valarray bitmask. 301132720Skan * @return New valarray containing elements indicated by @a m. 302132720Skan */ 30397403Sobrien mask_array<_Tp> operator[](const valarray<bool>&); 304132720Skan 305132720Skan /** 306132720Skan * @brief Return an array subset. 307132720Skan * 308132720Skan * Returns a new valarray containing the elements of the array 309132720Skan * indicated by the argument. The elements in the argument are 310132720Skan * interpreted as the indices of elements of this valarray to copy to 311132720Skan * the return valarray. 312132720Skan * 313132720Skan * @param i The valarray element index list. 314132720Skan * @return New valarray containing elements in @a s. 315132720Skan */ 31697403Sobrien _Expr<_IClos<_ValArray, _Tp>, _Tp> 317117397Skan operator[](const valarray<size_t>&) const; 318132720Skan 319132720Skan /** 320132720Skan * @brief Return a reference to an array subset. 321132720Skan * 322132720Skan * Returns an indirect_array referencing the elements of the array 323132720Skan * indicated by the argument. The elements in the argument are 324132720Skan * interpreted as the indices of elements of this valarray to include 325132720Skan * in the subset. The returned indirect_array refers to these 326132720Skan * elements. 327132720Skan * 328132720Skan * @param i The valarray element index list. 329132720Skan * @return Indirect_array referencing elements in @a i. 330132720Skan */ 33197403Sobrien indirect_array<_Tp> operator[](const valarray<size_t>&); 33297403Sobrien 33397403Sobrien // _lib.valarray.unary_ unary operators: 334132720Skan /// Return a new valarray by applying unary + to each element. 335117397Skan typename _UnaryOp<__unary_plus>::_Rt operator+() const; 336132720Skan 337132720Skan /// Return a new valarray by applying unary - to each element. 338117397Skan typename _UnaryOp<__negate>::_Rt operator-() const; 339132720Skan 340132720Skan /// Return a new valarray by applying unary ~ to each element. 341117397Skan typename _UnaryOp<__bitwise_not>::_Rt operator~() const; 342132720Skan 343132720Skan /// Return a new valarray by applying unary ! to each element. 344117397Skan typename _UnaryOp<__logical_not>::_Rt operator!() const; 345117397Skan 34697403Sobrien // _lib.valarray.cassign_ computed assignment: 347132720Skan /// Multiply each element of array by @a t. 348117397Skan valarray<_Tp>& operator*=(const _Tp&); 349132720Skan 350132720Skan /// Divide each element of array by @a t. 351117397Skan valarray<_Tp>& operator/=(const _Tp&); 352132720Skan 353132720Skan /// Set each element e of array to e % @a t. 354117397Skan valarray<_Tp>& operator%=(const _Tp&); 355132720Skan 356132720Skan /// Add @a t to each element of array. 357117397Skan valarray<_Tp>& operator+=(const _Tp&); 358132720Skan 359132720Skan /// Subtract @a t to each element of array. 360117397Skan valarray<_Tp>& operator-=(const _Tp&); 361132720Skan 362132720Skan /// Set each element e of array to e ^ @a t. 363117397Skan valarray<_Tp>& operator^=(const _Tp&); 364132720Skan 365132720Skan /// Set each element e of array to e & @a t. 366117397Skan valarray<_Tp>& operator&=(const _Tp&); 367132720Skan 368132720Skan /// Set each element e of array to e | @a t. 369117397Skan valarray<_Tp>& operator|=(const _Tp&); 370132720Skan 371132720Skan /// Left shift each element e of array by @a t bits. 37297403Sobrien valarray<_Tp>& operator<<=(const _Tp&); 373132720Skan 374132720Skan /// Right shift each element e of array by @a t bits. 37597403Sobrien valarray<_Tp>& operator>>=(const _Tp&); 376132720Skan 377132720Skan /// Multiply elements of array by corresponding elements of @a v. 378117397Skan valarray<_Tp>& operator*=(const valarray<_Tp>&); 379132720Skan 380132720Skan /// Divide elements of array by corresponding elements of @a v. 381117397Skan valarray<_Tp>& operator/=(const valarray<_Tp>&); 382132720Skan 383132720Skan /// Modulo elements of array by corresponding elements of @a v. 384117397Skan valarray<_Tp>& operator%=(const valarray<_Tp>&); 385132720Skan 386132720Skan /// Add corresponding elements of @a v to elements of array. 387117397Skan valarray<_Tp>& operator+=(const valarray<_Tp>&); 388132720Skan 389132720Skan /// Subtract corresponding elements of @a v from elements of array. 390117397Skan valarray<_Tp>& operator-=(const valarray<_Tp>&); 391132720Skan 392132720Skan /// Logical xor corresponding elements of @a v with elements of array. 393117397Skan valarray<_Tp>& operator^=(const valarray<_Tp>&); 394132720Skan 395132720Skan /// Logical or corresponding elements of @a v with elements of array. 396117397Skan valarray<_Tp>& operator|=(const valarray<_Tp>&); 397132720Skan 398132720Skan /// Logical and corresponding elements of @a v with elements of array. 399117397Skan valarray<_Tp>& operator&=(const valarray<_Tp>&); 400132720Skan 401132720Skan /// Left shift elements of array by corresponding elements of @a v. 40297403Sobrien valarray<_Tp>& operator<<=(const valarray<_Tp>&); 403132720Skan 404132720Skan /// Right shift elements of array by corresponding elements of @a v. 40597403Sobrien valarray<_Tp>& operator>>=(const valarray<_Tp>&); 40697403Sobrien 40797403Sobrien template<class _Dom> 408169691Skan valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&); 40997403Sobrien template<class _Dom> 410169691Skan valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&); 41197403Sobrien template<class _Dom> 412169691Skan valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&); 41397403Sobrien template<class _Dom> 414169691Skan valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&); 41597403Sobrien template<class _Dom> 416169691Skan valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&); 41797403Sobrien template<class _Dom> 418169691Skan valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&); 41997403Sobrien template<class _Dom> 420169691Skan valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&); 42197403Sobrien template<class _Dom> 422169691Skan valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&); 42397403Sobrien template<class _Dom> 424169691Skan valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&); 42597403Sobrien template<class _Dom> 426169691Skan valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&); 42797403Sobrien 42897403Sobrien // _lib.valarray.members_ member functions: 429132720Skan /// Return the number of elements in array. 43097403Sobrien size_t size() const; 431132720Skan 432132720Skan /** 433132720Skan * @brief Return the sum of all elements in the array. 434132720Skan * 435132720Skan * Accumulates the sum of all elements into a Tp using +=. The order 436132720Skan * of adding the elements is unspecified. 437132720Skan */ 438132720Skan _Tp sum() const; 439132720Skan 440132720Skan /// Return the minimum element using operator<(). 44197403Sobrien _Tp min() const; 442132720Skan 443132720Skan /// Return the maximum element using operator<(). 44497403Sobrien _Tp max() const; 44597403Sobrien 446132720Skan /** 447132720Skan * @brief Return a shifted array. 448132720Skan * 449132720Skan * A new valarray is constructed as a copy of this array with elements 450132720Skan * in shifted positions. For an element with index i, the new position 451169691Skan * is i - n. The new valarray has the same size as the current one. 452169691Skan * New elements without a value are set to 0. Elements whose new 453132720Skan * position is outside the bounds of the array are discarded. 454132720Skan * 455132720Skan * Positive arguments shift toward index 0, discarding elements [0, n). 456132720Skan * Negative arguments discard elements from the top of the array. 457132720Skan * 458132720Skan * @param n Number of element positions to shift. 459132720Skan * @return New valarray with elements in shifted positions. 460132720Skan */ 46197403Sobrien valarray<_Tp> shift (int) const; 462132720Skan 463132720Skan /** 464132720Skan * @brief Return a rotated array. 465132720Skan * 466132720Skan * A new valarray is constructed as a copy of this array with elements 467132720Skan * in shifted positions. For an element with index i, the new position 468169691Skan * is (i - n) % size(). The new valarray has the same size as the 469132720Skan * current one. Elements that are shifted beyond the array bounds are 470132720Skan * shifted into the other end of the array. No elements are lost. 471132720Skan * 472132720Skan * Positive arguments shift toward index 0, wrapping around the top. 473132720Skan * Negative arguments shift towards the top, wrapping around to 0. 474132720Skan * 475132720Skan * @param n Number of element positions to rotate. 476132720Skan * @return New valarray with elements in shifted positions. 477132720Skan */ 47897403Sobrien valarray<_Tp> cshift(int) const; 479132720Skan 480132720Skan /** 481132720Skan * @brief Apply a function to the array. 482132720Skan * 483132720Skan * Returns a new valarray with elements assigned to the result of 484132720Skan * applying func to the corresponding element of this array. The new 485169691Skan * array has the same size as this one. 486132720Skan * 487132720Skan * @param func Function of Tp returning Tp to apply. 488132720Skan * @return New valarray with transformed elements. 489132720Skan */ 490169691Skan _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const; 491132720Skan 492132720Skan /** 493132720Skan * @brief Apply a function to the array. 494132720Skan * 495132720Skan * Returns a new valarray with elements assigned to the result of 496132720Skan * applying func to the corresponding element of this array. The new 497169691Skan * array has the same size as this one. 498132720Skan * 499132720Skan * @param func Function of const Tp& returning Tp to apply. 500132720Skan * @return New valarray with transformed elements. 501132720Skan */ 502169691Skan _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const; 503132720Skan 504132720Skan /** 505132720Skan * @brief Resize array. 506132720Skan * 507169691Skan * Resize this array to @a size and set all elements to @a c. All 508132720Skan * references and iterators are invalidated. 509132720Skan * 510132720Skan * @param size New array size. 511132720Skan * @param c New value for all elements. 512132720Skan */ 51397403Sobrien void resize(size_t __size, _Tp __c = _Tp()); 51497403Sobrien 515117397Skan private: 51697403Sobrien size_t _M_size; 51797403Sobrien _Tp* __restrict__ _M_data; 518117397Skan 51997403Sobrien friend class _Array<_Tp>; 520117397Skan }; 52197403Sobrien 52297403Sobrien template<typename _Tp> 523117397Skan inline const _Tp& 524117397Skan valarray<_Tp>::operator[](size_t __i) const 525132720Skan { 526132720Skan __glibcxx_requires_subscript(__i); 527169691Skan return _M_data[__i]; 528132720Skan } 52997403Sobrien 53097403Sobrien template<typename _Tp> 531117397Skan inline _Tp& 532117397Skan valarray<_Tp>::operator[](size_t __i) 533132720Skan { 534132720Skan __glibcxx_requires_subscript(__i); 535169691Skan return _M_data[__i]; 536132720Skan } 53797403Sobrien 538169691Skan_GLIBCXX_END_NAMESPACE 539132720Skan 540132720Skan#include <bits/valarray_after.h> 54197403Sobrien#include <bits/slice_array.h> 54297403Sobrien#include <bits/gslice.h> 54397403Sobrien#include <bits/gslice_array.h> 54497403Sobrien#include <bits/mask_array.h> 54597403Sobrien#include <bits/indirect_array.h> 54697403Sobrien 547169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 548169691Skan 54997403Sobrien template<typename _Tp> 550117397Skan inline 551117397Skan valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {} 55297403Sobrien 55397403Sobrien template<typename _Tp> 554117397Skan inline 555117397Skan valarray<_Tp>::valarray(size_t __n) 556169691Skan : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) 557132720Skan { std::__valarray_default_construct(_M_data, _M_data + __n); } 55897403Sobrien 55997403Sobrien template<typename _Tp> 560117397Skan inline 561117397Skan valarray<_Tp>::valarray(const _Tp& __t, size_t __n) 562169691Skan : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) 563132720Skan { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } 56497403Sobrien 56597403Sobrien template<typename _Tp> 566117397Skan inline 567117397Skan valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) 568169691Skan : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) 569132720Skan { 570132720Skan _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0); 571132720Skan std::__valarray_copy_construct(__p, __p + __n, _M_data); 572132720Skan } 57397403Sobrien 57497403Sobrien template<typename _Tp> 575117397Skan inline 576117397Skan valarray<_Tp>::valarray(const valarray<_Tp>& __v) 577169691Skan : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) 578169691Skan { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, 579169691Skan _M_data); } 58097403Sobrien 58197403Sobrien template<typename _Tp> 582117397Skan inline 583117397Skan valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) 584169691Skan : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) 585117397Skan { 586169691Skan std::__valarray_copy_construct 587117397Skan (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); 588117397Skan } 58997403Sobrien 59097403Sobrien template<typename _Tp> 591117397Skan inline 592117397Skan valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) 593169691Skan : _M_size(__ga._M_index.size()), 594169691Skan _M_data(__valarray_get_storage<_Tp>(_M_size)) 595117397Skan { 596169691Skan std::__valarray_copy_construct 597117397Skan (__ga._M_array, _Array<size_t>(__ga._M_index), 598117397Skan _Array<_Tp>(_M_data), _M_size); 599117397Skan } 60097403Sobrien 60197403Sobrien template<typename _Tp> 602117397Skan inline 603117397Skan valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) 604169691Skan : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) 605117397Skan { 606169691Skan std::__valarray_copy_construct 607117397Skan (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); 608117397Skan } 60997403Sobrien 61097403Sobrien template<typename _Tp> 611117397Skan inline 612117397Skan valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) 613169691Skan : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) 614117397Skan { 615169691Skan std::__valarray_copy_construct 616117397Skan (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); 617117397Skan } 61897403Sobrien 61997403Sobrien template<typename _Tp> template<class _Dom> 620117397Skan inline 621117397Skan valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) 622169691Skan : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) 623169691Skan { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } 62497403Sobrien 62597403Sobrien template<typename _Tp> 626117397Skan inline 627117397Skan valarray<_Tp>::~valarray() 628117397Skan { 629132720Skan std::__valarray_destroy_elements(_M_data, _M_data + _M_size); 630132720Skan std::__valarray_release_memory(_M_data); 631117397Skan } 63297403Sobrien 63397403Sobrien template<typename _Tp> 634117397Skan inline valarray<_Tp>& 635117397Skan valarray<_Tp>::operator=(const valarray<_Tp>& __v) 636117397Skan { 637132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); 638132720Skan std::__valarray_copy(__v._M_data, _M_size, _M_data); 63997403Sobrien return *this; 640117397Skan } 64197403Sobrien 64297403Sobrien template<typename _Tp> 643117397Skan inline valarray<_Tp>& 644117397Skan valarray<_Tp>::operator=(const _Tp& __t) 645117397Skan { 646132720Skan std::__valarray_fill(_M_data, _M_size, __t); 64797403Sobrien return *this; 648117397Skan } 64997403Sobrien 65097403Sobrien template<typename _Tp> 651117397Skan inline valarray<_Tp>& 652117397Skan valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) 653117397Skan { 654132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz); 655132720Skan std::__valarray_copy(__sa._M_array, __sa._M_sz, 656132720Skan __sa._M_stride, _Array<_Tp>(_M_data)); 65797403Sobrien return *this; 658117397Skan } 65997403Sobrien 66097403Sobrien template<typename _Tp> 661117397Skan inline valarray<_Tp>& 662117397Skan valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) 663117397Skan { 664132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size()); 665132720Skan std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index), 666132720Skan _Array<_Tp>(_M_data), _M_size); 66797403Sobrien return *this; 668117397Skan } 66997403Sobrien 67097403Sobrien template<typename _Tp> 671117397Skan inline valarray<_Tp>& 672117397Skan valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) 673117397Skan { 674132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz); 675132720Skan std::__valarray_copy(__ma._M_array, __ma._M_mask, 676132720Skan _Array<_Tp>(_M_data), _M_size); 67797403Sobrien return *this; 678117397Skan } 67997403Sobrien 68097403Sobrien template<typename _Tp> 681117397Skan inline valarray<_Tp>& 682117397Skan valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) 683117397Skan { 684132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz); 685132720Skan std::__valarray_copy(__ia._M_array, __ia._M_index, 686132720Skan _Array<_Tp>(_M_data), _M_size); 68797403Sobrien return *this; 688117397Skan } 68997403Sobrien 69097403Sobrien template<typename _Tp> template<class _Dom> 691117397Skan inline valarray<_Tp>& 692117397Skan valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) 693117397Skan { 694132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size()); 695132720Skan std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); 696132720Skan return *this; 697117397Skan } 69897403Sobrien 69997403Sobrien template<typename _Tp> 700117397Skan inline _Expr<_SClos<_ValArray,_Tp>, _Tp> 701117397Skan valarray<_Tp>::operator[](slice __s) const 702117397Skan { 70397403Sobrien typedef _SClos<_ValArray,_Tp> _Closure; 704117397Skan return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); 705117397Skan } 70697403Sobrien 70797403Sobrien template<typename _Tp> 708117397Skan inline slice_array<_Tp> 709117397Skan valarray<_Tp>::operator[](slice __s) 710169691Skan { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); } 71197403Sobrien 71297403Sobrien template<typename _Tp> 713117397Skan inline _Expr<_GClos<_ValArray,_Tp>, _Tp> 714117397Skan valarray<_Tp>::operator[](const gslice& __gs) const 715117397Skan { 71697403Sobrien typedef _GClos<_ValArray,_Tp> _Closure; 71797403Sobrien return _Expr<_Closure, _Tp> 718117397Skan (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); 719117397Skan } 72097403Sobrien 72197403Sobrien template<typename _Tp> 722117397Skan inline gslice_array<_Tp> 723117397Skan valarray<_Tp>::operator[](const gslice& __gs) 724117397Skan { 72597403Sobrien return gslice_array<_Tp> 726117397Skan (_Array<_Tp>(_M_data), __gs._M_index->_M_index); 727117397Skan } 72897403Sobrien 72997403Sobrien template<typename _Tp> 730117397Skan inline valarray<_Tp> 731117397Skan valarray<_Tp>::operator[](const valarray<bool>& __m) const 732117397Skan { 733117397Skan size_t __s = 0; 734117397Skan size_t __e = __m.size(); 73597403Sobrien for (size_t __i=0; __i<__e; ++__i) 736117397Skan if (__m[__i]) ++__s; 737117397Skan return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, 738117397Skan _Array<bool> (__m))); 739117397Skan } 74097403Sobrien 74197403Sobrien template<typename _Tp> 742117397Skan inline mask_array<_Tp> 743117397Skan valarray<_Tp>::operator[](const valarray<bool>& __m) 744117397Skan { 745117397Skan size_t __s = 0; 746117397Skan size_t __e = __m.size(); 74797403Sobrien for (size_t __i=0; __i<__e; ++__i) 748117397Skan if (__m[__i]) ++__s; 749117397Skan return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m)); 750117397Skan } 75197403Sobrien 75297403Sobrien template<typename _Tp> 753117397Skan inline _Expr<_IClos<_ValArray,_Tp>, _Tp> 754117397Skan valarray<_Tp>::operator[](const valarray<size_t>& __i) const 755117397Skan { 75697403Sobrien typedef _IClos<_ValArray,_Tp> _Closure; 757117397Skan return _Expr<_Closure, _Tp>(_Closure(*this, __i)); 758117397Skan } 75997403Sobrien 76097403Sobrien template<typename _Tp> 761117397Skan inline indirect_array<_Tp> 762117397Skan valarray<_Tp>::operator[](const valarray<size_t>& __i) 763117397Skan { 764117397Skan return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), 765117397Skan _Array<size_t>(__i)); 766117397Skan } 76797403Sobrien 76897403Sobrien template<class _Tp> 769117397Skan inline size_t 770117397Skan valarray<_Tp>::size() const 771117397Skan { return _M_size; } 77297403Sobrien 77397403Sobrien template<class _Tp> 774117397Skan inline _Tp 775117397Skan valarray<_Tp>::sum() const 776117397Skan { 777132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size > 0); 778132720Skan return std::__valarray_sum(_M_data, _M_data + _M_size); 779117397Skan } 78097403Sobrien 781169691Skan template<class _Tp> 78297403Sobrien inline valarray<_Tp> 78397403Sobrien valarray<_Tp>::shift(int __n) const 78497403Sobrien { 785169691Skan valarray<_Tp> __ret; 786169691Skan 787169691Skan if (_M_size == 0) 788169691Skan return __ret; 789169691Skan 790169691Skan _Tp* __restrict__ __tmp_M_data = 791169691Skan std::__valarray_get_storage<_Tp>(_M_size); 792169691Skan 793169691Skan if (__n == 0) 794169691Skan std::__valarray_copy_construct(_M_data, 795169691Skan _M_data + _M_size, __tmp_M_data); 796169691Skan else if (__n > 0) // shift left 797169691Skan { 798169691Skan if (size_t(__n) > _M_size) 799169691Skan __n = _M_size; 800169691Skan 801169691Skan std::__valarray_copy_construct(_M_data + __n, 802169691Skan _M_data + _M_size, __tmp_M_data); 803169691Skan std::__valarray_default_construct(__tmp_M_data + _M_size - __n, 804169691Skan __tmp_M_data + _M_size); 805169691Skan } 806169691Skan else // shift right 807169691Skan { 808169691Skan if (size_t(-__n) > _M_size) 809169691Skan __n = -_M_size; 810169691Skan 811169691Skan std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, 812169691Skan __tmp_M_data - __n); 813169691Skan std::__valarray_default_construct(__tmp_M_data, 814169691Skan __tmp_M_data - __n); 815169691Skan } 816169691Skan 817169691Skan __ret._M_size = _M_size; 818169691Skan __ret._M_data = __tmp_M_data; 819169691Skan return __ret; 82097403Sobrien } 82197403Sobrien 822169691Skan template<class _Tp> 82397403Sobrien inline valarray<_Tp> 824169691Skan valarray<_Tp>::cshift(int __n) const 82597403Sobrien { 826169691Skan valarray<_Tp> __ret; 827169691Skan 828169691Skan if (_M_size == 0) 829169691Skan return __ret; 830169691Skan 831169691Skan _Tp* __restrict__ __tmp_M_data = 832169691Skan std::__valarray_get_storage<_Tp>(_M_size); 833169691Skan 834169691Skan if (__n == 0) 835169691Skan std::__valarray_copy_construct(_M_data, 836169691Skan _M_data + _M_size, __tmp_M_data); 837169691Skan else if (__n > 0) // cshift left 838169691Skan { 839169691Skan if (size_t(__n) > _M_size) 840169691Skan __n = __n % _M_size; 841169691Skan 842169691Skan std::__valarray_copy_construct(_M_data, _M_data + __n, 843169691Skan __tmp_M_data + _M_size - __n); 844169691Skan std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, 845169691Skan __tmp_M_data); 846169691Skan } 847169691Skan else // cshift right 848169691Skan { 849169691Skan if (size_t(-__n) > _M_size) 850169691Skan __n = -(size_t(-__n) % _M_size); 851169691Skan 852169691Skan std::__valarray_copy_construct(_M_data + _M_size + __n, 853169691Skan _M_data + _M_size, __tmp_M_data); 854169691Skan std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, 855169691Skan __tmp_M_data - __n); 856169691Skan } 857169691Skan 858169691Skan __ret._M_size = _M_size; 859169691Skan __ret._M_data = __tmp_M_data; 860169691Skan return __ret; 86197403Sobrien } 86297403Sobrien 863169691Skan template<class _Tp> 864117397Skan inline void 865169691Skan valarray<_Tp>::resize(size_t __n, _Tp __c) 866117397Skan { 867117397Skan // This complication is so to make valarray<valarray<T> > work 868117397Skan // even though it is not required by the standard. Nobody should 869117397Skan // be saying valarray<valarray<T> > anyway. See the specs. 870132720Skan std::__valarray_destroy_elements(_M_data, _M_data + _M_size); 871117397Skan if (_M_size != __n) 872117397Skan { 873132720Skan std::__valarray_release_memory(_M_data); 874117397Skan _M_size = __n; 875117397Skan _M_data = __valarray_get_storage<_Tp>(__n); 876117397Skan } 877132720Skan std::__valarray_fill_construct(_M_data, _M_data + __n, __c); 878117397Skan } 87997403Sobrien 88097403Sobrien template<typename _Tp> 881117397Skan inline _Tp 882117397Skan valarray<_Tp>::min() const 883117397Skan { 884132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size > 0); 885169691Skan return *std::min_element(_M_data, _M_data+_M_size); 886117397Skan } 88797403Sobrien 88897403Sobrien template<typename _Tp> 889117397Skan inline _Tp 890117397Skan valarray<_Tp>::max() const 891117397Skan { 892132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size > 0); 893169691Skan return *std::max_element(_M_data, _M_data+_M_size); 894117397Skan } 89597403Sobrien 89697403Sobrien template<class _Tp> 897169691Skan inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> 898117397Skan valarray<_Tp>::apply(_Tp func(_Tp)) const 899117397Skan { 900169691Skan typedef _ValFunClos<_ValArray, _Tp> _Closure; 901169691Skan return _Expr<_Closure, _Tp>(_Closure(*this, func)); 902117397Skan } 90397403Sobrien 90497403Sobrien template<class _Tp> 905169691Skan inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> 906117397Skan valarray<_Tp>::apply(_Tp func(const _Tp &)) const 907117397Skan { 908169691Skan typedef _RefFunClos<_ValArray, _Tp> _Closure; 909169691Skan return _Expr<_Closure, _Tp>(_Closure(*this, func)); 910117397Skan } 91197403Sobrien 91297403Sobrien#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ 91397403Sobrien template<typename _Tp> \ 914169691Skan inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ 915169691Skan valarray<_Tp>::operator _Op() const \ 916169691Skan { \ 917169691Skan typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \ 918169691Skan typedef typename __fun<_Name, _Tp>::result_type _Rt; \ 919169691Skan return _Expr<_Closure, _Rt>(_Closure(*this)); \ 920169691Skan } 92197403Sobrien 922117397Skan _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) 923117397Skan _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) 924117397Skan _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) 925117397Skan _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) 92697403Sobrien 92797403Sobrien#undef _DEFINE_VALARRAY_UNARY_OPERATOR 92897403Sobrien 92997403Sobrien#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ 93097403Sobrien template<class _Tp> \ 931117397Skan inline valarray<_Tp>& \ 932117397Skan valarray<_Tp>::operator _Op##=(const _Tp &__t) \ 933117397Skan { \ 934117397Skan _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ 93597403Sobrien return *this; \ 936117397Skan } \ 93797403Sobrien \ 93897403Sobrien template<class _Tp> \ 939117397Skan inline valarray<_Tp>& \ 940117397Skan valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ 941117397Skan { \ 942132720Skan _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \ 943117397Skan _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ 944117397Skan _Array<_Tp>(__v._M_data)); \ 94597403Sobrien return *this; \ 946117397Skan } 94797403Sobrien 948117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) 949117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) 950117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) 951117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) 952117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) 953117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) 954117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) 955117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) 956117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) 957117397Skan_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) 95897403Sobrien 95997403Sobrien#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT 96097403Sobrien 96197403Sobrien#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ 96297403Sobrien template<class _Tp> template<class _Dom> \ 963117397Skan inline valarray<_Tp>& \ 964169691Skan valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \ 965117397Skan { \ 966117397Skan _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ 96797403Sobrien return *this; \ 968117397Skan } 96997403Sobrien 970117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) 971117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) 972117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) 973117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) 974117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) 975117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) 976117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) 977117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) 978117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) 979117397Skan_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) 98097403Sobrien 98197403Sobrien#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT 98297403Sobrien 98397403Sobrien 98497403Sobrien#define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ 98597403Sobrien template<typename _Tp> \ 986169691Skan inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \ 987117397Skan typename __fun<_Name, _Tp>::result_type> \ 988117397Skan operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ 989117397Skan { \ 990132720Skan _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \ 991169691Skan typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ 992117397Skan typedef typename __fun<_Name, _Tp>::result_type _Rt; \ 993117397Skan return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ 994117397Skan } \ 99597403Sobrien \ 99697403Sobrien template<typename _Tp> \ 997169691Skan inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \ 998169691Skan typename __fun<_Name, _Tp>::result_type> \ 999169691Skan operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \ 1000169691Skan { \ 1001169691Skan typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \ 1002169691Skan typedef typename __fun<_Name, _Tp>::result_type _Rt; \ 1003169691Skan return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ 1004169691Skan } \ 100597403Sobrien \ 100697403Sobrien template<typename _Tp> \ 1007169691Skan inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \ 1008169691Skan typename __fun<_Name, _Tp>::result_type> \ 1009169691Skan operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \ 1010169691Skan { \ 1011169691Skan typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \ 1012169691Skan typedef typename __fun<_Name, _Tp>::result_type _Rt; \ 1013220150Smm return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \ 1014169691Skan } 101597403Sobrien 1016117397Skan_DEFINE_BINARY_OPERATOR(+, __plus) 1017117397Skan_DEFINE_BINARY_OPERATOR(-, __minus) 1018117397Skan_DEFINE_BINARY_OPERATOR(*, __multiplies) 1019117397Skan_DEFINE_BINARY_OPERATOR(/, __divides) 1020117397Skan_DEFINE_BINARY_OPERATOR(%, __modulus) 1021117397Skan_DEFINE_BINARY_OPERATOR(^, __bitwise_xor) 1022117397Skan_DEFINE_BINARY_OPERATOR(&, __bitwise_and) 1023117397Skan_DEFINE_BINARY_OPERATOR(|, __bitwise_or) 1024117397Skan_DEFINE_BINARY_OPERATOR(<<, __shift_left) 1025117397Skan_DEFINE_BINARY_OPERATOR(>>, __shift_right) 1026117397Skan_DEFINE_BINARY_OPERATOR(&&, __logical_and) 1027117397Skan_DEFINE_BINARY_OPERATOR(||, __logical_or) 1028117397Skan_DEFINE_BINARY_OPERATOR(==, __equal_to) 1029117397Skan_DEFINE_BINARY_OPERATOR(!=, __not_equal_to) 1030117397Skan_DEFINE_BINARY_OPERATOR(<, __less) 1031117397Skan_DEFINE_BINARY_OPERATOR(>, __greater) 1032117397Skan_DEFINE_BINARY_OPERATOR(<=, __less_equal) 1033117397Skan_DEFINE_BINARY_OPERATOR(>=, __greater_equal) 103497403Sobrien 1035169691Skan#undef _DEFINE_BINARY_OPERATOR 103697403Sobrien 1037169691Skan_GLIBCXX_END_NAMESPACE 1038169691Skan 1039132720Skan#endif /* _GLIBCXX_VALARRAY */ 1040