1 // The template and inlines for the -*- C++ -*- valarray class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5 // Free Software Foundation, Inc.
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 2, or (at your option)
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.
18 // You should have received a copy of the GNU General Public License
19 // along with this library; see the file COPYING. If not, write to
20 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301, USA.
23 // As a special exception, you may use this file as part of a free software
24 // library without restriction. Specifically, if other files instantiate
25 // templates or use macros or inline functions from this file, or you compile
26 // this file and link it with other files to produce an executable, this
27 // file does not by itself cause the resulting executable to be covered by
28 // the GNU General Public License. This exception does not however
29 // invalidate any other reasons why the executable file might be covered by
30 // the GNU General Public License.
33 * This is a Standard C++ Library header.
36 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
38 #ifndef _GLIBCXX_VALARRAY
39 #define _GLIBCXX_VALARRAY 1
41 #pragma GCC system_header
43 #include <bits/c++config.h>
47 #include <debug/debug.h>
49 _GLIBCXX_BEGIN_NAMESPACE(std)
51 template<class _Clos, typename _Tp>
54 template<typename _Tp1, typename _Tp2>
57 template<class _Oper, template<class, class> class _Meta, class _Dom>
61 template<class, class> class _Meta1,
62 template<class, class> class _Meta2,
63 class _Dom1, class _Dom2>
66 template<template<class, class> class _Meta, class _Dom>
69 template<template<class, class> class _Meta, class _Dom>
72 template<template<class, class> class _Meta, class _Dom>
75 template<template<class, class> class _Meta, class _Dom>
78 template<template<class, class> class _Meta, class _Dom>
81 template<class _Tp> class valarray; // An array of type _Tp
82 class slice; // BLAS-like slice out of an array
83 template<class _Tp> class slice_array;
84 class gslice; // generalized slice out of an array
85 template<class _Tp> class gslice_array;
86 template<class _Tp> class mask_array; // masked array
87 template<class _Tp> class indirect_array; // indirected array
89 _GLIBCXX_END_NAMESPACE
91 #include <bits/valarray_array.h>
92 #include <bits/valarray_before.h>
94 _GLIBCXX_BEGIN_NAMESPACE(std)
97 * @brief Smart array designed to support numeric processing.
99 * A valarray is an array that provides constraints intended to allow for
100 * effective optimization of numeric array processing by reducing the
101 * aliasing that can result from pointer representations. It represents a
102 * one-dimensional array from which different multidimensional subsets can
103 * be accessed and modified.
105 * @param Tp Type of object in the array.
113 typedef typename __fun<_Op, _Tp>::result_type __rt;
114 typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
117 typedef _Tp value_type;
119 // _lib.valarray.cons_ construct/destroy:
120 /// Construct an empty array.
123 /// Construct an array with @a n elements.
124 explicit valarray(size_t);
126 /// Construct an array with @a n elements initialized to @a t.
127 valarray(const _Tp&, size_t);
129 /// Construct an array initialized to the first @a n elements of @a t.
130 valarray(const _Tp* __restrict__, size_t);
132 /// Copy constructor.
133 valarray(const valarray&);
135 /// Construct an array with the same size and values in @a sa.
136 valarray(const slice_array<_Tp>&);
138 /// Construct an array with the same size and values in @a ga.
139 valarray(const gslice_array<_Tp>&);
141 /// Construct an array with the same size and values in @a ma.
142 valarray(const mask_array<_Tp>&);
144 /// Construct an array with the same size and values in @a ia.
145 valarray(const indirect_array<_Tp>&);
148 valarray(const _Expr<_Dom, _Tp>& __e);
152 // _lib.valarray.assign_ assignment:
154 * @brief Assign elements to an array.
156 * Assign elements of array to values in @a v. Results are undefined
157 * if @a v does not have the same size as this array.
159 * @param v Valarray to get values from.
161 valarray<_Tp>& operator=(const valarray<_Tp>&);
164 * @brief Assign elements to a value.
166 * Assign all elements of array to @a t.
168 * @param t Value for elements.
170 valarray<_Tp>& operator=(const _Tp&);
173 * @brief Assign elements to an array subset.
175 * Assign elements of array to values in @a sa. Results are undefined
176 * if @a sa does not have the same size as this array.
178 * @param sa Array slice to get values from.
180 valarray<_Tp>& operator=(const slice_array<_Tp>&);
183 * @brief Assign elements to an array subset.
185 * Assign elements of array to values in @a ga. Results are undefined
186 * if @a ga does not have the same size as this array.
188 * @param ga Array slice to get values from.
190 valarray<_Tp>& operator=(const gslice_array<_Tp>&);
193 * @brief Assign elements to an array subset.
195 * Assign elements of array to values in @a ma. Results are undefined
196 * if @a ma does not have the same size as this array.
198 * @param ma Array slice to get values from.
200 valarray<_Tp>& operator=(const mask_array<_Tp>&);
203 * @brief Assign elements to an array subset.
205 * Assign elements of array to values in @a ia. Results are undefined
206 * if @a ia does not have the same size as this array.
208 * @param ia Array slice to get values from.
210 valarray<_Tp>& operator=(const indirect_array<_Tp>&);
212 template<class _Dom> valarray<_Tp>&
213 operator= (const _Expr<_Dom, _Tp>&);
215 // _lib.valarray.access_ element access:
217 * Return a reference to the i'th array element.
219 * @param i Index of element to return.
220 * @return Reference to the i'th element.
222 _Tp& operator[](size_t);
224 // _GLIBCXX_RESOLVE_LIB_DEFECTS
225 // 389. Const overload of valarray::operator[] returns by value.
226 const _Tp& operator[](size_t) const;
228 // _lib.valarray.sub_ subset operations:
230 * @brief Return an array subset.
232 * Returns a new valarray containing the elements of the array
233 * indicated by the slice argument. The new valarray has the same size
234 * as the input slice. @see slice.
236 * @param s The source slice.
237 * @return New valarray containing elements in @a s.
239 _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice) const;
242 * @brief Return a reference to an array subset.
244 * Returns a new valarray containing the elements of the array
245 * indicated by the slice argument. The new valarray has the same size
246 * as the input slice. @see slice.
248 * @param s The source slice.
249 * @return New valarray containing elements in @a s.
251 slice_array<_Tp> operator[](slice);
254 * @brief Return an array subset.
256 * Returns a slice_array referencing the elements of the array
257 * indicated by the slice argument. @see gslice.
259 * @param s The source slice.
260 * @return Slice_array referencing elements indicated by @a s.
262 _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice&) const;
265 * @brief Return a reference to an array subset.
267 * Returns a new valarray containing the elements of the array
268 * indicated by the gslice argument. The new valarray has
269 * the same size as the input gslice. @see gslice.
271 * @param s The source gslice.
272 * @return New valarray containing elements in @a s.
274 gslice_array<_Tp> operator[](const gslice&);
277 * @brief Return an array subset.
279 * Returns a new valarray containing the elements of the array
280 * indicated by the argument. The input is a valarray of bool which
281 * represents a bitmask indicating which elements should be copied into
282 * the new valarray. Each element of the array is added to the return
283 * valarray if the corresponding element of the argument is true.
285 * @param m The valarray bitmask.
286 * @return New valarray containing elements indicated by @a m.
288 valarray<_Tp> operator[](const valarray<bool>&) const;
291 * @brief Return a reference to an array subset.
293 * Returns a new mask_array referencing the elements of the array
294 * indicated by the argument. The input is a valarray of bool which
295 * represents a bitmask indicating which elements are part of the
296 * subset. Elements of the array are part of the subset if the
297 * corresponding element of the argument is true.
299 * @param m The valarray bitmask.
300 * @return New valarray containing elements indicated by @a m.
302 mask_array<_Tp> operator[](const valarray<bool>&);
305 * @brief Return an array subset.
307 * Returns a new valarray containing the elements of the array
308 * indicated by the argument. The elements in the argument are
309 * interpreted as the indices of elements of this valarray to copy to
310 * the return valarray.
312 * @param i The valarray element index list.
313 * @return New valarray containing elements in @a s.
315 _Expr<_IClos<_ValArray, _Tp>, _Tp>
316 operator[](const valarray<size_t>&) const;
319 * @brief Return a reference to an array subset.
321 * Returns an indirect_array referencing the elements of the array
322 * indicated by the argument. The elements in the argument are
323 * interpreted as the indices of elements of this valarray to include
324 * in the subset. The returned indirect_array refers to these
327 * @param i The valarray element index list.
328 * @return Indirect_array referencing elements in @a i.
330 indirect_array<_Tp> operator[](const valarray<size_t>&);
332 // _lib.valarray.unary_ unary operators:
333 /// Return a new valarray by applying unary + to each element.
334 typename _UnaryOp<__unary_plus>::_Rt operator+() const;
336 /// Return a new valarray by applying unary - to each element.
337 typename _UnaryOp<__negate>::_Rt operator-() const;
339 /// Return a new valarray by applying unary ~ to each element.
340 typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
342 /// Return a new valarray by applying unary ! to each element.
343 typename _UnaryOp<__logical_not>::_Rt operator!() const;
345 // _lib.valarray.cassign_ computed assignment:
346 /// Multiply each element of array by @a t.
347 valarray<_Tp>& operator*=(const _Tp&);
349 /// Divide each element of array by @a t.
350 valarray<_Tp>& operator/=(const _Tp&);
352 /// Set each element e of array to e % @a t.
353 valarray<_Tp>& operator%=(const _Tp&);
355 /// Add @a t to each element of array.
356 valarray<_Tp>& operator+=(const _Tp&);
358 /// Subtract @a t to each element of array.
359 valarray<_Tp>& operator-=(const _Tp&);
361 /// Set each element e of array to e ^ @a t.
362 valarray<_Tp>& operator^=(const _Tp&);
364 /// Set each element e of array to e & @a t.
365 valarray<_Tp>& operator&=(const _Tp&);
367 /// Set each element e of array to e | @a t.
368 valarray<_Tp>& operator|=(const _Tp&);
370 /// Left shift each element e of array by @a t bits.
371 valarray<_Tp>& operator<<=(const _Tp&);
373 /// Right shift each element e of array by @a t bits.
374 valarray<_Tp>& operator>>=(const _Tp&);
376 /// Multiply elements of array by corresponding elements of @a v.
377 valarray<_Tp>& operator*=(const valarray<_Tp>&);
379 /// Divide elements of array by corresponding elements of @a v.
380 valarray<_Tp>& operator/=(const valarray<_Tp>&);
382 /// Modulo elements of array by corresponding elements of @a v.
383 valarray<_Tp>& operator%=(const valarray<_Tp>&);
385 /// Add corresponding elements of @a v to elements of array.
386 valarray<_Tp>& operator+=(const valarray<_Tp>&);
388 /// Subtract corresponding elements of @a v from elements of array.
389 valarray<_Tp>& operator-=(const valarray<_Tp>&);
391 /// Logical xor corresponding elements of @a v with elements of array.
392 valarray<_Tp>& operator^=(const valarray<_Tp>&);
394 /// Logical or corresponding elements of @a v with elements of array.
395 valarray<_Tp>& operator|=(const valarray<_Tp>&);
397 /// Logical and corresponding elements of @a v with elements of array.
398 valarray<_Tp>& operator&=(const valarray<_Tp>&);
400 /// Left shift elements of array by corresponding elements of @a v.
401 valarray<_Tp>& operator<<=(const valarray<_Tp>&);
403 /// Right shift elements of array by corresponding elements of @a v.
404 valarray<_Tp>& operator>>=(const valarray<_Tp>&);
407 valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&);
409 valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&);
411 valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&);
413 valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&);
415 valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&);
417 valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&);
419 valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&);
421 valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&);
423 valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&);
425 valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
427 // _lib.valarray.members_ member functions:
428 /// Return the number of elements in array.
432 * @brief Return the sum of all elements in the array.
434 * Accumulates the sum of all elements into a Tp using +=. The order
435 * of adding the elements is unspecified.
439 /// Return the minimum element using operator<().
442 /// Return the maximum element using operator<().
446 * @brief Return a shifted array.
448 * A new valarray is constructed as a copy of this array with elements
449 * in shifted positions. For an element with index i, the new position
450 * is i - n. The new valarray has the same size as the current one.
451 * New elements without a value are set to 0. Elements whose new
452 * position is outside the bounds of the array are discarded.
454 * Positive arguments shift toward index 0, discarding elements [0, n).
455 * Negative arguments discard elements from the top of the array.
457 * @param n Number of element positions to shift.
458 * @return New valarray with elements in shifted positions.
460 valarray<_Tp> shift (int) const;
463 * @brief Return a rotated array.
465 * A new valarray is constructed as a copy of this array with elements
466 * in shifted positions. For an element with index i, the new position
467 * is (i - n) % size(). The new valarray has the same size as the
468 * current one. Elements that are shifted beyond the array bounds are
469 * shifted into the other end of the array. No elements are lost.
471 * Positive arguments shift toward index 0, wrapping around the top.
472 * Negative arguments shift towards the top, wrapping around to 0.
474 * @param n Number of element positions to rotate.
475 * @return New valarray with elements in shifted positions.
477 valarray<_Tp> cshift(int) const;
480 * @brief Apply a function to the array.
482 * Returns a new valarray with elements assigned to the result of
483 * applying func to the corresponding element of this array. The new
484 * array has the same size as this one.
486 * @param func Function of Tp returning Tp to apply.
487 * @return New valarray with transformed elements.
489 _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const;
492 * @brief Apply a function to the array.
494 * Returns a new valarray with elements assigned to the result of
495 * applying func to the corresponding element of this array. The new
496 * array has the same size as this one.
498 * @param func Function of const Tp& returning Tp to apply.
499 * @return New valarray with transformed elements.
501 _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const;
504 * @brief Resize array.
506 * Resize this array to @a size and set all elements to @a c. All
507 * references and iterators are invalidated.
509 * @param size New array size.
510 * @param c New value for all elements.
512 void resize(size_t __size, _Tp __c = _Tp());
516 _Tp* __restrict__ _M_data;
518 friend class _Array<_Tp>;
521 template<typename _Tp>
523 valarray<_Tp>::operator[](size_t __i) const
525 __glibcxx_requires_subscript(__i);
529 template<typename _Tp>
531 valarray<_Tp>::operator[](size_t __i)
533 __glibcxx_requires_subscript(__i);
537 _GLIBCXX_END_NAMESPACE
539 #include <bits/valarray_after.h>
540 #include <bits/slice_array.h>
541 #include <bits/gslice.h>
542 #include <bits/gslice_array.h>
543 #include <bits/mask_array.h>
544 #include <bits/indirect_array.h>
546 _GLIBCXX_BEGIN_NAMESPACE(std)
548 template<typename _Tp>
550 valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
552 template<typename _Tp>
554 valarray<_Tp>::valarray(size_t __n)
555 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
556 { std::__valarray_default_construct(_M_data, _M_data + __n); }
558 template<typename _Tp>
560 valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
561 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
562 { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
564 template<typename _Tp>
566 valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
567 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
569 _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
570 std::__valarray_copy_construct(__p, __p + __n, _M_data);
573 template<typename _Tp>
575 valarray<_Tp>::valarray(const valarray<_Tp>& __v)
576 : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
577 { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
580 template<typename _Tp>
582 valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
583 : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
585 std::__valarray_copy_construct
586 (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
589 template<typename _Tp>
591 valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
592 : _M_size(__ga._M_index.size()),
593 _M_data(__valarray_get_storage<_Tp>(_M_size))
595 std::__valarray_copy_construct
596 (__ga._M_array, _Array<size_t>(__ga._M_index),
597 _Array<_Tp>(_M_data), _M_size);
600 template<typename _Tp>
602 valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
603 : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
605 std::__valarray_copy_construct
606 (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
609 template<typename _Tp>
611 valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
612 : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
614 std::__valarray_copy_construct
615 (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
618 template<typename _Tp> template<class _Dom>
620 valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
621 : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
622 { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
624 template<typename _Tp>
626 valarray<_Tp>::~valarray()
628 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
629 std::__valarray_release_memory(_M_data);
632 template<typename _Tp>
633 inline valarray<_Tp>&
634 valarray<_Tp>::operator=(const valarray<_Tp>& __v)
636 _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);
637 std::__valarray_copy(__v._M_data, _M_size, _M_data);
641 template<typename _Tp>
642 inline valarray<_Tp>&
643 valarray<_Tp>::operator=(const _Tp& __t)
645 std::__valarray_fill(_M_data, _M_size, __t);
649 template<typename _Tp>
650 inline valarray<_Tp>&
651 valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
653 _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
654 std::__valarray_copy(__sa._M_array, __sa._M_sz,
655 __sa._M_stride, _Array<_Tp>(_M_data));
659 template<typename _Tp>
660 inline valarray<_Tp>&
661 valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
663 _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
664 std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
665 _Array<_Tp>(_M_data), _M_size);
669 template<typename _Tp>
670 inline valarray<_Tp>&
671 valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
673 _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
674 std::__valarray_copy(__ma._M_array, __ma._M_mask,
675 _Array<_Tp>(_M_data), _M_size);
679 template<typename _Tp>
680 inline valarray<_Tp>&
681 valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
683 _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
684 std::__valarray_copy(__ia._M_array, __ia._M_index,
685 _Array<_Tp>(_M_data), _M_size);
689 template<typename _Tp> template<class _Dom>
690 inline valarray<_Tp>&
691 valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
693 _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
694 std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
698 template<typename _Tp>
699 inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
700 valarray<_Tp>::operator[](slice __s) const
702 typedef _SClos<_ValArray,_Tp> _Closure;
703 return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
706 template<typename _Tp>
707 inline slice_array<_Tp>
708 valarray<_Tp>::operator[](slice __s)
709 { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
711 template<typename _Tp>
712 inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
713 valarray<_Tp>::operator[](const gslice& __gs) const
715 typedef _GClos<_ValArray,_Tp> _Closure;
716 return _Expr<_Closure, _Tp>
717 (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
720 template<typename _Tp>
721 inline gslice_array<_Tp>
722 valarray<_Tp>::operator[](const gslice& __gs)
724 return gslice_array<_Tp>
725 (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
728 template<typename _Tp>
730 valarray<_Tp>::operator[](const valarray<bool>& __m) const
733 size_t __e = __m.size();
734 for (size_t __i=0; __i<__e; ++__i)
736 return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
737 _Array<bool> (__m)));
740 template<typename _Tp>
741 inline mask_array<_Tp>
742 valarray<_Tp>::operator[](const valarray<bool>& __m)
745 size_t __e = __m.size();
746 for (size_t __i=0; __i<__e; ++__i)
748 return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
751 template<typename _Tp>
752 inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
753 valarray<_Tp>::operator[](const valarray<size_t>& __i) const
755 typedef _IClos<_ValArray,_Tp> _Closure;
756 return _Expr<_Closure, _Tp>(_Closure(*this, __i));
759 template<typename _Tp>
760 inline indirect_array<_Tp>
761 valarray<_Tp>::operator[](const valarray<size_t>& __i)
763 return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
764 _Array<size_t>(__i));
769 valarray<_Tp>::size() const
774 valarray<_Tp>::sum() const
776 _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
777 return std::__valarray_sum(_M_data, _M_data + _M_size);
782 valarray<_Tp>::shift(int __n) const
789 _Tp* __restrict__ __tmp_M_data =
790 std::__valarray_get_storage<_Tp>(_M_size);
793 std::__valarray_copy_construct(_M_data,
794 _M_data + _M_size, __tmp_M_data);
795 else if (__n > 0) // shift left
797 if (size_t(__n) > _M_size)
800 std::__valarray_copy_construct(_M_data + __n,
801 _M_data + _M_size, __tmp_M_data);
802 std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
803 __tmp_M_data + _M_size);
807 if (-size_t(__n) > _M_size)
810 std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
812 std::__valarray_default_construct(__tmp_M_data,
816 __ret._M_size = _M_size;
817 __ret._M_data = __tmp_M_data;
823 valarray<_Tp>::cshift(int __n) const
830 _Tp* __restrict__ __tmp_M_data =
831 std::__valarray_get_storage<_Tp>(_M_size);
834 std::__valarray_copy_construct(_M_data,
835 _M_data + _M_size, __tmp_M_data);
836 else if (__n > 0) // cshift left
838 if (size_t(__n) > _M_size)
839 __n = int(__n % _M_size);
841 std::__valarray_copy_construct(_M_data, _M_data + __n,
842 __tmp_M_data + _M_size - __n);
843 std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
848 if (-size_t(__n) > _M_size)
849 __n = -int(-size_t(__n) % _M_size);
851 std::__valarray_copy_construct(_M_data + _M_size + __n,
852 _M_data + _M_size, __tmp_M_data);
853 std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
857 __ret._M_size = _M_size;
858 __ret._M_data = __tmp_M_data;
864 valarray<_Tp>::resize(size_t __n, _Tp __c)
866 // This complication is so to make valarray<valarray<T> > work
867 // even though it is not required by the standard. Nobody should
868 // be saying valarray<valarray<T> > anyway. See the specs.
869 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
872 std::__valarray_release_memory(_M_data);
874 _M_data = __valarray_get_storage<_Tp>(__n);
876 std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
879 template<typename _Tp>
881 valarray<_Tp>::min() const
883 _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
884 return *std::min_element(_M_data, _M_data+_M_size);
887 template<typename _Tp>
889 valarray<_Tp>::max() const
891 _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
892 return *std::max_element(_M_data, _M_data+_M_size);
896 inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
897 valarray<_Tp>::apply(_Tp func(_Tp)) const
899 typedef _ValFunClos<_ValArray, _Tp> _Closure;
900 return _Expr<_Closure, _Tp>(_Closure(*this, func));
904 inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
905 valarray<_Tp>::apply(_Tp func(const _Tp &)) const
907 typedef _RefFunClos<_ValArray, _Tp> _Closure;
908 return _Expr<_Closure, _Tp>(_Closure(*this, func));
911 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
912 template<typename _Tp> \
913 inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \
914 valarray<_Tp>::operator _Op() const \
916 typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \
917 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
918 return _Expr<_Closure, _Rt>(_Closure(*this)); \
921 _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
922 _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
923 _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
924 _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
926 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
928 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \
929 template<class _Tp> \
930 inline valarray<_Tp>& \
931 valarray<_Tp>::operator _Op##=(const _Tp &__t) \
933 _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
937 template<class _Tp> \
938 inline valarray<_Tp>& \
939 valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \
941 _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \
942 _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \
943 _Array<_Tp>(__v._M_data)); \
947 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
948 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
949 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
950 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
951 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
952 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
953 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
954 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
955 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
956 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
958 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
960 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
961 template<class _Tp> template<class _Dom> \
962 inline valarray<_Tp>& \
963 valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \
965 _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
969 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
970 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
971 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
972 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
973 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
974 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
975 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
976 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
977 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
978 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
980 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
983 #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \
984 template<typename _Tp> \
985 inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \
986 typename __fun<_Name, _Tp>::result_type> \
987 operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
989 _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \
990 typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
991 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
992 return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \
995 template<typename _Tp> \
996 inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \
997 typename __fun<_Name, _Tp>::result_type> \
998 operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \
1000 typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
1001 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1002 return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \
1005 template<typename _Tp> \
1006 inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \
1007 typename __fun<_Name, _Tp>::result_type> \
1008 operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \
1010 typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
1011 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1012 return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \
1015 _DEFINE_BINARY_OPERATOR(+, __plus)
1016 _DEFINE_BINARY_OPERATOR(-, __minus)
1017 _DEFINE_BINARY_OPERATOR(*, __multiplies)
1018 _DEFINE_BINARY_OPERATOR(/, __divides)
1019 _DEFINE_BINARY_OPERATOR(%, __modulus)
1020 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
1021 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
1022 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
1023 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
1024 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
1025 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
1026 _DEFINE_BINARY_OPERATOR(||, __logical_or)
1027 _DEFINE_BINARY_OPERATOR(==, __equal_to)
1028 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
1029 _DEFINE_BINARY_OPERATOR(<, __less)
1030 _DEFINE_BINARY_OPERATOR(>, __greater)
1031 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
1032 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
1034 #undef _DEFINE_BINARY_OPERATOR
1036 _GLIBCXX_END_NAMESPACE
1038 #endif /* _GLIBCXX_VALARRAY */