1
/*
2
 * Copyright (c) 1999
3
 * Silicon Graphics Computer Systems, Inc.
4
 *
5
 * Copyright (c) 1999
6
 * Boris Fomitchev
7
 *
8
 * This material is provided "as is", with absolutely no warranty expressed
9
 * or implied. Any use is at your own risk.
10
 *
11
 * Permission to use or copy this software for any purpose is hereby granted
12
 * without fee, provided the above notices are retained on all copies.
13
 * Permission to modify the code and to distribute modified code is granted,
14
 * provided the above notices are retained, and a notice that the code was
15
 * modified is included with the above copyright notice.
16
 *
17
 */
18
19
#ifndef _STLP_VALARRAY
20
#  define _STLP_VALARRAY
21
22
#include <algorithm>
23
#include <limits>
24
25
#ifndef _STLP_OUTERMOST_HEADER_ID
26
#  define _STLP_OUTERMOST_HEADER_ID 0x76
27
#  include <stl/_prolog.h>
28
#endif
29
30
#ifndef _STLP_INTERNAL_CMATH
31
#  include <stl/_cmath.h>
32
#endif
33
34
#include <new>
35
36
#ifndef _STLP_INTERNAL_NUMERIC_H
37
#  include <stl/_numeric.h>
38
#endif
39
40
_STLP_BEGIN_NAMESPACE
41
42
class slice;
43
class gslice;
44
45
template <class _Tp> class valarray;
46
typedef valarray<bool>    _Valarray_bool;
47
typedef valarray<size_t>  _Valarray_size_t;
48
49
template <class _Tp> class slice_array;
50
template <class _Tp> class gslice_array;
51
template <class _Tp> class mask_array;
52
template <class _Tp> class indirect_array;
53
54
//----------------------------------------------------------------------
55
// class valarray
56
57
// Base class to handle memory allocation and deallocation.  We can't just
58
// use vector<>, because vector<bool> would be unsuitable as an internal
59
// representation for valarray<bool>.
60
61
template <class _Tp>
62
struct _Valarray_base {
63
  _Tp*   _M_first;
64
  size_t _M_size;
65
66
  _Valarray_base() : _M_first(0), _M_size(0) {}
67
  _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); }
68
  ~_Valarray_base() { _M_deallocate(); }
69
70
  void _M_allocate(size_t __n) {
71
    if (__n != 0) {
72
      _M_first = __STATIC_CAST(_Tp*, __stl_new(__n * sizeof(_Tp)));
73
      _M_size  = __n;
74
    }
75
    else {
76
      _M_first = 0;
77
      _M_size = 0;
78
    }
79
  }
80
81
  void _M_deallocate() {
82
    __stl_delete(_M_first);
83
    _M_first = 0;
84
    _M_size = 0;
85
  }
86
};
87
88
template <class _Tp>
89
class valarray : private _Valarray_base<_Tp>
90
{
91
  friend class gslice;
92
93
public:
94
  typedef _Tp value_type;
95
96
  // Basic constructors
97
  valarray() : _Valarray_base<_Tp>() {}
98
  explicit valarray(size_t __n) : _Valarray_base<_Tp>(__n)
99
    { uninitialized_fill_n(this->_M_first, this->_M_size, _STLP_DEFAULT_CONSTRUCTED(value_type)); }
100
  valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n)
101
    { uninitialized_fill_n(this->_M_first, this->_M_size, __x); }
102
  valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n)
103
    { uninitialized_copy(__p, __p + __n, this->_M_first); }
104
  valarray(const valarray<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_size) {
105
    uninitialized_copy(__x._M_first, __x._M_first + __x._M_size,
106
                       this->_M_first);
107
  }
108
109
  // Constructors from auxiliary array types
110
  valarray(const slice_array<_Tp>&);
111
  valarray(const gslice_array<_Tp>&);
112
  valarray(const mask_array<_Tp>&);
113
  valarray(const indirect_array<_Tp>&);
114
115
  // Destructor
116
    ~valarray() { _STLP_STD::detail::_Destroy_Range( this->_M_first, this->_M_first + this->_M_size ); }
117
118
    struct _NoInit {};
119
120
    valarray( size_t __n, _NoInit ) :
121
        _Valarray_base<_Tp>(__n)
122
      { uninitialized_fill_n(this->_M_first, this->_M_size, _Tp() ); }
123
124
public:                         // Assignment
125
  // Basic assignment.  Note that 'x = y' is undefined if x.size() != y.size()
126
  valarray<_Tp>& operator=(const valarray<_Tp>& __x) {
127
    _STLP_ASSERT(__x.size() == this->size())
128
    if (this != &__x)
129
      copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first);
130
    return *this;
131
  }
132
133
  // Scalar assignment
134
  valarray<_Tp>& operator=(const value_type& __x) {
135
    fill_n(this->_M_first, this->_M_size, __x);
136
    return *this;
137
  }
138
139
  // Assignment of auxiliary array types
140
  valarray<_Tp>& operator=(const slice_array<_Tp>&);
141
  valarray<_Tp>& operator=(const gslice_array<_Tp>&);
142
  valarray<_Tp>& operator=(const mask_array<_Tp>&);
143
  valarray<_Tp>& operator=(const indirect_array<_Tp>&);
144
145
public:                         // Element access
146
  value_type  operator[](size_t __n) const {
147
    _STLP_ASSERT(__n < this->size())
148
    return this->_M_first[__n];
149
  }
150
  value_type& operator[](size_t __n) {
151
    _STLP_ASSERT(__n < this->size())
152
    return this->_M_first[__n];
153
  }
154
  size_t size() const { return this->_M_size; }
155
156
public:                         // Subsetting operations with auxiliary type
157
  valarray<_Tp>       operator[](slice) const;
158
  slice_array<_Tp>    operator[](slice);
159
  valarray<_Tp>       operator[](const gslice&) const;
160
  gslice_array<_Tp>   operator[](const gslice&);
161
  valarray<_Tp>       operator[](const _Valarray_bool&) const;
162
  mask_array<_Tp>     operator[](const _Valarray_bool&);
163
  valarray<_Tp>       operator[](const _Valarray_size_t&) const;
164
  indirect_array<_Tp> operator[](const _Valarray_size_t&);
165
166
public:                         // Unary operators.
167
  valarray<_Tp> operator+() const { return *this; }
168
169
  valarray<_Tp> operator-() const {
170
    valarray<_Tp> __tmp(this->size(), _NoInit());
171
    for (size_t __i = 0; __i < this->size(); ++__i)
172
      __tmp[__i] = -(*this)[__i];
173
    return __tmp;
174
  }
175
176
  valarray<_Tp> operator~() const {
177
    valarray<_Tp> __tmp(this->size(), _NoInit());
178
    for (size_t __i = 0; __i < this->size(); ++__i)
179
      __tmp[__i] = ~(*this)[__i];
180
    return __tmp;
181
  }
182
183
  _Valarray_bool operator!() const;
184
185
public:                         // Scalar computed assignment.
186
  valarray<_Tp>& operator*= (const value_type& __x) {
187
    for (size_t __i = 0; __i < this->size(); ++__i)
188
      (*this)[__i] *= __x;
189
    return *this;
190
  }
191
192
  valarray<_Tp>& operator/= (const value_type& __x) {
193
    for (size_t __i = 0; __i < this->size(); ++__i)
194
      (*this)[__i] /= __x;
195
    return *this;
196
  }
197
198
  valarray<_Tp>& operator%= (const value_type& __x) {
199
    for (size_t __i = 0; __i < this->size(); ++__i)
200
      (*this)[__i] %= __x;
201
    return *this;
202
  }
203
204
  valarray<_Tp>& operator+= (const value_type& __x) {
205
    for (size_t __i = 0; __i < this->size(); ++__i)
206
      (*this)[__i] += __x;
207
    return *this;
208
  }
209
210
  valarray<_Tp>& operator-= (const value_type& __x) {
211
    for (size_t __i = 0; __i < this->size(); ++__i)
212
      (*this)[__i] -= __x;
213
    return *this;
214
  }
215
216
  valarray<_Tp>& operator^= (const value_type& __x) {
217
    for (size_t __i = 0; __i < this->size(); ++__i)
218
      (*this)[__i] ^= __x;
219
    return *this;
220
  }
