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