Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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