221
222
  valarray<_Tp>& operator&= (const value_type& __x) {
223
    for (size_t __i = 0; __i < this->size(); ++__i)
224
      (*this)[__i] &= __x;
225
    return *this;
226
  }
227
228
  valarray<_Tp>& operator|= (const value_type& __x) {
229
    for (size_t __i = 0; __i < this->size(); ++__i)
230
      (*this)[__i] |= __x;
231
    return *this;
232
  }
233
234
  valarray<_Tp>& operator<<= (const value_type& __x) {
235
    for (size_t __i = 0; __i < this->size(); ++__i)
236
      (*this)[__i] <<= __x;
237
    return *this;
238
  }
239
240
  valarray<_Tp>& operator>>= (const value_type& __x) {
241
    for (size_t __i = 0; __i < this->size(); ++__i)
242
      (*this)[__i] >>= __x;
243
    return *this;
244
  }
245
246
public:                         // Array computed assignment.
247
  valarray<_Tp>& operator*= (const valarray<_Tp>& __x) {
248
    _STLP_ASSERT(__x.size() == this->size())
249
    for (size_t __i = 0; __i < this->size(); ++__i)
250
      (*this)[__i] *= __x[__i];
251
    return *this;
252
  }
253
254
  valarray<_Tp>& operator/= (const valarray<_Tp>& __x) {
255
    _STLP_ASSERT(__x.size() == this->size())
256
    for (size_t __i = 0; __i < this->size(); ++__i)
257
      (*this)[__i] /= __x[__i];
258
    return *this;
259
  }
260
261
  valarray<_Tp>& operator%= (const valarray<_Tp>& __x) {
262
    _STLP_ASSERT(__x.size() == this->size())
263
    for (size_t __i = 0; __i < this->size(); ++__i)
264
      (*this)[__i] %= __x[__i];
265
    return *this;
266
  }
267
268
  valarray<_Tp>& operator+= (const valarray<_Tp>& __x) {
269
    _STLP_ASSERT(__x.size() == this->size())
270
    for (size_t __i = 0; __i < this->size(); ++__i)
271
      (*this)[__i] += __x[__i];
272
    return *this;
273
  }
274
275
  valarray<_Tp>& operator-= (const valarray<_Tp>& __x) {
276
    _STLP_ASSERT(__x.size() == this->size())
277
    for (size_t __i = 0; __i < this->size(); ++__i)
278
      (*this)[__i] -= __x[__i];
279
    return *this;
280
  }
281
282
  valarray<_Tp>& operator^= (const valarray<_Tp>& __x) {
283
    _STLP_ASSERT(__x.size() == this->size())
284
    for (size_t __i = 0; __i < this->size(); ++__i)
285
      (*this)[__i] ^= __x[__i];
286
    return *this;
287
  }
288
289
  valarray<_Tp>& operator&= (const valarray<_Tp>& __x) {
290
    _STLP_ASSERT(__x.size() == this->size())
291
    for (size_t __i = 0; __i < this->size(); ++__i)
292
      (*this)[__i] &= __x[__i];
293
    return *this;
294
  }
295
296
  valarray<_Tp>& operator|= (const valarray<_Tp>& __x) {
297
    _STLP_ASSERT(__x.size() == this->size())
298
    for (size_t __i = 0; __i < this->size(); ++__i)
299
      (*this)[__i] |= __x[__i];
300
    return *this;
301
  }
302
303
  valarray<_Tp>& operator<<= (const valarray<_Tp>& __x) {
304
    _STLP_ASSERT(__x.size() == this->size())
305
    for (size_t __i = 0; __i < this->size(); ++__i)
306
      (*this)[__i] <<= __x[__i];
307
    return *this;
308
  }
309
310
  valarray<_Tp>& operator>>= (const valarray<_Tp>& __x) {
311
    _STLP_ASSERT(__x.size() == this->size())
312
    for (size_t __i = 0; __i < this->size(); ++__i)
313
      (*this)[__i] >>= __x[__i];
314
    return *this;
315
  }
316
317
public:                         // Other member functions.
318
319
  // The result is undefined for zero-length arrays
320
  value_type sum() const {
321
    _STLP_ASSERT(this->size() != 0)
322
    return accumulate(this->_M_first + 1, this->_M_first + this->_M_size,
323
                      (*this)[0]);
324
  }
325
326
  // The result is undefined for zero-length arrays
327
  value_type (min) () const {
328
    _STLP_ASSERT(this->size() != 0)
329
    return *min_element(this->_M_first + 0, this->_M_first + this->_M_size);
330
  }
331
332
  value_type (max) () const {
333
    _STLP_ASSERT(this->size() != 0)
334
    return *max_element(this->_M_first + 0, this->_M_first + this->_M_size);
335
  }
336
337
  valarray<_Tp> shift(int __n) const;
338
  valarray<_Tp> cshift(int __n) const;
339
340
  valarray<_Tp> apply(value_type __f(value_type)) const {
341
    valarray<_Tp> __tmp(this->size());
342
    transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
343
              __f);
344
    return __tmp;
345
  }
346
  valarray<_Tp> apply(value_type __f(const value_type&)) const {
347
    valarray<_Tp> __tmp(this->size());
348
    transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
349
              __f);
350
    return __tmp;
351
  }
352
353
  void resize(size_t __n, value_type __x = value_type()) {
354
    _STLP_STD::detail::_Destroy_Range( this->_M_first, this->_M_first + this->_M_size );
355
    _Valarray_base<_Tp>::_M_deallocate();
356
    _Valarray_base<_Tp>::_M_allocate(__n);
357
    uninitialized_fill_n(this->_M_first, this->_M_size, __x);
358
  }
