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