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