359
};
360
361
//----------------------------------------------------------------------
362
// valarray non-member functions.
363
364
// Binary arithmetic operations between two arrays.  Behavior is
365
// undefined if the two arrays do not have the same length.
366
367
template <class _Tp>
368
inline valarray<_Tp>  _STLP_CALL operator*(const valarray<_Tp>& __x,
369
                                           const valarray<_Tp>& __y) {
370
  _STLP_ASSERT(__x.size() == __y.size())
371
  typedef typename valarray<_Tp>::_NoInit _NoInit;
372
  valarray<_Tp> __tmp(__x.size(), _NoInit());
373
  for (size_t __i = 0; __i < __x.size(); ++__i)
374
    __tmp[__i] = __x[__i] * __y[__i];
375
  return __tmp;
376
}
377
378
template <class _Tp>
379
inline valarray<_Tp>  _STLP_CALL operator/(const valarray<_Tp>& __x,
380
                                           const valarray<_Tp>& __y) {
381
  _STLP_ASSERT(__x.size() == __y.size())
382
  typedef typename valarray<_Tp>::_NoInit _NoInit;
383
  valarray<_Tp> __tmp(__x.size(), _NoInit());
384
  for (size_t __i = 0; __i < __x.size(); ++__i)
385
    __tmp[__i] = __x[__i] / __y[__i];
386
  return __tmp;
387
}
388
389
template <class _Tp>
390
inline valarray<_Tp>  _STLP_CALL operator%(const valarray<_Tp>& __x,
391
                                           const valarray<_Tp>& __y) {
392
  _STLP_ASSERT(__x.size() == __y.size())
393
  typedef typename valarray<_Tp>::_NoInit _NoInit;
394
  valarray<_Tp> __tmp(__x.size(), _NoInit());
395
  for (size_t __i = 0; __i < __x.size(); ++__i)
396
    __tmp[__i] = __x[__i] % __y[__i];
397
  return __tmp;
398
}
399
400
template <class _Tp>
401
inline valarray<_Tp>  _STLP_CALL operator+(const valarray<_Tp>& __x,
402
                                           const valarray<_Tp>& __y) {
403
  _STLP_ASSERT(__x.size() == __y.size())
404
  typedef typename valarray<_Tp>::_NoInit _NoInit;
405
  valarray<_Tp> __tmp(__x.size(), _NoInit());
406
  for (size_t __i = 0; __i < __x.size(); ++__i)
407
    __tmp[__i] = __x[__i] + __y[__i];
408
  return __tmp;
409
}
410
411
template <class _Tp>
412
inline valarray<_Tp>  _STLP_CALL operator-(const valarray<_Tp>& __x,
413
                                           const valarray<_Tp>& __y) {
414
  _STLP_ASSERT(__x.size() == __y.size())
415
  typedef typename valarray<_Tp>::_NoInit _NoInit;
416
  valarray<_Tp> __tmp(__x.size(), _NoInit());
417
  for (size_t __i = 0; __i < __x.size(); ++__i)
418
    __tmp[__i] = __x[__i] - __y[__i];
419
  return __tmp;
420
}
421
422
template <class _Tp>
423
inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x,
424
                                          const valarray<_Tp>& __y) {
425
  _STLP_ASSERT(__x.size() == __y.size())
426
  typedef typename valarray<_Tp>::_NoInit _NoInit;
427
  valarray<_Tp> __tmp(__x.size(), _NoInit());
428
  for (size_t __i = 0; __i < __x.size(); ++__i)
429
    __tmp[__i] = __x[__i] ^ __y[__i];
430
  return __tmp;
431
}
432
433
template <class _Tp>
434
inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x,
435
                                          const valarray<_Tp>& __y) {
436
  _STLP_ASSERT(__x.size() == __y.size())
437
  typedef typename valarray<_Tp>::_NoInit _NoInit;
438
  valarray<_Tp> __tmp(__x.size(), _NoInit());
439
  for (size_t __i = 0; __i < __x.size(); ++__i)
440
    __tmp[__i] = __x[__i] & __y[__i];
441
  return __tmp;
442
}
443
444
template <class _Tp>
445
inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x,
446
                                          const valarray<_Tp>& __y) {
447
  _STLP_ASSERT(__x.size() == __y.size())
448
  typedef typename valarray<_Tp>::_NoInit _NoInit;
449
  valarray<_Tp> __tmp(__x.size(), _NoInit());
450
  for (size_t __i = 0; __i < __x.size(); ++__i)
451
    __tmp[__i] = __x[__i] | __y[__i];
452
  return __tmp;
453
}
454
455
template <class _Tp>
456
inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x,
457
                                           const valarray<_Tp>& __y) {
458
  _STLP_ASSERT(__x.size() == __y.size())
459
  typedef typename valarray<_Tp>::_NoInit _NoInit;
460
  valarray<_Tp> __tmp(__x.size(), _NoInit());
461
  for (size_t __i = 0; __i < __x.size(); ++__i)
462
    __tmp[__i] = __x[__i] << __y[__i];
463
  return __tmp;
464
}
465
466
template <class _Tp>
467
inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x,
468
                                           const valarray<_Tp>& __y) {
469
  _STLP_ASSERT(__x.size() == __y.size())
470
  typedef typename valarray<_Tp>::_NoInit _NoInit;
471
  valarray<_Tp> __tmp(__x.size(), _NoInit());
472
  for (size_t __i = 0; __i < __x.size(); ++__i)
473
    __tmp[__i] = __x[__i] >> __y[__i];
474
  return __tmp;
475
}
476
477
// Binary arithmetic operations between an array and a scalar.
478
479
template <class _Tp>
480
inline valarray<_Tp> _STLP_CALL operator*(const valarray<_Tp>& __x, const _Tp& __c) {
481
  typedef typename valarray<_Tp>::_NoInit _NoInit;
482
  valarray<_Tp> __tmp(__x.size(), _NoInit());
483
  for (size_t __i = 0; __i < __x.size(); ++__i)
484
    __tmp[__i] = __x[__i]  * __c;
485
  return __tmp;
486
}
487
488
template <class _Tp>
489
inline valarray<_Tp> _STLP_CALL operator*(const _Tp& __c, const valarray<_Tp>& __x) {
490
  typedef typename valarray<_Tp>::_NoInit _NoInit;
491
  valarray<_Tp> __tmp(__x.size(), _NoInit());
492
  for (size_t __i = 0; __i < __x.size(); ++__i)
493
    __tmp[__i] = __c * __x[__i];
494
  return __tmp;
495
}
496
497
template <class _Tp>
498
inline valarray<_Tp> _STLP_CALL operator/(const valarray<_Tp>& __x, const _Tp& __c) {
499
  typedef typename valarray<_Tp>::_NoInit _NoInit;
500
  valarray<_Tp> __tmp(__x.size(), _NoInit());
501
  for (size_t __i = 0; __i < __x.size(); ++__i)
502
    __tmp[__i] = __x[__i]  / __c;
503
  return __tmp;
504
}
505
506
template <class _Tp>
507
inline valarray<_Tp> _STLP_CALL operator/(const _Tp& __c, const valarray<_Tp>& __x) {
508
  typedef typename valarray<_Tp>::_NoInit _NoInit;
509
  valarray<_Tp> __tmp(__x.size(), _NoInit());
510
  for (size_t __i = 0; __i < __x.size(); ++__i)
511
    __tmp[__i] = __c / __x[__i];
512
  return __tmp;
513
}
514
515
template <class _Tp>
516
inline valarray<_Tp> _STLP_CALL operator%(const valarray<_Tp>& __x, const _Tp& __c) {
517
  typedef typename valarray<_Tp>::_NoInit _NoInit;
518
  valarray<_Tp> __tmp(__x.size(), _NoInit());
519
  for (size_t __i = 0; __i < __x.size(); ++__i)
520
    __tmp[__i] = __x[__i]  % __c;
521
  return __tmp;
522
}
523
524
template <class _Tp>
525
inline valarray<_Tp> _STLP_CALL operator%(const _Tp& __c, const valarray<_Tp>& __x) {
526
  typedef typename valarray<_Tp>::_NoInit _NoInit;
527
  valarray<_Tp> __tmp(__x.size(), _NoInit());
528
  for (size_t __i = 0; __i < __x.size(); ++__i)
529
    __tmp[__i] = __c % __x[__i];
530
  return __tmp;
531
}
532
533
template <class _Tp>
534
inline valarray<_Tp> _STLP_CALL operator+(const valarray<_Tp>& __x, const _Tp& __c) {
535
  typedef typename valarray<_Tp>::_NoInit _NoInit;
536
  valarray<_Tp> __tmp(__x.size(), _NoInit());
537
  for (size_t __i = 0; __i < __x.size(); ++__i)
538
    __tmp[__i] = __x[__i]  + __c;
539
  return __tmp;
540
}
541
542
template <class _Tp>
543
inline valarray<_Tp> _STLP_CALL operator+(const _Tp& __c, const valarray<_Tp>& __x) {
544
  typedef typename valarray<_Tp>::_NoInit _NoInit;
545
  valarray<_Tp> __tmp(__x.size(), _NoInit());
546
  for (size_t __i = 0; __i < __x.size(); ++__i)
547
    __tmp[__i] = __c + __x[__i];
548
  return __tmp;
549
}
550
551
template <class _Tp>
552
inline valarray<_Tp> _STLP_CALL operator-(const valarray<_Tp>& __x, const _Tp& __c) {
553
  typedef typename valarray<_Tp>::_NoInit _NoInit;
554
  valarray<_Tp> __tmp(__x.size(), _NoInit());
555
  for (size_t __i = 0; __i < __x.size(); ++__i)
556
    __tmp[__i] = __x[__i]  - __c;
557
  return __tmp;
558
}
559
560
template <class _Tp>
561
inline valarray<_Tp> _STLP_CALL operator-(const _Tp& __c, const valarray<_Tp>& __x) {
562
  typedef typename valarray<_Tp>::_NoInit _NoInit;
563
  valarray<_Tp> __tmp(__x.size(), _NoInit());
564
  for (size_t __i = 0; __i < __x.size(); ++__i)
565
    __tmp[__i] = __c - __x[__i];
566
  return __tmp;
567
}
568
569
template <class _Tp>
570
inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x, const _Tp& __c) {
571
  typedef typename valarray<_Tp>::_NoInit _NoInit;
572
  valarray<_Tp> __tmp(__x.size(), _NoInit());
573
  for (size_t __i = 0; __i < __x.size(); ++__i)
574
    __tmp[__i] = __x[__i]  ^ __c;
575
  return __tmp;
576
}
577
578
template <class _Tp>
579
inline valarray<_Tp> _STLP_CALL operator^(const _Tp& __c, const valarray<_Tp>& __x) {
580
  typedef typename valarray<_Tp>::_NoInit _NoInit;
581
  valarray<_Tp> __tmp(__x.size(), _NoInit());
582
  for (size_t __i = 0; __i < __x.size(); ++__i)
583
    __tmp[__i] = __c ^ __x[__i];
584
  return __tmp;
585
}
586
587
template <class _Tp>
588
inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x, const _Tp& __c) {
589
  typedef typename valarray<_Tp>::_NoInit _NoInit;
590
  valarray<_Tp> __tmp(__x.size(), _NoInit());
591
  for (size_t __i = 0; __i < __x.size(); ++__i)
592
    __tmp[__i] = __x[__i]  & __c;
593
  return __tmp;
594
}
595
596
template <class _Tp>
597
inline valarray<_Tp> _STLP_CALL operator&(const _Tp& __c, const valarray<_Tp>& __x) {
598
  typedef typename valarray<_Tp>::_NoInit _NoInit;
599
  valarray<_Tp> __tmp(__x.size(), _NoInit());
600
  for (size_t __i = 0; __i < __x.size(); ++__i)
601
    __tmp[__i] = __c & __x[__i];
602
  return __tmp;
603
}
604
605
template <class _Tp>
606
inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x, const _Tp& __c) {
607
  typedef typename valarray<_Tp>::_NoInit _NoInit;
608
  valarray<_Tp> __tmp(__x.size(), _NoInit());
609
  for (size_t __i = 0; __i < __x.size(); ++__i)
610
    __tmp[__i] = __x[__i]  | __c;
611
  return __tmp;
612
}
613
614
template <class _Tp>
615
inline valarray<_Tp> _STLP_CALL operator|(const _Tp& __c, const valarray<_Tp>& __x) {
616
  typedef typename valarray<_Tp>::_NoInit _NoInit;
617
  valarray<_Tp> __tmp(__x.size(), _NoInit());
618
  for (size_t __i = 0; __i < __x.size(); ++__i)
619
    __tmp[__i] = __c | __x[__i];
620
  return __tmp;
621
}
622
623
template <class _Tp>
624
inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x, const _Tp& __c) {
625
  typedef typename valarray<_Tp>::_NoInit _NoInit;
626
  valarray<_Tp> __tmp(__x.size(), _NoInit());
627
  for (size_t __i = 0; __i < __x.size(); ++__i)
628
    __tmp[__i] = __x[__i]  << __c;
629
  return __tmp;
630
}
631
632
template <class _Tp>
633
inline valarray<_Tp> _STLP_CALL operator<<(const _Tp& __c, const valarray<_Tp>& __x) {
634
  typedef typename valarray<_Tp>::_NoInit _NoInit;
635
  valarray<_Tp> __tmp(__x.size(), _NoInit());
636
  for (size_t __i = 0; __i < __x.size(); ++__i)
637
    __tmp[__i] = __c << __x[__i];
638
  return __tmp;
639
}
640
641
template <class _Tp>
642
inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x, const _Tp& __c) {
643
  typedef typename valarray<_Tp>::_NoInit _NoInit;
644
  valarray<_Tp> __tmp(__x.size(), _NoInit());
645
  for (size_t __i = 0; __i < __x.size(); ++__i)
646
    __tmp[__i] = __x[__i]  >> __c;
647
  return __tmp;
648
}
649
650
template <class _Tp>
651
inline valarray<_Tp> _STLP_CALL operator>>(const _Tp& __c, const valarray<_Tp>& __x) {
652
  typedef typename valarray<_Tp>::_NoInit _NoInit;
653
  valarray<_Tp> __tmp(__x.size(), _NoInit());
654
  for (size_t __i = 0; __i < __x.size(); ++__i)
655
    __tmp[__i] = __c >> __x[__i];
656
  return __tmp;
657
}
658
659
// Binary logical operations between two arrays.  Behavior is undefined
660
// if the two arrays have different lengths.  Note that operator== does
661
// not do what you might at first expect.
662
663
template <class _Tp>
664
inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x,
665
                                            const valarray<_Tp>& __y) {
666
  _STLP_ASSERT(__x.size() == __y.size())
667
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
668
  for (size_t __i = 0; __i < __x.size(); ++__i)
669
    __tmp[__i] = __x[__i] == __y[__i];
670
  return __tmp;
671
}
672
673
template <class _Tp>
674
inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x,
675
                                           const valarray<_Tp>& __y) {
676
  _STLP_ASSERT(__x.size() == __y.size())
677
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
678
  for (size_t __i = 0; __i < __x.size(); ++__i)
679
    __tmp[__i] = __x[__i] < __y[__i];
680
  return __tmp;
681
}
682
683
#ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
684
685
template <class _Tp>
686
inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x,
687
                                            const valarray<_Tp>& __y) {
688
  _STLP_ASSERT(__x.size() == __y.size())
689
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
690
  for (size_t __i = 0; __i < __x.size(); ++__i)
691
    __tmp[__i] = __x[__i] != __y[__i];
692
  return __tmp;
693
}
694
695
template <class _Tp>
696
inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x,
697
                                           const valarray<_Tp>& __y) {
698
  _STLP_ASSERT(__x.size() == __y.size())
699
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
700
  for (size_t __i = 0; __i < __x.size(); ++__i)
701
    __tmp[__i] = __x[__i] > __y[__i];
702
  return __tmp;
703
}
704
705
template <class _Tp>
706
inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x,
707
                                            const valarray<_Tp>& __y) {
708
  _STLP_ASSERT(__x.size() == __y.size())
709
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
710
  for (size_t __i = 0; __i < __x.size(); ++__i)
711
    __tmp[__i] = __x[__i] <= __y[__i];
712
  return __tmp;
713
}
714
715
template <class _Tp>
716
inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x,
717
                                            const valarray<_Tp>& __y) {
718
  _STLP_ASSERT(__x.size() == __y.size())
719
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
720
  for (size_t __i = 0; __i < __x.size(); ++__i)
721
    __tmp[__i] = __x[__i] >= __y[__i];
722
  return __tmp;
723
}
724
725
#endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
726
// fbp : swap ?
727
728
template <class _Tp>
729
inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x,
730
                                            const valarray<_Tp>& __y) {
731
  _STLP_ASSERT(__x.size() == __y.size())
732
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
733
  for (size_t __i = 0; __i < __x.size(); ++__i)
734
    __tmp[__i] = __x[__i] && __y[__i];
735
  return __tmp;
736
}
737
738
template <class _Tp>
739
inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x,
740
                                            const valarray<_Tp>& __y) {
741
  _STLP_ASSERT(__x.size() == __y.size())
742
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
743
  for (size_t __i = 0; __i < __x.size(); ++__i)
744
    __tmp[__i] = __x[__i] || __y[__i];
745
  return __tmp;
746
}
747
748
// Logical operations between an array and a scalar.
749
750
template <class _Tp>
751
inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x, const _Tp& __c) {
752
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
753
  for (size_t __i = 0; __i < __x.size(); ++__i)
754
    __tmp[__i] = __x[__i] == __c;
755
  return __tmp;
756
}
757
758
template <class _Tp>
759
inline _Valarray_bool _STLP_CALL operator==(const _Tp& __c, const valarray<_Tp>& __x) {
760
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
761
  for (size_t __i = 0; __i < __x.size(); ++__i)
762
    __tmp[__i] = __c == __x[__i];
763
  return __tmp;
764
}
765
766
template <class _Tp>
767
inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x, const _Tp& __c) {
768
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
769
  for (size_t __i = 0; __i < __x.size(); ++__i)
770
    __tmp[__i] = __x[__i] != __c;
771
  return __tmp;
772
}
773
774
template <class _Tp>
775
inline _Valarray_bool _STLP_CALL operator!=(const _Tp& __c, const valarray<_Tp>& __x) {
776
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
777
  for (size_t __i = 0; __i < __x.size(); ++__i)
778
    __tmp[__i] = __c != __x[__i];
779
  return __tmp;
780
}
781
782
template <class _Tp>
783
inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x, const _Tp& __c) {
784
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
785
  for (size_t __i = 0; __i < __x.size(); ++__i)
786
    __tmp[__i] = __x[__i] < __c;
787
  return __tmp;
788
}
789
790
template <class _Tp>
791
inline _Valarray_bool _STLP_CALL operator<(const _Tp& __c, const valarray<_Tp>& __x) {
792
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
793
  for (size_t __i = 0; __i < __x.size(); ++__i)
794
    __tmp[__i] = __c < __x[__i];
795
  return __tmp;
796
}
797
798
template <class _Tp>
799
inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x, const _Tp& __c) {
800
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
801
  for (size_t __i = 0; __i < __x.size(); ++__i)
802
    __tmp[__i] = __x[__i] > __c;
803
  return __tmp;
804
}
805
806
template <class _Tp>
807
inline _Valarray_bool _STLP_CALL operator>(const _Tp& __c, const valarray<_Tp>& __x) {
808
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
809
  for (size_t __i = 0; __i < __x.size(); ++__i)
810
    __tmp[__i] = __c > __x[__i];
811
  return __tmp;
812
}
813
814
template <class _Tp>
815
inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x, const _Tp& __c) {
816
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
817
  for (size_t __i = 0; __i < __x.size(); ++__i)
818
    __tmp[__i] = __x[__i]  <= __c;
819
  return __tmp;
820
}
821
822
template <class _Tp>
823
inline _Valarray_bool _STLP_CALL operator<=(const _Tp& __c, const valarray<_Tp>& __x) {
824
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
825
  for (size_t __i = 0; __i < __x.size(); ++__i)
826
    __tmp[__i] = __c <= __x[__i];
827
  return __tmp;
828
}
829
830
template <class _Tp>
831
inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x, const _Tp& __c) {
832
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
833
  for (size_t __i = 0; __i < __x.size(); ++__i)
834
    __tmp[__i] = __x[__i] >= __c;
835
  return __tmp;
836
}
837
838
template <class _Tp>
839
inline _Valarray_bool _STLP_CALL operator>=(const _Tp& __c, const valarray<_Tp>& __x) {
840
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
841
  for (size_t __i = 0; __i < __x.size(); ++__i)
842
    __tmp[__i] = __c >= __x[__i];
843
  return __tmp;
844
}
845
846
template <class _Tp>
847
inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x, const _Tp& __c) {
848
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
849
  for (size_t __i = 0; __i < __x.size(); ++__i)
850
    __tmp[__i] = __x[__i] && __c;
851
  return __tmp;
852
}
853
854
template <class _Tp>
855
inline _Valarray_bool _STLP_CALL operator&&(const _Tp& __c, const valarray<_Tp>& __x) {
856
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
857
  for (size_t __i = 0; __i < __x.size(); ++__i)
858
    __tmp[__i] = __c && __x[__i];
859
  return __tmp;
860
}
861
862
template <class _Tp>
863
inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x, const _Tp& __c) {
864
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
865
  for (size_t __i = 0; __i < __x.size(); ++__i)
866
    __tmp[__i] = __x[__i] || __c;
867
  return __tmp;
868
}
869
870
template <class _Tp>
871
inline _Valarray_bool _STLP_CALL operator||(const _Tp& __c, const valarray<_Tp>& __x) {
872
  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
873
  for (size_t __i = 0; __i < __x.size(); ++__i)
874
    __tmp[__i] = __c || __x[__i];
875
  return __tmp;
876
}
877
878
// valarray "transcendentals" (the list includes abs and sqrt, which,
879
// of course, are not transcendental).
880
881
template <class _Tp>
882
inline valarray<_Tp> abs(const valarray<_Tp>& __x) {
883
  typedef typename valarray<_Tp>::_NoInit _NoInit;
884
  valarray<_Tp> __tmp(__x.size(), _NoInit());
885
  for (size_t __i = 0; __i < __x.size(); ++__i)
886
    __tmp[__i] = ::abs(__x[__i]);
887
  return __tmp;
888
}
889
890
template <class _Tp>
891
inline valarray<_Tp> acos(const valarray<_Tp>& __x) {
892
  typedef typename valarray<_Tp>::_NoInit _NoInit;
893
  valarray<_Tp> __tmp(__x.size(), _NoInit());
894
  for (size_t __i = 0; __i < __x.size(); ++__i)
895
    __tmp[__i] = ::acos(__x[__i]);
896
  return __tmp;
897
}
898
899
template <class _Tp>
900
inline valarray<_Tp> asin(const valarray<_Tp>& __x) {
901
  typedef typename valarray<_Tp>::_NoInit _NoInit;
902
  valarray<_Tp> __tmp(__x.size(), _NoInit());
903
  for (size_t __i = 0; __i < __x.size(); ++__i)
904
    __tmp[__i] = ::asin(__x[__i]);
905
  return __tmp;
906
}
907
908
template <class _Tp>
909
inline valarray<_Tp> atan(const valarray<_Tp>& __x) {
910
  typedef typename valarray<_Tp>::_NoInit _NoInit;
911
  valarray<_Tp> __tmp(__x.size(), _NoInit());
912
  for (size_t __i = 0; __i < __x.size(); ++__i)
913
    __tmp[__i] = ::atan(__x[__i]);
914
  return __tmp;
915
}
916
917
template <class _Tp>
918
inline valarray<_Tp> atan2(const valarray<_Tp>& __x,
919
                           const valarray<_Tp>& __y) {
920
  typedef typename valarray<_Tp>::_NoInit _NoInit;
921
  valarray<_Tp> __tmp(__x.size(), _NoInit());
922
  for (size_t __i = 0; __i < __x.size(); ++__i)
923
    __tmp[__i] = ::atan2(__x[__i], __y[__i]);
924
  return __tmp;
925
}
926
927
template <class _Tp>
928
inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) {
929
  typedef typename valarray<_Tp>::_NoInit _NoInit;
930
  valarray<_Tp> __tmp(__x.size(), _NoInit());
931
  for (size_t __i = 0; __i < __x.size(); ++__i)
932
    __tmp[__i] = ::atan2(__x[__i], __c);
933
  return __tmp;
934
}
935
936
template <class _Tp>
937
inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) {
938
  typedef typename valarray<_Tp>::_NoInit _NoInit;
939
  valarray<_Tp> __tmp(__x.size(), _NoInit());
940
  for (size_t __i = 0; __i < __x.size(); ++__i)
941
    __tmp[__i] = ::atan2(__c, __x[__i]);
942
  return __tmp;
943
}
944
945
template <class _Tp>
946
inline valarray<_Tp> cos(const valarray<_Tp>& __x) {
947
  typedef typename valarray<_Tp>::_NoInit _NoInit;
948
  valarray<_Tp> __tmp(__x.size(), _NoInit());
949
  for (size_t __i = 0; __i < __x.size(); ++__i)
950
    __tmp[__i] = ::cos(__x[__i]);
951
  return __tmp;
952
}
953
954
template <class _Tp>
955
inline valarray<_Tp> cosh(const valarray<_Tp>& __x) {
956
  typedef typename valarray<_Tp>::_NoInit _NoInit;
957
  valarray<_Tp> __tmp(__x.size(), _NoInit());
958
  for (size_t __i = 0; __i < __x.size(); ++__i)
959
    __tmp[__i] = ::cosh(__x[__i]);
960
  return __tmp;
961
}
962
963
template <class _Tp>
964
inline valarray<_Tp> exp(const valarray<_Tp>& __x) {
965
  typedef typename valarray<_Tp>::_NoInit _NoInit;
966
  valarray<_Tp> __tmp(__x.size(), _NoInit());
967
  for (size_t __i = 0; __i < __x.size(); ++__i)
968
    __tmp[__i] = ::exp(__x[__i]);
969
  return __tmp;
970
}
971
972
template <class _Tp>
973
inline valarray<_Tp> log(const valarray<_Tp>& __x) {
974
  typedef typename valarray<_Tp>::_NoInit _NoInit;
975
  valarray<_Tp> __tmp(__x.size(), _NoInit());
976
  for (size_t __i = 0; __i < __x.size(); ++__i)
977
    __tmp[__i] = ::log(__x[__i]);
978
  return __tmp;
979
}
980
981
template <class _Tp>
982
inline valarray<_Tp> log10(const valarray<_Tp>& __x) {
983
  typedef typename valarray<_Tp>::_NoInit _NoInit;
984
  valarray<_Tp> __tmp(__x.size(), _NoInit());
985
  for (size_t __i = 0; __i < __x.size(); ++__i)
986
    __tmp[__i] = ::log10(__x[__i]);
987
  return __tmp;
988
}
989
990
template <class _Tp>
991
inline valarray<_Tp> pow(const valarray<_Tp>& __x,
992
                         const valarray<_Tp>& __y) {
993
  typedef typename valarray<_Tp>::_NoInit _NoInit;
994
  valarray<_Tp> __tmp(__x.size(), _NoInit());
995
  for (size_t __i = 0; __i < __x.size(); ++__i)
996
    __tmp[__i] = ::pow(__x[__i], __y[__i]);
997
  return __tmp;
998
}
999
1000
template <class _Tp>
1001
inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) {
1002
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1003
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1004
  for (size_t __i = 0; __i < __x.size(); ++__i)
1005
    __tmp[__i] = ::pow(__x[__i], __c);
1006
  return __tmp;
1007
}
1008
1009
template <class _Tp>
1010
inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) {
1011
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1012
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1013
  for (size_t __i = 0; __i < __x.size(); ++__i)
1014
    __tmp[__i] = ::pow(__c, __x[__i]);
1015
  return __tmp;
1016
}
1017
1018
template <class _Tp>
1019
inline valarray<_Tp> sin(const valarray<_Tp>& __x) {
1020
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1021
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1022
  for (size_t __i = 0; __i < __x.size(); ++__i)
1023
    __tmp[__i] = ::sin(__x[__i]);
1024
  return __tmp;
1025
}
1026
1027
template <class _Tp>
1028
inline valarray<_Tp> sinh(const valarray<_Tp>& __x) {
1029
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1030
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1031
  for (size_t __i = 0; __i < __x.size(); ++__i)
1032
    __tmp[__i] = ::sinh(__x[__i]);
1033
  return __tmp;
1034
}
1035
1036
template <class _Tp>
1037
inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) {
1038
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1039
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1040
  for (size_t __i = 0; __i < __x.size(); ++__i)
1041
    __tmp[__i] = ::sqrt(__x[__i]);
1042
  return __tmp;
1043
}
1044
1045
template <class _Tp>
1046
inline valarray<_Tp> tan(const valarray<_Tp>& __x) {
1047
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1048
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1049
  for (size_t __i = 0; __i < __x.size(); ++__i)
1050
    __tmp[__i] = ::tan(__x[__i]);
1051
  return __tmp;
1052
}
1053
1054
template <class _Tp>
1055
inline valarray<_Tp> tanh(const valarray<_Tp>& __x) {
1056
  typedef typename valarray<_Tp>::_NoInit _NoInit;
1057
  valarray<_Tp> __tmp(__x.size(), _NoInit());
1058
  for (size_t __i = 0; __i < __x.size(); ++__i)
1059
    __tmp[__i] = ::tanh(__x[__i]);
1060
  return __tmp;
1061
}
1062
1063
//----------------------------------------------------------------------
1064
// slice and slice_array
1065
1066
class slice {
1067
public:
1068
  slice() : _M_start(0), _M_length(0), _M_stride(0) {}
1069
  slice(size_t __start, size_t __length, size_t __stride)
1070
    : _M_start(__start), _M_length(__length), _M_stride(__stride)
1071
    {}
1072
  __TRIVIAL_DESTRUCTOR(slice)
1073
1074
  size_t start()  const { return _M_start; }
1075
  size_t size()   const { return _M_length; }
1076
  size_t stride() const { return _M_stride; }
1077
1078
private:
1079
  size_t _M_start;
1080
  size_t _M_length;
1081
  size_t _M_stride;
1082
};
1083
1084
template <class _Tp>
1085
class slice_array {
1086
  friend class valarray<_Tp>;
1087
public:
1088
  typedef _Tp value_type;
1089
1090
  void operator=(const valarray<value_type>& __x) const {
1091
    size_t __index = _M_slice.start();
1092
    for (size_t __i = 0;
1093
         __i < _M_slice.size();
1094
         ++__i, __index += _M_slice.stride())
1095
      _M_array[__index] = __x[__i];
1096
  }
1097
1098
  void operator*=(const valarray<value_type>& __x) const {
1099
    size_t __index = _M_slice.start();
1100
    for (size_t __i = 0;
1101
         __i < _M_slice.size();
1102
         ++__i, __index += _M_slice.stride())
1103
      _M_array[__index] *= __x[__i];
1104
  }
1105
1106
  void operator/=(const valarray<value_type>& __x) const {
1107
    size_t __index = _M_slice.start();
1108
    for (size_t __i = 0;
1109
         __i < _M_slice.size();
1110
         ++__i, __index += _M_slice.stride())
1111
      _M_array[__index] /= __x[__i];
1112
  }
1113
1114
  void operator%=(const valarray<value_type>& __x) const {
1115
    size_t __index = _M_slice.start();
1116
    for (size_t __i = 0;
1117
         __i < _M_slice.size();
1118
         ++__i, __index += _M_slice.stride())
1119
      _M_array[__index] %= __x[__i];
1120
  }
1121
1122
  void operator+=(const valarray<value_type>& __x) const {
1123
    size_t __index = _M_slice.start();
1124
    for (size_t __i = 0;
1125
         __i < _M_slice.size();
1126
         ++__i, __index += _M_slice.stride())
1127
      _M_array[__index] += __x[__i];
1128
  }
1129
1130
  void operator-=(const valarray<value_type>& __x) const {
1131
    size_t __index = _M_slice.start();
1132
    for (size_t __i = 0;
1133
         __i < _M_slice.size();
1134
         ++__i, __index += _M_slice.stride())
1135
      _M_array[__index] -= __x[__i];
1136
  }
1137
1138
  void operator^=(const valarray<value_type>& __x) const {
1139
    size_t __index = _M_slice.start();
1140
    for (size_t __i = 0;
1141
         __i < _M_slice.size();
1142
         ++__i, __index += _M_slice.stride())
1143
      _M_array[__index] ^= __x[__i];
1144
  }
1145
1146
  void operator&=(const valarray<value_type>& __x) const {
1147
    size_t __index = _M_slice.start();
1148
    for (size_t __i = 0;
1149
         __i < _M_slice.size();
1150
         ++__i, __index += _M_slice.stride())
1151
      _M_array[__index] &= __x[__i];
1152
  }
1153
1154
  void operator|=(const valarray<value_type>& __x) const {
1155
    size_t __index = _M_slice.start();
1156
    for (size_t __i = 0;
1157
         __i < _M_slice.size();
1158
         ++__i, __index += _M_slice.stride())
1159
      _M_array[__index] |= __x[__i];
1160
  }
1161
1162
  void operator<<=(const valarray<value_type>& __x) const {
1163
    size_t __index = _M_slice.start();
1164
    for (size_t __i = 0;
1165
         __i < _M_slice.size();
1166
         ++__i, __index += _M_slice.stride())
1167
      _M_array[__index] <<= __x[__i];
1168
  }
1169
1170
  void operator>>=(const valarray<value_type>& __x) const {
1171
    size_t __index = _M_slice.start();
1172
    for (size_t __i = 0;
1173
         __i < _M_slice.size();
1174
         ++__i, __index += _M_slice.stride())
1175
      _M_array[__index] >>= __x[__i];
1176
  }
1177
1178
  void operator=(const value_type& __c) /*const could be const but standard says NO (26.3.5.4-1)*/ {
1179
    size_t __index = _M_slice.start();
1180
    for (size_t __i = 0;
1181
         __i < _M_slice.size();
1182
         ++__i, __index += _M_slice.stride())
1183
      _M_array[__index] = __c;
1184
  }
1185
1186
  // C++ Standard defect 253, copy constructor must be public.
1187
  slice_array(const slice_array &__x)
1188
    : _M_slice(__x._M_slice), _M_array(__x._M_array)
1189
    {}
1190
1191
  ~slice_array() {}
1192
1193
private:
1194
  slice_array(const slice& __slice, valarray<_Tp> &__array)
1195
    : _M_slice(__slice), _M_array(__array)
1196
    {}
1197
1198
  slice          _M_slice;
1199
  valarray<_Tp>& _M_array;
1200
1201
private:
1202
  // Disable default constructor and assignment
1203
  slice_array();
1204
  slice_array& operator=(const slice_array&);
1205
};
1206
1207
// valarray member functions dealing with slice and slice_array
1208
1209
template <class _Tp>
1210
inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x) :
1211
    _Valarray_base<_Tp>(__x._M_slice.size())
1212
{
1213
  uninitialized_fill_n(this->_M_first, this->_M_size, _Tp() );
1214
  *this = __x;
1215
}
1216
1217
1218
template <class _Tp>
1219
inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice)
1220
{ return slice_array<_Tp>(__slice, *this); }
1221
1222
//----------------------------------------------------------------------
1223
// gslice and gslice_array
1224
1225
template <class _Size>
1226
struct _Gslice_Iter_tmpl;
1227
1228
class gslice {
1229
  friend struct _Gslice_Iter_tmpl<size_t>;
1230
public:
1231
  gslice() : _M_start(0), _M_lengths(), _M_strides() {}
1232
  gslice(size_t __start,
1233
         const _Valarray_size_t& __lengths, const _Valarray_size_t& __strides)
1234
    : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides)
1235
    {}
1236
  __TRIVIAL_DESTRUCTOR(gslice)
1237
1238
  size_t start()            const { return _M_start; }
1239
  _Valarray_size_t size()   const { return _M_lengths; }
1240
  _Valarray_size_t stride() const { return _M_strides; }
1241
1242
  // Extension: check for an empty gslice.
1243
  bool _M_empty() const { return _M_lengths.size() == 0; }
1244
1245
  // Extension: number of indices this gslice represents.  (For a degenerate
1246
  // gslice, they're not necessarily all distinct.)
1247
  size_t _M_size() const {
1248
    return !this->_M_empty()
1249
      ? accumulate(_M_lengths._M_first + 1,
1250
                   _M_lengths._M_first + _M_lengths._M_size,
1251
                   _M_lengths[0],
1252
                   multiplies<size_t>())
1253
      : 0;
1254
  }
1255
1256
# ifndef __HP_aCC
1257
private:
1258
# endif
1259
1260
  size_t _M_start;
1261
  _Valarray_size_t _M_lengths;
1262
  _Valarray_size_t _M_strides;
1263
};
1264
1265
// This is not an STL iterator.  It is constructed from a gslice, and it
1266
// steps through the gslice indices in sequence.  See 23.3.6 of the C++
1267
// standard, paragraphs 2-3, for an explanation of the sequence.  At
1268
// each step we get two things: the ordinal (i.e. number of steps taken),
1269
// and the one-dimensional index.
1270
1271
template <class _Size>
1272
struct _Gslice_Iter_tmpl {
1273
  _Gslice_Iter_tmpl(const gslice& __gslice)
1274
    : _M_step(0), _M_1d_idx(__gslice.start()),
1275
      _M_indices(size_t(0), __gslice._M_lengths.size()),
1276
      _M_gslice(__gslice)
1277
    {}
1278
1279
  bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; }
1280
1281
  bool _M_incr();
1282
1283
  _Size _M_step;
1284
  _Size _M_1d_idx;
1285
1286
  valarray<_Size> _M_indices;
1287
  const gslice& _M_gslice;
1288
};
1289
1290
typedef _Gslice_Iter_tmpl<size_t> _Gslice_Iter;
1291
1292
template <class _Tp>
1293
class gslice_array {
1294
  friend class valarray<_Tp>;
1295
public:
1296
  typedef _Tp value_type;
1297
1298
  void operator= (const valarray<value_type>& __x) const {
1299
    if (!_M_gslice._M_empty()) {
1300
      _Gslice_Iter __i(_M_gslice);
1301
      do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr());
1302
    }
1303
  }
1304
1305
  void operator*= (const valarray<value_type>& __x) const {
1306
    if (!_M_gslice._M_empty()) {
1307
      _Gslice_Iter __i(_M_gslice);
1308
      do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr());
1309
    }
1310
  }
1311
1312
  void operator/= (const valarray<value_type>& __x) const {
1313
    if (!_M_gslice._M_empty()) {
1314
      _Gslice_Iter __i(_M_gslice);
1315
      do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr());
1316
    }
1317
  }
1318
1319
  void operator%= (const valarray<value_type>& __x) const {
1320
    if (!_M_gslice._M_empty()) {
1321
      _Gslice_Iter __i(_M_gslice);
1322
      do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr());
1323
    }
1324
  }
1325
1326
  void operator+= (const valarray<value_type>& __x) const {
1327
    if (!_M_gslice._M_empty()) {
1328
      _Gslice_Iter __i(_M_gslice);
1329
      do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr());
1330
    }
1331
  }
1332
1333
  void operator-= (const valarray<value_type>& __x) const {
1334
    if (!_M_gslice._M_empty()) {
1335
      _Gslice_Iter __i(_M_gslice);
1336
      do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr());
1337
    }
1338
  }
1339
1340
  void operator^= (const valarray<value_type>& __x) const {
1341
    if (!_M_gslice._M_empty()) {
1342
      _Gslice_Iter __i(_M_gslice);
1343
      do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr());
1344
    }
1345
  }
1346
1347
  void operator&= (const valarray<value_type>& __x) const {
1348
    if (!_M_gslice._M_empty()) {
1349
      _Gslice_Iter __i(_M_gslice);
1350
      do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr());
1351
    }
1352
  }
1353
1354
  void operator|= (const valarray<value_type>& __x) const {
1355
    if (!_M_gslice._M_empty()) {
1356
      _Gslice_Iter __i(_M_gslice);
1357
      do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr());
1358
    }
1359
  }
1360
1361
  void operator<<= (const valarray<value_type>& __x) const {
1362
    if (!_M_gslice._M_empty()) {
1363
      _Gslice_Iter __i(_M_gslice);
1364
      do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr());
1365
    }
1366
  }
1367
1368
  void operator>>= (const valarray<value_type>& __x) const {
1369
    if (!_M_gslice._M_empty()) {
1370
      _Gslice_Iter __i(_M_gslice);
1371
      do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr());
1372
    }
1373
  }
1374
1375
  void operator= (const value_type& __c) /*const could be const but standard says NO (26.3.7.4-1)*/ {
1376
    if (!_M_gslice._M_empty()) {
1377
      _Gslice_Iter __i(_M_gslice);
1378
      do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr());
1379
    }
1380
  }
1381
1382
  // C++ Standard defect 253, copy constructor must be public.
1383
  gslice_array(const gslice_array& __x)
1384
    : _M_gslice(__x._M_gslice), _M_array(__x._M_array)
1385
    {}
1386
1387
  ~gslice_array() {}
1388
1389
private:
1390
  gslice_array(const gslice &__gslice, valarray<_Tp> &__array)
1391
    : _M_gslice(__gslice), _M_array(__array)
1392
    {}
1393
1394
  gslice                _M_gslice;
1395
  valarray<value_type>& _M_array;
1396
1397
private:
1398
  // Disable default constructor and assignment
1399
  gslice_array();
1400
  void operator=(const gslice_array<_Tp>&);
1401
};
1402
1403
// valarray member functions dealing with gslice and gslice_array.  Note
1404
// that it is illegal (behavior is undefined) to construct a gslice_array
1405
// from a degenerate gslice.
1406
1407
template <class _Tp>
1408
inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x) :
1409
    _Valarray_base<_Tp>(__x._M_gslice._M_size())
1410
{
1411
  uninitialized_fill_n(this->_M_first, this->_M_size, _Tp() );
1412
  *this = __x;
1413
}
1414
1415
template <class _Tp>
1416
inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __slice)
1417
{ return gslice_array<_Tp>(__slice, *this); }
1418
1419
1420
//----------------------------------------------------------------------
1421
// mask_array
1422
1423
template <class _Tp>
1424
class mask_array {
1425
  friend class valarray<_Tp>;
1426
public:
1427
  typedef _Tp value_type;
1428
1429
  void operator=(const valarray<value_type>& __x) const {
1430
    size_t __idx = 0;
1431
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1432
      if (_M_mask[__i]) _M_array[__i] = __x[__idx++];
1433
  }
1434
1435
  void operator*=(const valarray<value_type>& __x) const {
1436
    size_t __idx = 0;
1437
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1438
      if (_M_mask[__i]) _M_array[__i] *= __x[__idx++];
1439
  }
1440
1441
  void operator/=(const valarray<value_type>& __x) const {
1442
    size_t __idx = 0;
1443
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1444
      if (_M_mask[__i]) _M_array[__i] /= __x[__idx++];
1445
  }
1446
1447
  void operator%=(const valarray<value_type>& __x) const {
1448
    size_t __idx = 0;
1449
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1450
      if (_M_mask[__i]) _M_array[__i] %= __x[__idx++];
1451
  }
1452
1453
  void operator+=(const valarray<value_type>& __x) const {
1454
    size_t __idx = 0;
1455
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1456
      if (_M_mask[__i]) _M_array[__i] += __x[__idx++];
1457
  }
1458
1459
  void operator-=(const valarray<value_type>& __x) const {
1460
    size_t __idx = 0;
1461
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1462
      if (_M_mask[__i]) _M_array[__i] -= __x[__idx++];
1463
  }
1464
1465
  void operator^=(const valarray<value_type>& __x) const {
1466
    size_t __idx = 0;
1467
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1468
      if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++];
1469
  }
1470
1471
  void operator&=(const valarray<value_type>& __x) const {
1472
    size_t __idx = 0;
1473
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1474
      if (_M_mask[__i]) _M_array[__i] &= __x[__idx++];
1475
  }
1476
1477
  void operator|=(const valarray<value_type>& __x) const {
1478
    size_t __idx = 0;
1479
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1480
      if (_M_mask[__i]) _M_array[__i] |= __x[__idx++];
1481
  }
1482
1483
  void operator<<=(const valarray<value_type>& __x) const {
1484
    size_t __idx = 0;
1485
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1486
      if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++];
1487
  }
1488
1489
  void operator>>=(const valarray<value_type>& __x) const {
1490
    size_t __idx = 0;
1491
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1492
      if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++];
1493
  }
1494
1495
  void operator=(const value_type& __c) const {
1496
    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1497
      if (_M_mask[__i]) _M_array[__i] = __c;
1498
  }
1499
1500
  // Extension: number of true values in the mask
1501
  size_t _M_num_true() const {
1502
    size_t __result = 0;
1503
    for (size_t __i = 0; __i < _M_mask.size(); ++__i)
1504
      if (_M_mask[__i]) ++__result;
1505
    return __result;
1506
  }
1507
1508
  // C++ Standard defect 253, copy constructor must be public.
1509
  mask_array(const mask_array& __x)
1510
    : _M_mask(__x._M_mask), _M_array(__x._M_array)
1511
    {}
1512
1513
  ~mask_array() {}
1514
1515
private:
1516
  mask_array(const _Valarray_bool& __mask, valarray<_Tp>& __array)
1517
    : _M_mask(__mask), _M_array(__array)
1518
    {}
1519
  _Valarray_bool _M_mask;
1520
  valarray<_Tp>& _M_array;
1521
1522
private:
1523
  // Disable default constructor and assignment
1524
  mask_array();
1525
  void operator=(const mask_array<_Tp>&);
1526
};
1527
1528
// valarray member functions dealing with mask_array
1529
1530
template <class _Tp>
1531
inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x) :
1532
    _Valarray_base<_Tp>(__x._M_num_true())
1533
{
1534
  uninitialized_fill_n(this->_M_first, this->_M_size, _Tp() );
1535
  *this = __x;
1536
}
1537
1538
// Behavior is undefined if __x._M_num_true() != this->size()
1539
template <class _Tp>
1540
inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) {
1541
  size_t __idx = 0;
1542
  for (size_t __i = 0; __i < __x._M_array.size(); ++__i)
1543
    if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i];
1544
  return *this;
1545
}
1546
1547
template <class _Tp>
1548
inline mask_array<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask) {
1549
  _STLP_ASSERT(__mask.size() == this->size())
1550
  return mask_array<_Tp>(__mask, *this);
1551
}
1552
1553
//----------------------------------------------------------------------
1554
// indirect_array
1555
1556
template <class _Tp>
1557
class indirect_array {
1558
  friend class valarray<_Tp>;
1559
public:
1560
  typedef _Tp value_type;
1561
1562
  void operator=(const valarray<value_type>& __x) const {
1563
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1564
      _M_array[_M_addr[__i]] = __x[__i];
1565
  }
1566
1567
  void operator*=(const valarray<value_type>& __x) const {
1568
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1569
      _M_array[_M_addr[__i]] *= __x[__i];
1570
  }
1571
1572
  void operator/=(const valarray<value_type>& __x) const {
1573
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1574
      _M_array[_M_addr[__i]] /= __x[__i];
1575
  }
1576
1577
  void operator%=(const valarray<value_type>& __x) const {
1578
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1579
      _M_array[_M_addr[__i]] %= __x[__i];
1580
  }
1581
1582
  void operator+=(const valarray<value_type>& __x) const {
1583
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1584
      _M_array[_M_addr[__i]] += __x[__i];
1585
  }
1586
1587
  void operator-=(const valarray<value_type>& __x) const {
1588
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1589
      _M_array[_M_addr[__i]] -= __x[__i];
1590
  }
1591
1592
  void operator^=(const valarray<value_type>& __x) const {
1593
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1594
      _M_array[_M_addr[__i]] ^= __x[__i];
1595
  }
1596
1597
  void operator&=(const valarray<value_type>& __x) const {
1598
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1599
      _M_array[_M_addr[__i]] &= __x[__i];
1600
  }
1601
1602
  void operator|=(const valarray<value_type>& __x) const {
1603
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1604
      _M_array[_M_addr[__i]] |= __x[__i];
1605
  }
1606
1607
  void operator<<=(const valarray<value_type>& __x) const {
1608
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1609
      _M_array[_M_addr[__i]] <<= __x[__i];
1610
  }
1611
1612
  void operator>>=(const valarray<value_type>& __x) const {
1613
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1614
      _M_array[_M_addr[__i]] >>= __x[__i];
1615
  }
1616
1617
  void operator=(const value_type& __c) const {
1618
    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1619
      _M_array[_M_addr[__i]] = __c;
1620
  }
1621
1622
  // C++ Standard defect 253, copy constructor must be public.
1623
  indirect_array(const indirect_array& __x)
1624
    : _M_addr(__x._M_addr), _M_array(__x._M_array)
1625
    {}
1626
1627
  ~indirect_array() {}
1628
1629
private:
1630
  indirect_array(const _Valarray_size_t& __addr, valarray<_Tp>& __array)
1631
    : _M_addr(__addr), _M_array(__array)
1632
  {}
1633
1634
  _Valarray_size_t _M_addr;
1635
  valarray<_Tp>&   _M_array;
1636
1637
private:
1638
  // Disable default constructor and assignment
1639
  indirect_array();
1640
  void operator=(const indirect_array<_Tp>&);
1641
};
1642
1643
// valarray member functions dealing with indirect_array
1644
1645
template <class _Tp>
1646
inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x) :
1647
    _Valarray_base<_Tp>(__x._M_addr.size())
1648
{
1649
  uninitialized_fill_n(this->_M_first, this->_M_size, _Tp() );
1650
  *this = __x;
1651
}
1652
1653
1654
template <class _Tp>
1655
inline indirect_array<_Tp>
1656
valarray<_Tp>::operator[](const _Valarray_size_t& __addr)
1657
{ return indirect_array<_Tp>(__addr, *this); }
1658
1659
_STLP_END_NAMESPACE
1660
1661
#include <stl/_valarray.c>
1662
1663
#if (_STLP_OUTERMOST_HEADER_ID == 0x76)
1664
#  include <stl/_epilog.h>
1665
#  undef _STLP_OUTERMOST_HEADER_ID
1666
#endif
1667
1668
#endif /* _STLP_VALARRAY */
1669
1670
// Local Variables:
1671
// mode:C++
1672
// End: