1// -*- C++ -*-
2//===-------------------------- valarray ----------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_VALARRAY
12#define _LIBCPP_VALARRAY
13
14/*
15    valarray synopsis
16
17namespace std
18{
19
20template<class T>
21class valarray
22{
23public:
24    typedef T value_type;
25
26    // construct/destroy:
27    valarray();
28    explicit valarray(size_t n);
29    valarray(const value_type& x, size_t n);
30    valarray(const value_type* px, size_t n);
31    valarray(const valarray& v);
32    valarray(valarray&& v);
33    valarray(const slice_array<value_type>& sa);
34    valarray(const gslice_array<value_type>& ga);
35    valarray(const mask_array<value_type>& ma);
36    valarray(const indirect_array<value_type>& ia);
37    valarray(initializer_list<value_type> il);
38    ~valarray();
39
40    // assignment:
41    valarray& operator=(const valarray& v);
42    valarray& operator=(valarray&& v);
43    valarray& operator=(initializer_list<value_type> il);
44    valarray& operator=(const value_type& x);
45    valarray& operator=(const slice_array<value_type>& sa);
46    valarray& operator=(const gslice_array<value_type>& ga);
47    valarray& operator=(const mask_array<value_type>& ma);
48    valarray& operator=(const indirect_array<value_type>& ia);
49
50    // element access:
51    const value_type& operator[](size_t i) const;
52    value_type&       operator[](size_t i);
53
54    // subset operations:
55    valarray                   operator[](slice s) const;
56    slice_array<value_type>    operator[](slice s);
57    valarray                   operator[](const gslice& gs) const;
58    gslice_array<value_type>   operator[](const gslice& gs);
59    valarray                   operator[](const valarray<bool>& vb) const;
60    mask_array<value_type>     operator[](const valarray<bool>& vb);
61    valarray                   operator[](const valarray<size_t>& vs) const;
62    indirect_array<value_type> operator[](const valarray<size_t>& vs);
63
64    // unary operators:
65    valarray       operator+() const;
66    valarray       operator-() const;
67    valarray       operator~() const;
68    valarray<bool> operator!() const;
69
70    // computed assignment:
71    valarray& operator*= (const value_type& x);
72    valarray& operator/= (const value_type& x);
73    valarray& operator%= (const value_type& x);
74    valarray& operator+= (const value_type& x);
75    valarray& operator-= (const value_type& x);
76    valarray& operator^= (const value_type& x);
77    valarray& operator&= (const value_type& x);
78    valarray& operator|= (const value_type& x);
79    valarray& operator<<=(const value_type& x);
80    valarray& operator>>=(const value_type& x);
81
82    valarray& operator*= (const valarray& v);
83    valarray& operator/= (const valarray& v);
84    valarray& operator%= (const valarray& v);
85    valarray& operator+= (const valarray& v);
86    valarray& operator-= (const valarray& v);
87    valarray& operator^= (const valarray& v);
88    valarray& operator|= (const valarray& v);
89    valarray& operator&= (const valarray& v);
90    valarray& operator<<=(const valarray& v);
91    valarray& operator>>=(const valarray& v);
92
93    // member functions:
94    void swap(valarray& v);
95
96    size_t size() const;
97
98    value_type sum() const;
99    value_type min() const;
100    value_type max() const;
101
102    valarray shift (int i) const;
103    valarray cshift(int i) const;
104    valarray apply(value_type f(value_type)) const;
105    valarray apply(value_type f(const value_type&)) const;
106    void resize(size_t n, value_type x = value_type());
107};
108
109class slice
110{
111public:
112    slice();
113    slice(size_t start, size_t size, size_t stride);
114
115    size_t start()  const;
116    size_t size()   const;
117    size_t stride() const;
118};
119
120template <class T>
121class slice_array
122{
123public:
124    typedef T value_type;
125
126    const slice_array& operator=(const slice_array& sa) const;
127    void operator=  (const valarray<value_type>& v) const;
128    void operator*= (const valarray<value_type>& v) const;
129    void operator/= (const valarray<value_type>& v) const;
130    void operator%= (const valarray<value_type>& v) const;
131    void operator+= (const valarray<value_type>& v) const;
132    void operator-= (const valarray<value_type>& v) const;
133    void operator^= (const valarray<value_type>& v) const;
134    void operator&= (const valarray<value_type>& v) const;
135    void operator|= (const valarray<value_type>& v) const;
136    void operator<<=(const valarray<value_type>& v) const;
137    void operator>>=(const valarray<value_type>& v) const;
138
139    void operator=(const value_type& x) const;
140
141    slice_array() = delete;
142};
143
144class gslice
145{
146public:
147    gslice();
148    gslice(size_t start, const valarray<size_t>& size,
149                         const valarray<size_t>& stride);
150
151    size_t           start()  const;
152    valarray<size_t> size()   const;
153    valarray<size_t> stride() const;
154};
155
156template <class T>
157class gslice_array
158{
159public:
160    typedef T value_type;
161
162    void operator=  (const valarray<value_type>& v) const;
163    void operator*= (const valarray<value_type>& v) const;
164    void operator/= (const valarray<value_type>& v) const;
165    void operator%= (const valarray<value_type>& v) const;
166    void operator+= (const valarray<value_type>& v) const;
167    void operator-= (const valarray<value_type>& v) const;
168    void operator^= (const valarray<value_type>& v) const;
169    void operator&= (const valarray<value_type>& v) const;
170    void operator|= (const valarray<value_type>& v) const;
171    void operator<<=(const valarray<value_type>& v) const;
172    void operator>>=(const valarray<value_type>& v) const;
173
174    gslice_array(const gslice_array& ga);
175    ~gslice_array();
176    const gslice_array& operator=(const gslice_array& ga) const;
177    void operator=(const value_type& x) const;
178
179    gslice_array() = delete;
180};
181
182template <class T>
183class mask_array
184{
185public:
186    typedef T value_type;
187
188    void operator=  (const valarray<value_type>& v) const;
189    void operator*= (const valarray<value_type>& v) const;
190    void operator/= (const valarray<value_type>& v) const;
191    void operator%= (const valarray<value_type>& v) const;
192    void operator+= (const valarray<value_type>& v) const;
193    void operator-= (const valarray<value_type>& v) const;
194    void operator^= (const valarray<value_type>& v) const;
195    void operator&= (const valarray<value_type>& v) const;
196    void operator|= (const valarray<value_type>& v) const;
197    void operator<<=(const valarray<value_type>& v) const;
198    void operator>>=(const valarray<value_type>& v) const;
199
200    mask_array(const mask_array& ma);
201    ~mask_array();
202    const mask_array& operator=(const mask_array& ma) const;
203    void operator=(const value_type& x) const;
204
205    mask_array() = delete;
206};
207
208template <class T>
209class indirect_array
210{
211public:
212    typedef T value_type;
213
214    void operator=  (const valarray<value_type>& v) const;
215    void operator*= (const valarray<value_type>& v) const;
216    void operator/= (const valarray<value_type>& v) const;
217    void operator%= (const valarray<value_type>& v) const;
218    void operator+= (const valarray<value_type>& v) const;
219    void operator-= (const valarray<value_type>& v) const;
220    void operator^= (const valarray<value_type>& v) const;
221    void operator&= (const valarray<value_type>& v) const;
222    void operator|= (const valarray<value_type>& v) const;
223    void operator<<=(const valarray<value_type>& v) const;
224    void operator>>=(const valarray<value_type>& v) const;
225
226    indirect_array(const indirect_array& ia);
227    ~indirect_array();
228    const indirect_array& operator=(const indirect_array& ia) const;
229    void operator=(const value_type& x) const;
230
231    indirect_array() = delete;
232};
233
234template<class T> void swap(valarray<T>& x, valarray<T>& y);
235
236template<class T> valarray<T> operator* (const valarray<T>& x, const valarray<T>& y);
237template<class T> valarray<T> operator* (const valarray<T>& x, const T& y);
238template<class T> valarray<T> operator* (const T& x, const valarray<T>& y);
239
240template<class T> valarray<T> operator/ (const valarray<T>& x, const valarray<T>& y);
241template<class T> valarray<T> operator/ (const valarray<T>& x, const T& y);
242template<class T> valarray<T> operator/ (const T& x, const valarray<T>& y);
243
244template<class T> valarray<T> operator% (const valarray<T>& x, const valarray<T>& y);
245template<class T> valarray<T> operator% (const valarray<T>& x, const T& y);
246template<class T> valarray<T> operator% (const T& x, const valarray<T>& y);
247
248template<class T> valarray<T> operator+ (const valarray<T>& x, const valarray<T>& y);
249template<class T> valarray<T> operator+ (const valarray<T>& x, const T& y);
250template<class T> valarray<T> operator+ (const T& x, const valarray<T>& y);
251
252template<class T> valarray<T> operator- (const valarray<T>& x, const valarray<T>& y);
253template<class T> valarray<T> operator- (const valarray<T>& x, const T& y);
254template<class T> valarray<T> operator- (const T& x, const valarray<T>& y);
255
256template<class T> valarray<T> operator^ (const valarray<T>& x, const valarray<T>& y);
257template<class T> valarray<T> operator^ (const valarray<T>& x, const T& y);
258template<class T> valarray<T> operator^ (const T& x, const valarray<T>& y);
259
260template<class T> valarray<T> operator& (const valarray<T>& x, const valarray<T>& y);
261template<class T> valarray<T> operator& (const valarray<T>& x, const T& y);
262template<class T> valarray<T> operator& (const T& x, const valarray<T>& y);
263
264template<class T> valarray<T> operator| (const valarray<T>& x, const valarray<T>& y);
265template<class T> valarray<T> operator| (const valarray<T>& x, const T& y);
266template<class T> valarray<T> operator| (const T& x, const valarray<T>& y);
267
268template<class T> valarray<T> operator<<(const valarray<T>& x, const valarray<T>& y);
269template<class T> valarray<T> operator<<(const valarray<T>& x, const T& y);
270template<class T> valarray<T> operator<<(const T& x, const valarray<T>& y);
271
272template<class T> valarray<T> operator>>(const valarray<T>& x, const valarray<T>& y);
273template<class T> valarray<T> operator>>(const valarray<T>& x, const T& y);
274template<class T> valarray<T> operator>>(const T& x, const valarray<T>& y);
275
276template<class T> valarray<bool> operator&&(const valarray<T>& x, const valarray<T>& y);
277template<class T> valarray<bool> operator&&(const valarray<T>& x, const T& y);
278template<class T> valarray<bool> operator&&(const T& x, const valarray<T>& y);
279
280template<class T> valarray<bool> operator||(const valarray<T>& x, const valarray<T>& y);
281template<class T> valarray<bool> operator||(const valarray<T>& x, const T& y);
282template<class T> valarray<bool> operator||(const T& x, const valarray<T>& y);
283
284template<class T> valarray<bool> operator==(const valarray<T>& x, const valarray<T>& y);
285template<class T> valarray<bool> operator==(const valarray<T>& x, const T& y);
286template<class T> valarray<bool> operator==(const T& x, const valarray<T>& y);
287
288template<class T> valarray<bool> operator!=(const valarray<T>& x, const valarray<T>& y);
289template<class T> valarray<bool> operator!=(const valarray<T>& x, const T& y);
290template<class T> valarray<bool> operator!=(const T& x, const valarray<T>& y);
291
292template<class T> valarray<bool> operator< (const valarray<T>& x, const valarray<T>& y);
293template<class T> valarray<bool> operator< (const valarray<T>& x, const T& y);
294template<class T> valarray<bool> operator< (const T& x, const valarray<T>& y);
295
296template<class T> valarray<bool> operator> (const valarray<T>& x, const valarray<T>& y);
297template<class T> valarray<bool> operator> (const valarray<T>& x, const T& y);
298template<class T> valarray<bool> operator> (const T& x, const valarray<T>& y);
299
300template<class T> valarray<bool> operator<=(const valarray<T>& x, const valarray<T>& y);
301template<class T> valarray<bool> operator<=(const valarray<T>& x, const T& y);
302template<class T> valarray<bool> operator<=(const T& x, const valarray<T>& y);
303
304template<class T> valarray<bool> operator>=(const valarray<T>& x, const valarray<T>& y);
305template<class T> valarray<bool> operator>=(const valarray<T>& x, const T& y);
306template<class T> valarray<bool> operator>=(const T& x, const valarray<T>& y);
307
308template<class T> valarray<T> abs (const valarray<T>& x);
309template<class T> valarray<T> acos (const valarray<T>& x);
310template<class T> valarray<T> asin (const valarray<T>& x);
311template<class T> valarray<T> atan (const valarray<T>& x);
312
313template<class T> valarray<T> atan2(const valarray<T>& x, const valarray<T>& y);
314template<class T> valarray<T> atan2(const valarray<T>& x, const T& y);
315template<class T> valarray<T> atan2(const T& x, const valarray<T>& y);
316
317template<class T> valarray<T> cos (const valarray<T>& x);
318template<class T> valarray<T> cosh (const valarray<T>& x);
319template<class T> valarray<T> exp (const valarray<T>& x);
320template<class T> valarray<T> log (const valarray<T>& x);
321template<class T> valarray<T> log10(const valarray<T>& x);
322
323template<class T> valarray<T> pow(const valarray<T>& x, const valarray<T>& y);
324template<class T> valarray<T> pow(const valarray<T>& x, const T& y);
325template<class T> valarray<T> pow(const T& x, const valarray<T>& y);
326
327template<class T> valarray<T> sin (const valarray<T>& x);
328template<class T> valarray<T> sinh (const valarray<T>& x);
329template<class T> valarray<T> sqrt (const valarray<T>& x);
330template<class T> valarray<T> tan (const valarray<T>& x);
331template<class T> valarray<T> tanh (const valarray<T>& x);
332
333template <class T> unspecified1 begin(valarray<T>& v);
334template <class T> unspecified2 begin(const valarray<T>& v);
335template <class T> unspecified1 end(valarray<T>& v);
336template <class T> unspecified2 end(const valarray<T>& v);
337
338}  // std
339
340*/
341
342#include <__config>
343#include <cstddef>
344#include <cmath>
345#include <initializer_list>
346#include <algorithm>
347#include <functional>
348
349#pragma GCC system_header
350
351_LIBCPP_BEGIN_NAMESPACE_STD
352
353template<class _Tp> class valarray;
354
355class slice
356{
357    size_t __start_;
358    size_t __size_;
359    size_t __stride_;
360public:
361    _LIBCPP_ALWAYS_INLINE
362    slice()
363        : __start_(0),
364          __size_(0),
365          __stride_(0)
366          {}
367
368    _LIBCPP_ALWAYS_INLINE
369    slice(size_t __start, size_t __size, size_t __stride)
370        : __start_(__start),
371          __size_(__size),
372          __stride_(__stride)
373          {}
374
375    _LIBCPP_ALWAYS_INLINE size_t start()  const {return __start_;}
376    _LIBCPP_ALWAYS_INLINE size_t size()   const {return __size_;}
377    _LIBCPP_ALWAYS_INLINE size_t stride() const {return __stride_;}
378};
379
380template <class _Tp> class slice_array;
381class gslice;
382template <class _Tp> class gslice_array;
383template <class _Tp> class mask_array;
384template <class _Tp> class indirect_array;
385
386template <class _Tp>
387_Tp*
388begin(valarray<_Tp>& __v);
389
390template <class _Tp>
391const _Tp*
392begin(const valarray<_Tp>& __v);
393
394template <class _Tp>
395_Tp*
396end(valarray<_Tp>& __v);
397
398template <class _Tp>
399const _Tp*
400end(const valarray<_Tp>& __v);
401
402template <class _Op, class _A0>
403struct _UnaryOp
404{
405    typedef typename _Op::result_type result_type;
406    typedef typename _A0::value_type value_type;
407
408    _Op __op_;
409    _A0 __a0_;
410
411    _LIBCPP_ALWAYS_INLINE
412    _UnaryOp(const _Op& __op, const _A0& __a0) : __op_(__op), __a0_(__a0) {}
413
414    _LIBCPP_ALWAYS_INLINE
415    result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
416
417    _LIBCPP_ALWAYS_INLINE
418    size_t size() const {return __a0_.size();}
419};
420
421template <class _Op, class _A0, class _A1>
422struct _BinaryOp
423{
424    typedef typename _Op::result_type result_type;
425    typedef typename _A0::value_type value_type;
426
427    _Op __op_;
428    _A0 __a0_;
429    _A1 __a1_;
430
431    _LIBCPP_ALWAYS_INLINE
432    _BinaryOp(const _Op& __op, const _A0& __a0, const _A1& __a1)
433        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
434
435    _LIBCPP_ALWAYS_INLINE
436    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
437
438    _LIBCPP_ALWAYS_INLINE
439    size_t size() const {return __a0_.size();}
440};
441
442template <class _Tp>
443class __scalar_expr
444{
445public:
446    typedef _Tp        value_type;
447    typedef const _Tp& result_type;
448private:
449    const value_type& __t_;
450    size_t __s_;
451public:
452    _LIBCPP_ALWAYS_INLINE
453    explicit __scalar_expr(const value_type& __t, size_t __s) : __t_(__t), __s_(__s) {}
454
455    _LIBCPP_ALWAYS_INLINE
456    result_type operator[](size_t) const {return __t_;}
457
458    _LIBCPP_ALWAYS_INLINE
459    size_t size() const {return __s_;}
460};
461
462template <class _Tp>
463struct __unary_plus : unary_function<_Tp, _Tp>
464{
465    _LIBCPP_ALWAYS_INLINE
466    _Tp operator()(const _Tp& __x) const
467        {return +__x;}
468};
469
470template <class _Tp>
471struct __bit_not  : unary_function<_Tp, _Tp>
472{
473    _LIBCPP_ALWAYS_INLINE
474    _Tp operator()(const _Tp& __x) const
475        {return ~__x;}
476};
477
478template <class _Tp>
479struct __bit_shift_left : binary_function<_Tp, _Tp, _Tp>
480{
481    _LIBCPP_ALWAYS_INLINE
482    _Tp operator()(const _Tp& __x, const _Tp& __y) const
483        {return __x << __y;}
484};
485
486template <class _Tp>
487struct __bit_shift_right : binary_function<_Tp, _Tp, _Tp>
488{
489    _LIBCPP_ALWAYS_INLINE
490    _Tp operator()(const _Tp& __x, const _Tp& __y) const
491        {return __x >> __y;}
492};
493
494template <class _Tp, class _F>
495struct __apply_expr   : unary_function<_Tp, _Tp>
496{
497private:
498    _F __f_;
499public:
500    _LIBCPP_ALWAYS_INLINE
501    explicit __apply_expr(_F __f) : __f_(__f) {}
502
503    _LIBCPP_ALWAYS_INLINE
504    _Tp operator()(const _Tp& __x) const
505        {return __f_(__x);}
506};
507
508template <class _Tp>
509struct __abs_expr : unary_function<_Tp, _Tp>
510{
511    _LIBCPP_ALWAYS_INLINE
512    _Tp operator()(const _Tp& __x) const
513        {return abs(__x);}
514};
515
516template <class _Tp>
517struct __acos_expr : unary_function<_Tp, _Tp>
518{
519    _LIBCPP_ALWAYS_INLINE
520    _Tp operator()(const _Tp& __x) const
521        {return acos(__x);}
522};
523
524template <class _Tp>
525struct __asin_expr : unary_function<_Tp, _Tp>
526{
527    _LIBCPP_ALWAYS_INLINE
528    _Tp operator()(const _Tp& __x) const
529        {return asin(__x);}
530};
531
532template <class _Tp>
533struct __atan_expr : unary_function<_Tp, _Tp>
534{
535    _LIBCPP_ALWAYS_INLINE
536    _Tp operator()(const _Tp& __x) const
537        {return atan(__x);}
538};
539
540template <class _Tp>
541struct __atan2_expr : binary_function<_Tp, _Tp, _Tp>
542{
543    _LIBCPP_ALWAYS_INLINE
544    _Tp operator()(const _Tp& __x, const _Tp& __y) const
545        {return atan2(__x, __y);}
546};
547
548template <class _Tp>
549struct __cos_expr : unary_function<_Tp, _Tp>
550{
551    _LIBCPP_ALWAYS_INLINE
552    _Tp operator()(const _Tp& __x) const
553        {return cos(__x);}
554};
555
556template <class _Tp>
557struct __cosh_expr : unary_function<_Tp, _Tp>
558{
559    _LIBCPP_ALWAYS_INLINE
560    _Tp operator()(const _Tp& __x) const
561        {return cosh(__x);}
562};
563
564template <class _Tp>
565struct __exp_expr : unary_function<_Tp, _Tp>
566{
567    _LIBCPP_ALWAYS_INLINE
568    _Tp operator()(const _Tp& __x) const
569        {return exp(__x);}
570};
571
572template <class _Tp>
573struct __log_expr : unary_function<_Tp, _Tp>
574{
575    _LIBCPP_ALWAYS_INLINE
576    _Tp operator()(const _Tp& __x) const
577        {return log(__x);}
578};
579
580template <class _Tp>
581struct __log10_expr : unary_function<_Tp, _Tp>
582{
583    _LIBCPP_ALWAYS_INLINE
584    _Tp operator()(const _Tp& __x) const
585        {return log10(__x);}
586};
587
588template <class _Tp>
589struct __pow_expr : binary_function<_Tp, _Tp, _Tp>
590{
591    _LIBCPP_ALWAYS_INLINE
592    _Tp operator()(const _Tp& __x, const _Tp& __y) const
593        {return pow(__x, __y);}
594};
595
596template <class _Tp>
597struct __sin_expr : unary_function<_Tp, _Tp>
598{
599    _LIBCPP_ALWAYS_INLINE
600    _Tp operator()(const _Tp& __x) const
601        {return sin(__x);}
602};
603
604template <class _Tp>
605struct __sinh_expr : unary_function<_Tp, _Tp>
606{
607    _LIBCPP_ALWAYS_INLINE
608    _Tp operator()(const _Tp& __x) const
609        {return sinh(__x);}
610};
611
612template <class _Tp>
613struct __sqrt_expr : unary_function<_Tp, _Tp>
614{
615    _LIBCPP_ALWAYS_INLINE
616    _Tp operator()(const _Tp& __x) const
617        {return sqrt(__x);}
618};
619
620template <class _Tp>
621struct __tan_expr : unary_function<_Tp, _Tp>
622{
623    _LIBCPP_ALWAYS_INLINE
624    _Tp operator()(const _Tp& __x) const
625        {return tan(__x);}
626};
627
628template <class _Tp>
629struct __tanh_expr : unary_function<_Tp, _Tp>
630{
631    _LIBCPP_ALWAYS_INLINE
632    _Tp operator()(const _Tp& __x) const
633        {return tanh(__x);}
634};
635
636template <class _ValExpr>
637class __slice_expr
638{
639    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
640public:
641    typedef typename _RmExpr::value_type value_type;
642    typedef value_type result_type;
643
644private:
645    _ValExpr __expr_;
646    size_t __start_;
647    size_t __size_;
648    size_t __stride_;
649
650    _LIBCPP_ALWAYS_INLINE
651    __slice_expr(const slice& __sl, const _RmExpr& __e)
652        : __expr_(__e),
653          __start_(__sl.start()),
654          __size_(__sl.size()),
655          __stride_(__sl.stride())
656        {}
657public:
658
659    _LIBCPP_ALWAYS_INLINE
660    result_type operator[](size_t __i) const
661        {return __expr_[__start_ + __i * __stride_];}
662
663    _LIBCPP_ALWAYS_INLINE
664    size_t size() const {return __size_;}
665
666    template <class> friend class valarray;
667};
668
669template <class _ValExpr>
670class __mask_expr;
671
672template <class _ValExpr>
673class __indirect_expr;
674
675template <class _ValExpr>
676class __shift_expr
677{
678    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
679public:
680    typedef typename _RmExpr::value_type value_type;
681    typedef value_type result_type;
682
683private:
684    _ValExpr __expr_;
685    size_t __size_;
686    ptrdiff_t __ul_;
687    ptrdiff_t __sn_;
688    ptrdiff_t __n_;
689    static const ptrdiff_t _N = static_cast<ptrdiff_t>(
690                                    sizeof(ptrdiff_t) * __CHAR_BIT__ - 1);
691
692    _LIBCPP_ALWAYS_INLINE
693    __shift_expr(int __n, const _RmExpr& __e)
694        : __expr_(__e),
695          __size_(__e.size()),
696          __n_(__n)
697        {
698            ptrdiff_t __neg_n = static_cast<ptrdiff_t>(__n_ >> _N);
699            __sn_ = __neg_n | static_cast<ptrdiff_t>(static_cast<size_t>(-__n_) >> _N);
700            __ul_ = ((__size_ - __n_) & ~__neg_n) | ((__n_ + 1) & __neg_n);
701        }
702public:
703
704    _LIBCPP_ALWAYS_INLINE
705    result_type operator[](size_t __j) const
706        {
707            ptrdiff_t __i = static_cast<size_t>(__j);
708            ptrdiff_t __m = (__sn_ * __i - __ul_) >> _N;
709            return (__expr_[(__i + __n_) & __m] & __m) | (value_type() & ~__m);
710        }
711
712    _LIBCPP_ALWAYS_INLINE
713    size_t size() const {return __size_;}
714
715    template <class> friend class __val_expr;
716};
717
718template <class _ValExpr>
719class __cshift_expr
720{
721    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
722public:
723    typedef typename _RmExpr::value_type value_type;
724    typedef value_type result_type;
725
726private:
727    _ValExpr __expr_;
728    size_t __size_;
729    size_t __m_;
730    size_t __o1_;
731    size_t __o2_;
732
733    _LIBCPP_ALWAYS_INLINE
734    __cshift_expr(int __n, const _RmExpr& __e)
735        : __expr_(__e),
736          __size_(__e.size())
737        {
738            __n %= static_cast<int>(__size_);
739            if (__n >= 0)
740            {
741                __m_ = __size_ - __n;
742                __o1_ = __n;
743                __o2_ = __n - __size_;
744            }
745            else
746            {
747                __m_ = -__n;
748                __o1_ = __n + __size_;
749                __o2_ = __n;
750            }
751        }
752public:
753
754    _LIBCPP_ALWAYS_INLINE
755    result_type operator[](size_t __i) const
756        {
757            if (__i < __m_)
758                return __expr_[__i + __o1_];
759            return __expr_[__i + __o2_];
760        }
761
762    _LIBCPP_ALWAYS_INLINE
763    size_t size() const {return __size_;}
764
765    template <class> friend class __val_expr;
766};
767
768template<class _ValExpr>
769class __val_expr;
770
771template<class _ValExpr>
772struct __is_val_expr : false_type {};
773
774template<class _ValExpr>
775struct __is_val_expr<__val_expr<_ValExpr> > : true_type {};
776
777template<class _Tp>
778struct __is_val_expr<valarray<_Tp> > : true_type {};
779
780template<class _Tp>
781class valarray
782{
783public:
784    typedef _Tp value_type;
785    typedef _Tp result_type;
786
787private:
788    value_type* __begin_;
789    value_type* __end_;
790
791public:
792    // construct/destroy:
793    valarray() : __begin_(0), __end_(0) {}
794    explicit valarray(size_t __n);
795    valarray(const value_type& __x, size_t __n);
796    valarray(const value_type* __p, size_t __n);
797    valarray(const valarray& __v);
798#ifdef _LIBCPP_MOVE
799    valarray(valarray&& __v);
800    valarray(initializer_list<value_type> __il);
801#endif
802    valarray(const slice_array<value_type>& __sa);
803    valarray(const gslice_array<value_type>& __ga);
804    valarray(const mask_array<value_type>& __ma);
805    valarray(const indirect_array<value_type>& __ia);
806    ~valarray();
807
808    // assignment:
809    valarray& operator=(const valarray& __v);
810#ifdef _LIBCPP_MOVE
811    valarray& operator=(valarray&& __v);
812    valarray& operator=(initializer_list<value_type>);
813#endif
814    valarray& operator=(const value_type& __x);
815    valarray& operator=(const slice_array<value_type>& __sa);
816    valarray& operator=(const gslice_array<value_type>& __ga);
817    valarray& operator=(const mask_array<value_type>& __ma);
818    valarray& operator=(const indirect_array<value_type>& __ia);
819
820    // element access:
821    _LIBCPP_ALWAYS_INLINE
822    const value_type& operator[](size_t __i) const {return __begin_[__i];}
823
824    _LIBCPP_ALWAYS_INLINE
825    value_type&       operator[](size_t __i)       {return __begin_[__i];}
826
827    // subset operations:
828    __val_expr<__slice_expr<const valarray&> >    operator[](slice __s) const;
829    slice_array<value_type>                       operator[](slice __s);
830    __val_expr<__indirect_expr<const valarray&> > operator[](const gslice& __gs) const;
831    gslice_array<value_type>   operator[](const gslice& __gs);
832#ifdef _LIBCPP_MOVE
833    __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
834    gslice_array<value_type>                      operator[](gslice&& __gs);
835#endif
836    __val_expr<__mask_expr<const valarray&> >     operator[](const valarray<bool>& __vb) const;
837    mask_array<value_type>                        operator[](const valarray<bool>& __vb);
838#ifdef _LIBCPP_MOVE
839    __val_expr<__mask_expr<const valarray&> >     operator[](valarray<bool>&& __vb) const;
840    mask_array<value_type>                        operator[](valarray<bool>&& __vb);
841#endif
842    __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;
843    indirect_array<value_type>                    operator[](const valarray<size_t>& __vs);
844#ifdef _LIBCPP_MOVE
845    __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;
846    indirect_array<value_type>                    operator[](valarray<size_t>&& __vs);
847#endif
848
849    // unary operators:
850    valarray       operator+() const;
851    valarray       operator-() const;
852    valarray       operator~() const;
853    valarray<bool> operator!() const;
854
855    // computed assignment:
856    valarray& operator*= (const value_type& __x);
857    valarray& operator/= (const value_type& __x);
858    valarray& operator%= (const value_type& __x);
859    valarray& operator+= (const value_type& __x);
860    valarray& operator-= (const value_type& __x);
861    valarray& operator^= (const value_type& __x);
862    valarray& operator&= (const value_type& __x);
863    valarray& operator|= (const value_type& __x);
864    valarray& operator<<=(const value_type& __x);
865    valarray& operator>>=(const value_type& __x);
866
867    template <class _Expr>
868    typename enable_if
869    <
870        __is_val_expr<_Expr>::value,
871        valarray&
872    >::type
873    operator*= (const _Expr& __v);
874
875    template <class _Expr>
876    typename enable_if
877    <
878        __is_val_expr<_Expr>::value,
879        valarray&
880    >::type
881    operator/= (const _Expr& __v);
882
883    template <class _Expr>
884    typename enable_if
885    <
886        __is_val_expr<_Expr>::value,
887        valarray&
888    >::type
889    operator%= (const _Expr& __v);
890
891    template <class _Expr>
892    typename enable_if
893    <
894        __is_val_expr<_Expr>::value,
895        valarray&
896    >::type
897    operator+= (const _Expr& __v);
898
899    template <class _Expr>
900    typename enable_if
901    <
902        __is_val_expr<_Expr>::value,
903        valarray&
904    >::type
905    operator-= (const _Expr& __v);
906
907    template <class _Expr>
908    typename enable_if
909    <
910        __is_val_expr<_Expr>::value,
911        valarray&
912    >::type
913    operator^= (const _Expr& __v);
914
915    template <class _Expr>
916    typename enable_if
917    <
918        __is_val_expr<_Expr>::value,
919        valarray&
920    >::type
921    operator|= (const _Expr& __v);
922
923    template <class _Expr>
924    typename enable_if
925    <
926        __is_val_expr<_Expr>::value,
927        valarray&
928    >::type
929    operator&= (const _Expr& __v);
930
931    template <class _Expr>
932    typename enable_if
933    <
934        __is_val_expr<_Expr>::value,
935        valarray&
936    >::type
937    operator<<= (const _Expr& __v);
938
939    template <class _Expr>
940    typename enable_if
941    <
942        __is_val_expr<_Expr>::value,
943        valarray&
944    >::type
945    operator>>= (const _Expr& __v);
946
947    // member functions:
948    void swap(valarray& __v);
949
950    _LIBCPP_ALWAYS_INLINE
951    size_t size() const {return __end_ - __begin_;}
952
953    value_type sum() const;
954    value_type min() const;
955    value_type max() const;
956
957    valarray shift (int __i) const;
958    valarray cshift(int __i) const;
959    valarray apply(value_type __f(value_type)) const;
960    valarray apply(value_type __f(const value_type&)) const;
961    void     resize(size_t __n, value_type __x = value_type());
962
963private:
964    template <class> friend class valarray;
965    template <class> friend class slice_array;
966    template <class> friend class gslice_array;
967    template <class> friend class mask_array;
968    template <class> friend class __mask_expr;
969    template <class> friend class indirect_array;
970    template <class> friend class __indirect_expr;
971    template <class> friend class __val_expr;
972
973    template <class _Up>
974    friend
975    _Up*
976    begin(valarray<_Up>& __v);
977
978    template <class _Up>
979    friend
980    const _Up*
981    begin(const valarray<_Up>& __v);
982
983    template <class _Up>
984    friend
985    _Up*
986    end(valarray<_Up>& __v);
987
988    template <class _Up>
989    friend
990    const _Up*
991    end(const valarray<_Up>& __v);
992};
993
994template <class _Op, class _Tp>
995struct _UnaryOp<_Op, valarray<_Tp> >
996{
997    typedef typename _Op::result_type result_type;
998    typedef _Tp value_type;
999
1000    _Op __op_;
1001    const valarray<_Tp>& __a0_;
1002
1003    _LIBCPP_ALWAYS_INLINE
1004    _UnaryOp(const _Op& __op, const valarray<_Tp>& __a0) : __op_(__op), __a0_(__a0) {}
1005
1006    _LIBCPP_ALWAYS_INLINE
1007    result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
1008
1009    _LIBCPP_ALWAYS_INLINE
1010    size_t size() const {return __a0_.size();}
1011};
1012
1013template <class _Op, class _Tp, class _A1>
1014struct _BinaryOp<_Op, valarray<_Tp>, _A1>
1015{
1016    typedef typename _Op::result_type result_type;
1017    typedef _Tp value_type;
1018
1019    _Op __op_;
1020    const valarray<_Tp>& __a0_;
1021    _A1 __a1_;
1022
1023    _LIBCPP_ALWAYS_INLINE
1024    _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const _A1& __a1)
1025        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
1026
1027    _LIBCPP_ALWAYS_INLINE
1028    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
1029
1030    _LIBCPP_ALWAYS_INLINE
1031    size_t size() const {return __a0_.size();}
1032};
1033
1034template <class _Op, class _A0, class _Tp>
1035struct _BinaryOp<_Op, _A0, valarray<_Tp> >
1036{
1037    typedef typename _Op::result_type result_type;
1038    typedef _Tp value_type;
1039
1040    _Op __op_;
1041    _A0 __a0_;
1042    const valarray<_Tp>& __a1_;
1043
1044    _LIBCPP_ALWAYS_INLINE
1045    _BinaryOp(const _Op& __op, const _A0& __a0, const valarray<_Tp>& __a1)
1046        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
1047
1048    _LIBCPP_ALWAYS_INLINE
1049    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
1050
1051    _LIBCPP_ALWAYS_INLINE
1052    size_t size() const {return __a0_.size();}
1053};
1054
1055template <class _Op, class _Tp>
1056struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
1057{
1058    typedef typename _Op::result_type result_type;
1059    typedef _Tp value_type;
1060
1061    _Op __op_;
1062    const valarray<_Tp>& __a0_;
1063    const valarray<_Tp>& __a1_;
1064
1065    _LIBCPP_ALWAYS_INLINE
1066    _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const valarray<_Tp>& __a1)
1067        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
1068
1069    _LIBCPP_ALWAYS_INLINE
1070    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
1071
1072    _LIBCPP_ALWAYS_INLINE
1073    size_t size() const {return __a0_.size();}
1074};
1075
1076// slice_array
1077
1078template <class _Tp>
1079class slice_array
1080{
1081public:
1082    typedef _Tp value_type;
1083
1084private:
1085    value_type* __vp_;
1086    size_t __size_;
1087    size_t __stride_;
1088
1089public:
1090    template <class _Expr>
1091    typename enable_if
1092    <
1093        __is_val_expr<_Expr>::value,
1094        void
1095    >::type
1096    operator=(const _Expr& __v) const;
1097
1098    template <class _Expr>
1099    typename enable_if
1100    <
1101        __is_val_expr<_Expr>::value,
1102        void
1103    >::type
1104    operator*=(const _Expr& __v) const;
1105
1106    template <class _Expr>
1107    typename enable_if
1108    <
1109        __is_val_expr<_Expr>::value,
1110        void
1111    >::type
1112    operator/=(const _Expr& __v) const;
1113
1114    template <class _Expr>
1115    typename enable_if
1116    <
1117        __is_val_expr<_Expr>::value,
1118        void
1119    >::type
1120    operator%=(const _Expr& __v) const;
1121
1122    template <class _Expr>
1123    typename enable_if
1124    <
1125        __is_val_expr<_Expr>::value,
1126        void
1127    >::type
1128    operator+=(const _Expr& __v) const;
1129
1130    template <class _Expr>
1131    typename enable_if
1132    <
1133        __is_val_expr<_Expr>::value,
1134        void
1135    >::type
1136    operator-=(const _Expr& __v) const;
1137
1138    template <class _Expr>
1139    typename enable_if
1140    <
1141        __is_val_expr<_Expr>::value,
1142        void
1143    >::type
1144    operator^=(const _Expr& __v) const;
1145
1146    template <class _Expr>
1147    typename enable_if
1148    <
1149        __is_val_expr<_Expr>::value,
1150        void
1151    >::type
1152    operator&=(const _Expr& __v) const;
1153
1154    template <class _Expr>
1155    typename enable_if
1156    <
1157        __is_val_expr<_Expr>::value,
1158        void
1159    >::type
1160    operator|=(const _Expr& __v) const;
1161
1162    template <class _Expr>
1163    typename enable_if
1164    <
1165        __is_val_expr<_Expr>::value,
1166        void
1167    >::type
1168    operator<<=(const _Expr& __v) const;
1169
1170    template <class _Expr>
1171    typename enable_if
1172    <
1173        __is_val_expr<_Expr>::value,
1174        void
1175    >::type
1176    operator>>=(const _Expr& __v) const;
1177
1178    const slice_array& operator=(const slice_array& __sa) const;
1179
1180    void operator=(const value_type& __x) const;
1181
1182private:
1183    slice_array(const slice& __sl, const valarray<value_type>& __v)
1184        : __vp_(const_cast<value_type*>(__v.__begin_ + __sl.start())),
1185          __size_(__sl.size()),
1186          __stride_(__sl.stride())
1187        {}
1188
1189    template <class> friend class valarray;
1190    template <class> friend class sliceExpr;
1191};
1192
1193template <class _Tp>
1194inline _LIBCPP_ALWAYS_INLINE
1195const slice_array<_Tp>&
1196slice_array<_Tp>::operator=(const slice_array& __sa) const
1197{
1198    value_type* __t = __vp_;
1199    const value_type* __s = __sa.__vp_;
1200    for (size_t __n = __size_; __n; --__n, __t += __stride_, __s += __sa.__stride_)
1201        *__t = *__s;
1202}
1203
1204template <class _Tp>
1205template <class _Expr>
1206inline _LIBCPP_ALWAYS_INLINE
1207typename enable_if
1208<
1209    __is_val_expr<_Expr>::value,
1210    void
1211>::type
1212slice_array<_Tp>::operator=(const _Expr& __v) const
1213{
1214    value_type* __t = __vp_;
1215    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1216        *__t = __v[__i];
1217}
1218
1219template <class _Tp>
1220template <class _Expr>
1221inline _LIBCPP_ALWAYS_INLINE
1222typename enable_if
1223<
1224    __is_val_expr<_Expr>::value,
1225    void
1226>::type
1227slice_array<_Tp>::operator*=(const _Expr& __v) const
1228{
1229    value_type* __t = __vp_;
1230    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1231        *__t *= __v[__i];
1232}
1233
1234template <class _Tp>
1235template <class _Expr>
1236inline _LIBCPP_ALWAYS_INLINE
1237typename enable_if
1238<
1239    __is_val_expr<_Expr>::value,
1240    void
1241>::type
1242slice_array<_Tp>::operator/=(const _Expr& __v) const
1243{
1244    value_type* __t = __vp_;
1245    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1246        *__t /= __v[__i];
1247}
1248
1249template <class _Tp>
1250template <class _Expr>
1251inline _LIBCPP_ALWAYS_INLINE
1252typename enable_if
1253<
1254    __is_val_expr<_Expr>::value,
1255    void
1256>::type
1257slice_array<_Tp>::operator%=(const _Expr& __v) const
1258{
1259    value_type* __t = __vp_;
1260    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1261        *__t %= __v[__i];
1262}
1263
1264template <class _Tp>
1265template <class _Expr>
1266inline _LIBCPP_ALWAYS_INLINE
1267typename enable_if
1268<
1269    __is_val_expr<_Expr>::value,
1270    void
1271>::type
1272slice_array<_Tp>::operator+=(const _Expr& __v) const
1273{
1274    value_type* __t = __vp_;
1275    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1276        *__t += __v[__i];
1277}
1278
1279template <class _Tp>
1280template <class _Expr>
1281inline _LIBCPP_ALWAYS_INLINE
1282typename enable_if
1283<
1284    __is_val_expr<_Expr>::value,
1285    void
1286>::type
1287slice_array<_Tp>::operator-=(const _Expr& __v) const
1288{
1289    value_type* __t = __vp_;
1290    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1291        *__t -= __v[__i];
1292}
1293
1294template <class _Tp>
1295template <class _Expr>
1296inline _LIBCPP_ALWAYS_INLINE
1297typename enable_if
1298<
1299    __is_val_expr<_Expr>::value,
1300    void
1301>::type
1302slice_array<_Tp>::operator^=(const _Expr& __v) const
1303{
1304    value_type* __t = __vp_;
1305    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1306        *__t ^= __v[__i];
1307}
1308
1309template <class _Tp>
1310template <class _Expr>
1311inline _LIBCPP_ALWAYS_INLINE
1312typename enable_if
1313<
1314    __is_val_expr<_Expr>::value,
1315    void
1316>::type
1317slice_array<_Tp>::operator&=(const _Expr& __v) const
1318{
1319    value_type* __t = __vp_;
1320    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1321        *__t &= __v[__i];
1322}
1323
1324template <class _Tp>
1325template <class _Expr>
1326inline _LIBCPP_ALWAYS_INLINE
1327typename enable_if
1328<
1329    __is_val_expr<_Expr>::value,
1330    void
1331>::type
1332slice_array<_Tp>::operator|=(const _Expr& __v) const
1333{
1334    value_type* __t = __vp_;
1335    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1336        *__t |= __v[__i];
1337}
1338
1339template <class _Tp>
1340template <class _Expr>
1341inline _LIBCPP_ALWAYS_INLINE
1342typename enable_if
1343<
1344    __is_val_expr<_Expr>::value,
1345    void
1346>::type
1347slice_array<_Tp>::operator<<=(const _Expr& __v) const
1348{
1349    value_type* __t = __vp_;
1350    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1351        *__t <<= __v[__i];
1352}
1353
1354template <class _Tp>
1355template <class _Expr>
1356inline _LIBCPP_ALWAYS_INLINE
1357typename enable_if
1358<
1359    __is_val_expr<_Expr>::value,
1360    void
1361>::type
1362slice_array<_Tp>::operator>>=(const _Expr& __v) const
1363{
1364    value_type* __t = __vp_;
1365    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
1366        *__t >>= __v[__i];
1367}
1368
1369template <class _Tp>
1370inline _LIBCPP_ALWAYS_INLINE
1371void
1372slice_array<_Tp>::operator=(const value_type& __x) const
1373{
1374    value_type* __t = __vp_;
1375    for (size_t __n = __size_; __n; --__n, __t += __stride_)
1376        *__t = __x;
1377}
1378
1379// gslice
1380
1381class gslice
1382{
1383    valarray<size_t> __size_;
1384    valarray<size_t> __stride_;
1385    valarray<size_t> __1d_;
1386
1387public:
1388    _LIBCPP_ALWAYS_INLINE
1389    gslice() {}
1390
1391    _LIBCPP_ALWAYS_INLINE
1392    gslice(size_t __start, const valarray<size_t>& __size,
1393                           const valarray<size_t>& __stride)
1394        : __size_(__size),
1395          __stride_(__stride)
1396        {__init(__start);}
1397
1398#ifdef _LIBCPP_MOVE
1399
1400    _LIBCPP_ALWAYS_INLINE
1401    gslice(size_t __start, const valarray<size_t>&  __size,
1402                                 valarray<size_t>&& __stride)
1403        : __size_(__size),
1404          __stride_(move(__stride))
1405        {__init(__start);}
1406
1407    _LIBCPP_ALWAYS_INLINE
1408    gslice(size_t __start,       valarray<size_t>&& __size,
1409                           const valarray<size_t>&  __stride)
1410        : __size_(move(__size)),
1411          __stride_(__stride)
1412        {__init(__start);}
1413
1414    _LIBCPP_ALWAYS_INLINE
1415    gslice(size_t __start,       valarray<size_t>&& __size,
1416                                 valarray<size_t>&& __stride)
1417        : __size_(move(__size)),
1418          __stride_(move(__stride))
1419        {__init(__start);}
1420
1421#endif
1422
1423//  gslice(const gslice&)            = default;
1424//  gslice(gslice&&)                 = default;
1425//  gslice& operator=(const gslice&) = default;
1426//  gslice& operator=(gslice&&)      = default;
1427
1428    _LIBCPP_ALWAYS_INLINE
1429    size_t           start()  const {return __1d_.size() ? __1d_[0] : 0;}
1430
1431    _LIBCPP_ALWAYS_INLINE
1432    valarray<size_t> size()   const {return __size_;}
1433
1434    _LIBCPP_ALWAYS_INLINE
1435    valarray<size_t> stride() const {return __stride_;}
1436
1437private:
1438    void __init(size_t __start);
1439
1440    template <class> friend class gslice_array;
1441    template <class> friend class valarray;
1442    template <class> friend class __val_expr;
1443};
1444
1445// gslice_array
1446
1447template <class _Tp>
1448class gslice_array
1449{
1450public:
1451    typedef _Tp value_type;
1452
1453private:
1454    value_type*      __vp_;
1455    valarray<size_t> __1d_;
1456
1457public:
1458    template <class _Expr>
1459    typename enable_if
1460    <
1461        __is_val_expr<_Expr>::value,
1462        void
1463    >::type
1464    operator=(const _Expr& __v) const;
1465
1466    template <class _Expr>
1467    typename enable_if
1468    <
1469        __is_val_expr<_Expr>::value,
1470        void
1471    >::type
1472    operator*=(const _Expr& __v) const;
1473
1474    template <class _Expr>
1475    typename enable_if
1476    <
1477        __is_val_expr<_Expr>::value,
1478        void
1479    >::type
1480    operator/=(const _Expr& __v) const;
1481
1482    template <class _Expr>
1483    typename enable_if
1484    <
1485        __is_val_expr<_Expr>::value,
1486        void
1487    >::type
1488    operator%=(const _Expr& __v) const;
1489
1490    template <class _Expr>
1491    typename enable_if
1492    <
1493        __is_val_expr<_Expr>::value,
1494        void
1495    >::type
1496    operator+=(const _Expr& __v) const;
1497
1498    template <class _Expr>
1499    typename enable_if
1500    <
1501        __is_val_expr<_Expr>::value,
1502        void
1503    >::type
1504    operator-=(const _Expr& __v) const;
1505
1506    template <class _Expr>
1507    typename enable_if
1508    <
1509        __is_val_expr<_Expr>::value,
1510        void
1511    >::type
1512    operator^=(const _Expr& __v) const;
1513
1514    template <class _Expr>
1515    typename enable_if
1516    <
1517        __is_val_expr<_Expr>::value,
1518        void
1519    >::type
1520    operator&=(const _Expr& __v) const;
1521
1522    template <class _Expr>
1523    typename enable_if
1524    <
1525        __is_val_expr<_Expr>::value,
1526        void
1527    >::type
1528    operator|=(const _Expr& __v) const;
1529
1530    template <class _Expr>
1531    typename enable_if
1532    <
1533        __is_val_expr<_Expr>::value,
1534        void
1535    >::type
1536    operator<<=(const _Expr& __v) const;
1537
1538    template <class _Expr>
1539    typename enable_if
1540    <
1541        __is_val_expr<_Expr>::value,
1542        void
1543    >::type
1544    operator>>=(const _Expr& __v) const;
1545
1546    const gslice_array& operator=(const gslice_array& __ga) const;
1547
1548    void operator=(const value_type& __x) const;
1549
1550//  gslice_array(const gslice_array&)            = default;
1551//  gslice_array(gslice_array&&)                 = default;
1552//  gslice_array& operator=(const gslice_array&) = default;
1553//  gslice_array& operator=(gslice_array&&)      = default;
1554
1555private:
1556    _LIBCPP_ALWAYS_INLINE
1557    gslice_array(const gslice& __gs, const valarray<value_type>& __v)
1558        : __vp_(const_cast<value_type*>(__v.__begin_)),
1559          __1d_(__gs.__1d_)
1560        {}
1561
1562#ifdef _LIBCPP_MOVE
1563
1564    _LIBCPP_ALWAYS_INLINE
1565    gslice_array(gslice&& __gs, const valarray<value_type>& __v)
1566        : __vp_(const_cast<value_type*>(__v.__begin_)),
1567          __1d_(move(__gs.__1d_))
1568        {}
1569
1570#endif
1571
1572    template <class> friend class valarray;
1573};
1574
1575template <class _Tp>
1576template <class _Expr>
1577inline _LIBCPP_ALWAYS_INLINE
1578typename enable_if
1579<
1580    __is_val_expr<_Expr>::value,
1581    void
1582>::type
1583gslice_array<_Tp>::operator=(const _Expr& __v) const
1584{
1585    typedef const size_t* _Ip;
1586    size_t __j = 0;
1587    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1588        __vp_[*__i] = __v[__j];
1589}
1590
1591template <class _Tp>
1592template <class _Expr>
1593inline _LIBCPP_ALWAYS_INLINE
1594typename enable_if
1595<
1596    __is_val_expr<_Expr>::value,
1597    void
1598>::type
1599gslice_array<_Tp>::operator*=(const _Expr& __v) const
1600{
1601    typedef const size_t* _Ip;
1602    size_t __j = 0;
1603    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1604        __vp_[*__i] *= __v[__j];
1605}
1606
1607template <class _Tp>
1608template <class _Expr>
1609inline _LIBCPP_ALWAYS_INLINE
1610typename enable_if
1611<
1612    __is_val_expr<_Expr>::value,
1613    void
1614>::type
1615gslice_array<_Tp>::operator/=(const _Expr& __v) const
1616{
1617    typedef const size_t* _Ip;
1618    size_t __j = 0;
1619    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1620        __vp_[*__i] /= __v[__j];
1621}
1622
1623template <class _Tp>
1624template <class _Expr>
1625inline _LIBCPP_ALWAYS_INLINE
1626typename enable_if
1627<
1628    __is_val_expr<_Expr>::value,
1629    void
1630>::type
1631gslice_array<_Tp>::operator%=(const _Expr& __v) const
1632{
1633    typedef const size_t* _Ip;
1634    size_t __j = 0;
1635    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1636        __vp_[*__i] %= __v[__j];
1637}
1638
1639template <class _Tp>
1640template <class _Expr>
1641inline _LIBCPP_ALWAYS_INLINE
1642typename enable_if
1643<
1644    __is_val_expr<_Expr>::value,
1645    void
1646>::type
1647gslice_array<_Tp>::operator+=(const _Expr& __v) const
1648{
1649    typedef const size_t* _Ip;
1650    size_t __j = 0;
1651    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1652        __vp_[*__i] += __v[__j];
1653}
1654
1655template <class _Tp>
1656template <class _Expr>
1657inline _LIBCPP_ALWAYS_INLINE
1658typename enable_if
1659<
1660    __is_val_expr<_Expr>::value,
1661    void
1662>::type
1663gslice_array<_Tp>::operator-=(const _Expr& __v) const
1664{
1665    typedef const size_t* _Ip;
1666    size_t __j = 0;
1667    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1668        __vp_[*__i] -= __v[__j];
1669}
1670
1671template <class _Tp>
1672template <class _Expr>
1673inline _LIBCPP_ALWAYS_INLINE
1674typename enable_if
1675<
1676    __is_val_expr<_Expr>::value,
1677    void
1678>::type
1679gslice_array<_Tp>::operator^=(const _Expr& __v) const
1680{
1681    typedef const size_t* _Ip;
1682    size_t __j = 0;
1683    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1684        __vp_[*__i] ^= __v[__j];
1685}
1686
1687template <class _Tp>
1688template <class _Expr>
1689inline _LIBCPP_ALWAYS_INLINE
1690typename enable_if
1691<
1692    __is_val_expr<_Expr>::value,
1693    void
1694>::type
1695gslice_array<_Tp>::operator&=(const _Expr& __v) const
1696{
1697    typedef const size_t* _Ip;
1698    size_t __j = 0;
1699    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1700        __vp_[*__i] &= __v[__j];
1701}
1702
1703template <class _Tp>
1704template <class _Expr>
1705inline _LIBCPP_ALWAYS_INLINE
1706typename enable_if
1707<
1708    __is_val_expr<_Expr>::value,
1709    void
1710>::type
1711gslice_array<_Tp>::operator|=(const _Expr& __v) const
1712{
1713    typedef const size_t* _Ip;
1714    size_t __j = 0;
1715    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1716        __vp_[*__i] |= __v[__j];
1717}
1718
1719template <class _Tp>
1720template <class _Expr>
1721inline _LIBCPP_ALWAYS_INLINE
1722typename enable_if
1723<
1724    __is_val_expr<_Expr>::value,
1725    void
1726>::type
1727gslice_array<_Tp>::operator<<=(const _Expr& __v) const
1728{
1729    typedef const size_t* _Ip;
1730    size_t __j = 0;
1731    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1732        __vp_[*__i] <<= __v[__j];
1733}
1734
1735template <class _Tp>
1736template <class _Expr>
1737inline _LIBCPP_ALWAYS_INLINE
1738typename enable_if
1739<
1740    __is_val_expr<_Expr>::value,
1741    void
1742>::type
1743gslice_array<_Tp>::operator>>=(const _Expr& __v) const
1744{
1745    typedef const size_t* _Ip;
1746    size_t __j = 0;
1747    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
1748        __vp_[*__i] >>= __v[__j];
1749}
1750
1751template <class _Tp>
1752inline _LIBCPP_ALWAYS_INLINE
1753const gslice_array<_Tp>&
1754gslice_array<_Tp>::operator=(const gslice_array& __ga) const
1755{
1756    typedef const size_t* _Ip;
1757    const value_type* __s = __ga.__vp_;
1758    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ga.__1d_.__begin_;
1759            __i != __e; ++__i, ++__j)
1760        __vp_[*__i] = __s[*__j];
1761    return *this;
1762}
1763
1764template <class _Tp>
1765inline _LIBCPP_ALWAYS_INLINE
1766void
1767gslice_array<_Tp>::operator=(const value_type& __x) const
1768{
1769    typedef const size_t* _Ip;
1770    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i)
1771        __vp_[*__i] = __x;
1772}
1773
1774// mask_array
1775
1776template <class _Tp>
1777class mask_array
1778{
1779public:
1780    typedef _Tp value_type;
1781
1782private:
1783    value_type*      __vp_;
1784    valarray<size_t> __1d_;
1785
1786public:
1787    template <class _Expr>
1788    typename enable_if
1789    <
1790        __is_val_expr<_Expr>::value,
1791        void
1792    >::type
1793    operator=(const _Expr& __v) const;
1794
1795    template <class _Expr>
1796    typename enable_if
1797    <
1798        __is_val_expr<_Expr>::value,
1799        void
1800    >::type
1801    operator*=(const _Expr& __v) const;
1802
1803    template <class _Expr>
1804    typename enable_if
1805    <
1806        __is_val_expr<_Expr>::value,
1807        void
1808    >::type
1809    operator/=(const _Expr& __v) const;
1810
1811    template <class _Expr>
1812    typename enable_if
1813    <
1814        __is_val_expr<_Expr>::value,
1815        void
1816    >::type
1817    operator%=(const _Expr& __v) const;
1818
1819    template <class _Expr>
1820    typename enable_if
1821    <
1822        __is_val_expr<_Expr>::value,
1823        void
1824    >::type
1825    operator+=(const _Expr& __v) const;
1826
1827    template <class _Expr>
1828    typename enable_if
1829    <
1830        __is_val_expr<_Expr>::value,
1831        void
1832    >::type
1833    operator-=(const _Expr& __v) const;
1834
1835    template <class _Expr>
1836    typename enable_if
1837    <
1838        __is_val_expr<_Expr>::value,
1839        void
1840    >::type
1841    operator^=(const _Expr& __v) const;
1842
1843    template <class _Expr>
1844    typename enable_if
1845    <
1846        __is_val_expr<_Expr>::value,
1847        void
1848    >::type
1849    operator&=(const _Expr& __v) const;
1850
1851    template <class _Expr>
1852    typename enable_if
1853    <
1854        __is_val_expr<_Expr>::value,
1855        void
1856    >::type
1857    operator|=(const _Expr& __v) const;
1858
1859    template <class _Expr>
1860    typename enable_if
1861    <
1862        __is_val_expr<_Expr>::value,
1863        void
1864    >::type
1865    operator<<=(const _Expr& __v) const;
1866
1867    template <class _Expr>
1868    typename enable_if
1869    <
1870        __is_val_expr<_Expr>::value,
1871        void
1872    >::type
1873    operator>>=(const _Expr& __v) const;
1874
1875    const mask_array& operator=(const mask_array& __ma) const;
1876
1877    void operator=(const value_type& __x) const;
1878
1879//  mask_array(const mask_array&)            = default;
1880//  mask_array(mask_array&&)                 = default;
1881//  mask_array& operator=(const mask_array&) = default;
1882//  mask_array& operator=(mask_array&&)      = default;
1883
1884private:
1885    _LIBCPP_ALWAYS_INLINE
1886    mask_array(const valarray<bool>& __vb, const valarray<value_type>& __v)
1887        : __vp_(const_cast<value_type*>(__v.__begin_)),
1888          __1d_(count(__vb.__begin_, __vb.__end_, true))
1889          {
1890              size_t __j = 0;
1891              for (size_t __i = 0; __i < __vb.size(); ++__i)
1892                  if (__vb[__i])
1893                      __1d_[__j++] = __i;
1894          }
1895
1896    template <class> friend class valarray;
1897};
1898
1899template <class _Tp>
1900template <class _Expr>
1901inline _LIBCPP_ALWAYS_INLINE
1902typename enable_if
1903<
1904    __is_val_expr<_Expr>::value,
1905    void
1906>::type
1907mask_array<_Tp>::operator=(const _Expr& __v) const
1908{
1909    size_t __n = __1d_.size();
1910    for (size_t __i = 0; __i < __n; ++__i)
1911        __vp_[__1d_[__i]] = __v[__i];
1912}
1913
1914template <class _Tp>
1915template <class _Expr>
1916inline _LIBCPP_ALWAYS_INLINE
1917typename enable_if
1918<
1919    __is_val_expr<_Expr>::value,
1920    void
1921>::type
1922mask_array<_Tp>::operator*=(const _Expr& __v) const
1923{
1924    size_t __n = __1d_.size();
1925    for (size_t __i = 0; __i < __n; ++__i)
1926        __vp_[__1d_[__i]] *= __v[__i];
1927}
1928
1929template <class _Tp>
1930template <class _Expr>
1931inline _LIBCPP_ALWAYS_INLINE
1932typename enable_if
1933<
1934    __is_val_expr<_Expr>::value,
1935    void
1936>::type
1937mask_array<_Tp>::operator/=(const _Expr& __v) const
1938{
1939    size_t __n = __1d_.size();
1940    for (size_t __i = 0; __i < __n; ++__i)
1941        __vp_[__1d_[__i]] /= __v[__i];
1942}
1943
1944template <class _Tp>
1945template <class _Expr>
1946inline _LIBCPP_ALWAYS_INLINE
1947typename enable_if
1948<
1949    __is_val_expr<_Expr>::value,
1950    void
1951>::type
1952mask_array<_Tp>::operator%=(const _Expr& __v) const
1953{
1954    size_t __n = __1d_.size();
1955    for (size_t __i = 0; __i < __n; ++__i)
1956        __vp_[__1d_[__i]] %= __v[__i];
1957}
1958
1959template <class _Tp>
1960template <class _Expr>
1961inline _LIBCPP_ALWAYS_INLINE
1962typename enable_if
1963<
1964    __is_val_expr<_Expr>::value,
1965    void
1966>::type
1967mask_array<_Tp>::operator+=(const _Expr& __v) const
1968{
1969    size_t __n = __1d_.size();
1970    for (size_t __i = 0; __i < __n; ++__i)
1971        __vp_[__1d_[__i]] += __v[__i];
1972}
1973
1974template <class _Tp>
1975template <class _Expr>
1976inline _LIBCPP_ALWAYS_INLINE
1977typename enable_if
1978<
1979    __is_val_expr<_Expr>::value,
1980    void
1981>::type
1982mask_array<_Tp>::operator-=(const _Expr& __v) const
1983{
1984    size_t __n = __1d_.size();
1985    for (size_t __i = 0; __i < __n; ++__i)
1986        __vp_[__1d_[__i]] -= __v[__i];
1987}
1988
1989template <class _Tp>
1990template <class _Expr>
1991inline _LIBCPP_ALWAYS_INLINE
1992typename enable_if
1993<
1994    __is_val_expr<_Expr>::value,
1995    void
1996>::type
1997mask_array<_Tp>::operator^=(const _Expr& __v) const
1998{
1999    size_t __n = __1d_.size();
2000    for (size_t __i = 0; __i < __n; ++__i)
2001        __vp_[__1d_[__i]] ^= __v[__i];
2002}
2003
2004template <class _Tp>
2005template <class _Expr>
2006inline _LIBCPP_ALWAYS_INLINE
2007typename enable_if
2008<
2009    __is_val_expr<_Expr>::value,
2010    void
2011>::type
2012mask_array<_Tp>::operator&=(const _Expr& __v) const
2013{
2014    size_t __n = __1d_.size();
2015    for (size_t __i = 0; __i < __n; ++__i)
2016        __vp_[__1d_[__i]] &= __v[__i];
2017}
2018
2019template <class _Tp>
2020template <class _Expr>
2021inline _LIBCPP_ALWAYS_INLINE
2022typename enable_if
2023<
2024    __is_val_expr<_Expr>::value,
2025    void
2026>::type
2027mask_array<_Tp>::operator|=(const _Expr& __v) const
2028{
2029    size_t __n = __1d_.size();
2030    for (size_t __i = 0; __i < __n; ++__i)
2031        __vp_[__1d_[__i]] |= __v[__i];
2032}
2033
2034template <class _Tp>
2035template <class _Expr>
2036inline _LIBCPP_ALWAYS_INLINE
2037typename enable_if
2038<
2039    __is_val_expr<_Expr>::value,
2040    void
2041>::type
2042mask_array<_Tp>::operator<<=(const _Expr& __v) const
2043{
2044    size_t __n = __1d_.size();
2045    for (size_t __i = 0; __i < __n; ++__i)
2046        __vp_[__1d_[__i]] <<= __v[__i];
2047}
2048
2049template <class _Tp>
2050template <class _Expr>
2051inline _LIBCPP_ALWAYS_INLINE
2052typename enable_if
2053<
2054    __is_val_expr<_Expr>::value,
2055    void
2056>::type
2057mask_array<_Tp>::operator>>=(const _Expr& __v) const
2058{
2059    size_t __n = __1d_.size();
2060    for (size_t __i = 0; __i < __n; ++__i)
2061        __vp_[__1d_[__i]] >>= __v[__i];
2062}
2063
2064template <class _Tp>
2065inline _LIBCPP_ALWAYS_INLINE
2066const mask_array<_Tp>&
2067mask_array<_Tp>::operator=(const mask_array& __ma) const
2068{
2069    size_t __n = __1d_.size();
2070    for (size_t __i = 0; __i < __n; ++__i)
2071        __vp_[__1d_[__i]] = __ma.__vp_[__1d_[__i]];
2072}
2073
2074template <class _Tp>
2075inline _LIBCPP_ALWAYS_INLINE
2076void
2077mask_array<_Tp>::operator=(const value_type& __x) const
2078{
2079    size_t __n = __1d_.size();
2080    for (size_t __i = 0; __i < __n; ++__i)
2081        __vp_[__1d_[__i]] = __x;
2082}
2083
2084template <class _ValExpr>
2085class __mask_expr
2086{
2087    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
2088public:
2089    typedef typename _RmExpr::value_type value_type;
2090    typedef value_type result_type;
2091
2092private:
2093    _ValExpr __expr_;
2094    valarray<size_t> __1d_;
2095
2096    _LIBCPP_ALWAYS_INLINE
2097    __mask_expr(const valarray<bool>& __vb, const _RmExpr& __e)
2098        : __expr_(__e),
2099          __1d_(count(__vb.__begin_, __vb.__end_, true))
2100          {
2101              size_t __j = 0;
2102              for (size_t __i = 0; __i < __vb.size(); ++__i)
2103                  if (__vb[__i])
2104                      __1d_[__j++] = __i;
2105          }
2106
2107public:
2108    _LIBCPP_ALWAYS_INLINE
2109    result_type operator[](size_t __i) const
2110        {return __expr_[__1d_[__i]];}
2111
2112    _LIBCPP_ALWAYS_INLINE
2113    size_t size() const {return __1d_.size();}
2114
2115    template <class> friend class valarray;
2116};
2117
2118// indirect_array
2119
2120template <class _Tp>
2121class indirect_array
2122{
2123public:
2124    typedef _Tp value_type;
2125
2126private:
2127    value_type*      __vp_;
2128    valarray<size_t> __1d_;
2129
2130public:
2131    template <class _Expr>
2132    typename enable_if
2133    <
2134        __is_val_expr<_Expr>::value,
2135        void
2136    >::type
2137    operator=(const _Expr& __v) const;
2138
2139    template <class _Expr>
2140    typename enable_if
2141    <
2142        __is_val_expr<_Expr>::value,
2143        void
2144    >::type
2145    operator*=(const _Expr& __v) const;
2146
2147    template <class _Expr>
2148    typename enable_if
2149    <
2150        __is_val_expr<_Expr>::value,
2151        void
2152    >::type
2153    operator/=(const _Expr& __v) const;
2154
2155    template <class _Expr>
2156    typename enable_if
2157    <
2158        __is_val_expr<_Expr>::value,
2159        void
2160    >::type
2161    operator%=(const _Expr& __v) const;
2162
2163    template <class _Expr>
2164    typename enable_if
2165    <
2166        __is_val_expr<_Expr>::value,
2167        void
2168    >::type
2169    operator+=(const _Expr& __v) const;
2170
2171    template <class _Expr>
2172    typename enable_if
2173    <
2174        __is_val_expr<_Expr>::value,
2175        void
2176    >::type
2177    operator-=(const _Expr& __v) const;
2178
2179    template <class _Expr>
2180    typename enable_if
2181    <
2182        __is_val_expr<_Expr>::value,
2183        void
2184    >::type
2185    operator^=(const _Expr& __v) const;
2186
2187    template <class _Expr>
2188    typename enable_if
2189    <
2190        __is_val_expr<_Expr>::value,
2191        void
2192    >::type
2193    operator&=(const _Expr& __v) const;
2194
2195    template <class _Expr>
2196    typename enable_if
2197    <
2198        __is_val_expr<_Expr>::value,
2199        void
2200    >::type
2201    operator|=(const _Expr& __v) const;
2202
2203    template <class _Expr>
2204    typename enable_if
2205    <
2206        __is_val_expr<_Expr>::value,
2207        void
2208    >::type
2209    operator<<=(const _Expr& __v) const;
2210
2211    template <class _Expr>
2212    typename enable_if
2213    <
2214        __is_val_expr<_Expr>::value,
2215        void
2216    >::type
2217    operator>>=(const _Expr& __v) const;
2218
2219    const indirect_array& operator=(const indirect_array& __ia) const;
2220
2221    void operator=(const value_type& __x) const;
2222
2223//  indirect_array(const indirect_array&)            = default;
2224//  indirect_array(indirect_array&&)                 = default;
2225//  indirect_array& operator=(const indirect_array&) = default;
2226//  indirect_array& operator=(indirect_array&&)      = default;
2227
2228private:
2229     _LIBCPP_ALWAYS_INLINE
2230   indirect_array(const valarray<size_t>& __ia, const valarray<value_type>& __v)
2231        : __vp_(const_cast<value_type*>(__v.__begin_)),
2232          __1d_(__ia)
2233        {}
2234
2235#ifdef _LIBCPP_MOVE
2236
2237    _LIBCPP_ALWAYS_INLINE
2238    indirect_array(valarray<size_t>&& __ia, const valarray<value_type>& __v)
2239        : __vp_(const_cast<value_type*>(__v.__begin_)),
2240          __1d_(move(__ia))
2241        {}
2242
2243#endif
2244
2245    template <class> friend class valarray;
2246};
2247
2248template <class _Tp>
2249template <class _Expr>
2250inline _LIBCPP_ALWAYS_INLINE
2251typename enable_if
2252<
2253    __is_val_expr<_Expr>::value,
2254    void
2255>::type
2256indirect_array<_Tp>::operator=(const _Expr& __v) const
2257{
2258    size_t __n = __1d_.size();
2259    for (size_t __i = 0; __i < __n; ++__i)
2260        __vp_[__1d_[__i]] = __v[__i];
2261}
2262
2263template <class _Tp>
2264template <class _Expr>
2265inline _LIBCPP_ALWAYS_INLINE
2266typename enable_if
2267<
2268    __is_val_expr<_Expr>::value,
2269    void
2270>::type
2271indirect_array<_Tp>::operator*=(const _Expr& __v) const
2272{
2273    size_t __n = __1d_.size();
2274    for (size_t __i = 0; __i < __n; ++__i)
2275        __vp_[__1d_[__i]] *= __v[__i];
2276}
2277
2278template <class _Tp>
2279template <class _Expr>
2280inline _LIBCPP_ALWAYS_INLINE
2281typename enable_if
2282<
2283    __is_val_expr<_Expr>::value,
2284    void
2285>::type
2286indirect_array<_Tp>::operator/=(const _Expr& __v) const
2287{
2288    size_t __n = __1d_.size();
2289    for (size_t __i = 0; __i < __n; ++__i)
2290        __vp_[__1d_[__i]] /= __v[__i];
2291}
2292
2293template <class _Tp>
2294template <class _Expr>
2295inline _LIBCPP_ALWAYS_INLINE
2296typename enable_if
2297<
2298    __is_val_expr<_Expr>::value,
2299    void
2300>::type
2301indirect_array<_Tp>::operator%=(const _Expr& __v) const
2302{
2303    size_t __n = __1d_.size();
2304    for (size_t __i = 0; __i < __n; ++__i)
2305        __vp_[__1d_[__i]] %= __v[__i];
2306}
2307
2308template <class _Tp>
2309template <class _Expr>
2310inline _LIBCPP_ALWAYS_INLINE
2311typename enable_if
2312<
2313    __is_val_expr<_Expr>::value,
2314    void
2315>::type
2316indirect_array<_Tp>::operator+=(const _Expr& __v) const
2317{
2318    size_t __n = __1d_.size();
2319    for (size_t __i = 0; __i < __n; ++__i)
2320        __vp_[__1d_[__i]] += __v[__i];
2321}
2322
2323template <class _Tp>
2324template <class _Expr>
2325inline _LIBCPP_ALWAYS_INLINE
2326typename enable_if
2327<
2328    __is_val_expr<_Expr>::value,
2329    void
2330>::type
2331indirect_array<_Tp>::operator-=(const _Expr& __v) const
2332{
2333    size_t __n = __1d_.size();
2334    for (size_t __i = 0; __i < __n; ++__i)
2335        __vp_[__1d_[__i]] -= __v[__i];
2336}
2337
2338template <class _Tp>
2339template <class _Expr>
2340inline _LIBCPP_ALWAYS_INLINE
2341typename enable_if
2342<
2343    __is_val_expr<_Expr>::value,
2344    void
2345>::type
2346indirect_array<_Tp>::operator^=(const _Expr& __v) const
2347{
2348    size_t __n = __1d_.size();
2349    for (size_t __i = 0; __i < __n; ++__i)
2350        __vp_[__1d_[__i]] ^= __v[__i];
2351}
2352
2353template <class _Tp>
2354template <class _Expr>
2355inline _LIBCPP_ALWAYS_INLINE
2356typename enable_if
2357<
2358    __is_val_expr<_Expr>::value,
2359    void
2360>::type
2361indirect_array<_Tp>::operator&=(const _Expr& __v) const
2362{
2363    size_t __n = __1d_.size();
2364    for (size_t __i = 0; __i < __n; ++__i)
2365        __vp_[__1d_[__i]] &= __v[__i];
2366}
2367
2368template <class _Tp>
2369template <class _Expr>
2370inline _LIBCPP_ALWAYS_INLINE
2371typename enable_if
2372<
2373    __is_val_expr<_Expr>::value,
2374    void
2375>::type
2376indirect_array<_Tp>::operator|=(const _Expr& __v) const
2377{
2378    size_t __n = __1d_.size();
2379    for (size_t __i = 0; __i < __n; ++__i)
2380        __vp_[__1d_[__i]] |= __v[__i];
2381}
2382
2383template <class _Tp>
2384template <class _Expr>
2385inline _LIBCPP_ALWAYS_INLINE
2386typename enable_if
2387<
2388    __is_val_expr<_Expr>::value,
2389    void
2390>::type
2391indirect_array<_Tp>::operator<<=(const _Expr& __v) const
2392{
2393    size_t __n = __1d_.size();
2394    for (size_t __i = 0; __i < __n; ++__i)
2395        __vp_[__1d_[__i]] <<= __v[__i];
2396}
2397
2398template <class _Tp>
2399template <class _Expr>
2400inline _LIBCPP_ALWAYS_INLINE
2401typename enable_if
2402<
2403    __is_val_expr<_Expr>::value,
2404    void
2405>::type
2406indirect_array<_Tp>::operator>>=(const _Expr& __v) const
2407{
2408    size_t __n = __1d_.size();
2409    for (size_t __i = 0; __i < __n; ++__i)
2410        __vp_[__1d_[__i]] >>= __v[__i];
2411}
2412
2413template <class _Tp>
2414inline _LIBCPP_ALWAYS_INLINE
2415const indirect_array<_Tp>&
2416indirect_array<_Tp>::operator=(const indirect_array& __ia) const
2417{
2418    typedef const size_t* _Ip;
2419    const value_type* __s = __ia.__vp_;
2420    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ia.__1d_.__begin_;
2421            __i != __e; ++__i, ++__j)
2422        __vp_[*__i] = __s[*__j];
2423    return *this;
2424}
2425
2426template <class _Tp>
2427inline _LIBCPP_ALWAYS_INLINE
2428void
2429indirect_array<_Tp>::operator=(const value_type& __x) const
2430{
2431    typedef const size_t* _Ip;
2432    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i)
2433        __vp_[*__i] = __x;
2434}
2435
2436template <class _ValExpr>
2437class __indirect_expr
2438{
2439    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
2440public:
2441    typedef typename _RmExpr::value_type value_type;
2442    typedef value_type result_type;
2443
2444private:
2445    _ValExpr __expr_;
2446    valarray<size_t> __1d_;
2447
2448    __indirect_expr(const valarray<size_t>& __ia, const _RmExpr& __e)
2449        : __expr_(__e),
2450          __1d_(__ia)
2451          {}
2452
2453#ifdef _LIBCPP_MOVE
2454
2455    __indirect_expr(valarray<size_t>&& __ia, const _RmExpr& __e)
2456        : __expr_(__e),
2457          __1d_(move(__ia))
2458          {}
2459
2460#endif
2461
2462public:
2463    _LIBCPP_ALWAYS_INLINE
2464    result_type operator[](size_t __i) const
2465        {return __expr_[__1d_[__i]];}
2466
2467    _LIBCPP_ALWAYS_INLINE
2468    size_t size() const {return __1d_.size();}
2469
2470    template <class> friend class valarray;
2471};
2472
2473template<class _ValExpr>
2474class __val_expr
2475{
2476    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
2477
2478    _ValExpr __expr_;
2479public:
2480    typedef typename _RmExpr::value_type value_type;
2481    typedef typename _RmExpr::result_type result_type;
2482
2483    _LIBCPP_ALWAYS_INLINE
2484    explicit __val_expr(const _RmExpr& __e) : __expr_(__e) {}
2485
2486    _LIBCPP_ALWAYS_INLINE
2487    result_type operator[](size_t __i) const
2488        {return __expr_[__i];}
2489
2490    _LIBCPP_ALWAYS_INLINE
2491    __val_expr<__slice_expr<_ValExpr> > operator[](slice __s) const
2492        {return __val_expr<__slice_expr<_ValExpr> >(__expr_, __s);}
2493
2494    _LIBCPP_ALWAYS_INLINE
2495    __val_expr<__indirect_expr<_ValExpr> > operator[](const gslice& __gs) const
2496        {return __val_expr<__indirect_expr<_ValExpr> >(__expr_, __gs.__1d_);}
2497
2498    _LIBCPP_ALWAYS_INLINE
2499    __val_expr<__mask_expr<_ValExpr> > operator[](const valarray<bool>& __vb) const
2500        {return __val_expr<__mask_expr<_ValExpr> >(__expr_, __vb);}
2501
2502    _LIBCPP_ALWAYS_INLINE
2503    __val_expr<__indirect_expr<_ValExpr> > operator[](const valarray<size_t>& __vs) const
2504        {return __val_expr<__indirect_expr<_ValExpr> >(__expr_, __vs);}
2505
2506    _LIBCPP_ALWAYS_INLINE
2507    __val_expr<_UnaryOp<__unary_plus<value_type>, _ValExpr> >
2508    operator+() const
2509    {
2510        typedef _UnaryOp<__unary_plus<value_type>, _ValExpr> _NewExpr;
2511        return __val_expr<_NewExpr>(_NewExpr(__unary_plus<value_type>(), __expr_));
2512    }
2513
2514    _LIBCPP_ALWAYS_INLINE
2515    __val_expr<_UnaryOp<negate<value_type>, _ValExpr> >
2516    operator-() const
2517    {
2518        typedef _UnaryOp<negate<value_type>, _ValExpr> _NewExpr;
2519        return __val_expr<_NewExpr>(_NewExpr(negate<value_type>(), __expr_));
2520    }
2521
2522    _LIBCPP_ALWAYS_INLINE
2523    __val_expr<_UnaryOp<__bit_not<value_type>, _ValExpr> >
2524    operator~() const
2525    {
2526        typedef _UnaryOp<__bit_not<value_type>, _ValExpr> _NewExpr;
2527        return __val_expr<_NewExpr>(_NewExpr(__bit_not<value_type>(), __expr_));
2528    }
2529
2530    _LIBCPP_ALWAYS_INLINE
2531    __val_expr<_UnaryOp<logical_not<value_type>, _ValExpr> >
2532    operator!() const
2533    {
2534        typedef _UnaryOp<logical_not<value_type>, _ValExpr> _NewExpr;
2535        return __val_expr<_NewExpr>(_NewExpr(logical_not<value_type>(), __expr_));
2536    }
2537
2538    operator valarray<result_type>() const;
2539
2540    _LIBCPP_ALWAYS_INLINE
2541    size_t size() const {return __expr_.size();}
2542
2543    _LIBCPP_ALWAYS_INLINE
2544    result_type sum() const
2545    {
2546        size_t __n = __expr_.size();
2547        result_type __r = __n ? __expr_[0] : result_type();
2548        for (size_t __i = 1; __i < __n; ++__i)
2549            __r += __expr_[__i];
2550        return __r;
2551    }
2552
2553    _LIBCPP_ALWAYS_INLINE
2554    result_type min() const
2555    {
2556        size_t __n = size();
2557        result_type __r = __n ? (*this)[0] : result_type();
2558        for (size_t __i = 1; __i < __n; ++__i)
2559        {
2560            result_type __x = __expr_[__i];
2561            if (__x < __r)
2562                __r = __x;
2563        }
2564        return __r;
2565    }
2566
2567    _LIBCPP_ALWAYS_INLINE
2568    result_type max() const
2569    {
2570        size_t __n = size();
2571        result_type __r = __n ? (*this)[0] : result_type();
2572        for (size_t __i = 1; __i < __n; ++__i)
2573        {
2574            result_type __x = __expr_[__i];
2575            if (__r < __x)
2576                __r = __x;
2577        }
2578        return __r;
2579    }
2580
2581    _LIBCPP_ALWAYS_INLINE
2582    __val_expr<__shift_expr<_ValExpr> > shift (int __i) const
2583        {return __val_expr<__shift_expr<_ValExpr> >(__shift_expr<_ValExpr>(__i, __expr_));}
2584
2585    _LIBCPP_ALWAYS_INLINE
2586    __val_expr<__cshift_expr<_ValExpr> > cshift(int __i) const
2587        {return __val_expr<__cshift_expr<_ValExpr> >(__cshift_expr<_ValExpr>(__i, __expr_));}
2588
2589    _LIBCPP_ALWAYS_INLINE
2590    __val_expr<_UnaryOp<__apply_expr<value_type, value_type(*)(value_type)>, _ValExpr> >
2591    apply(value_type __f(value_type)) const
2592    {
2593        typedef __apply_expr<value_type, value_type(*)(value_type)> _Op;
2594        typedef _UnaryOp<_Op, _ValExpr> _NewExpr;
2595        return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_));
2596    }
2597
2598    _LIBCPP_ALWAYS_INLINE
2599    __val_expr<_UnaryOp<__apply_expr<value_type, value_type(*)(const value_type&)>, _ValExpr> >
2600    apply(value_type __f(const value_type&)) const
2601    {
2602        typedef __apply_expr<value_type, value_type(*)(const value_type&)> _Op;
2603        typedef _UnaryOp<_Op, _ValExpr> _NewExpr;
2604        return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_));
2605    }
2606};
2607
2608template<class _ValExpr>
2609__val_expr<_ValExpr>::operator valarray<result_type>() const
2610{
2611    valarray<result_type> __r;
2612    size_t __n = __expr_.size();
2613    if (__n)
2614    {
2615        __r.__begin_ =
2616            __r.__end_ =
2617                static_cast<result_type*>(::operator new(__n * sizeof(result_type)));
2618        for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)
2619            ::new (__r.__end_) result_type(__expr_[__i]);
2620    }
2621    return __r;
2622}
2623
2624// valarray
2625
2626template <class _Tp>
2627inline _LIBCPP_ALWAYS_INLINE
2628valarray<_Tp>::valarray(size_t __n)
2629    : __begin_(0),
2630      __end_(0)
2631{
2632    resize(__n);
2633}
2634
2635template <class _Tp>
2636inline _LIBCPP_ALWAYS_INLINE
2637valarray<_Tp>::valarray(const value_type& __x, size_t __n)
2638    : __begin_(0),
2639      __end_(0)
2640{
2641    resize(__n, __x);
2642}
2643
2644template <class _Tp>
2645valarray<_Tp>::valarray(const value_type* __p, size_t __n)
2646    : __begin_(0),
2647      __end_(0)
2648{
2649    if (__n)
2650    {
2651        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
2652#ifndef _LIBCPP_NO_EXCEPTIONS
2653        try
2654        {
2655#endif
2656            for (; __n; ++__end_, ++__p, --__n)
2657                ::new (__end_) value_type(*__p);
2658#ifndef _LIBCPP_NO_EXCEPTIONS
2659        }
2660        catch (...)
2661        {
2662            resize(0);
2663            throw;
2664        }
2665#endif
2666    }
2667}
2668
2669template <class _Tp>
2670valarray<_Tp>::valarray(const valarray& __v)
2671    : __begin_(0),
2672      __end_(0)
2673{
2674    if (__v.size())
2675    {
2676        __begin_ = __end_ = static_cast<value_type*>(::operator new(__v.size() * sizeof(value_type)));
2677#ifndef _LIBCPP_NO_EXCEPTIONS
2678        try
2679        {
2680#endif
2681            for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
2682                ::new (__end_) value_type(*__p);
2683#ifndef _LIBCPP_NO_EXCEPTIONS
2684        }
2685        catch (...)
2686        {
2687            resize(0);
2688            throw;
2689        }
2690#endif
2691    }
2692}
2693
2694#ifdef _LIBCPP_MOVE
2695
2696template <class _Tp>
2697inline _LIBCPP_ALWAYS_INLINE
2698valarray<_Tp>::valarray(valarray&& __v)
2699    : __begin_(__v.__begin_),
2700      __end_(__v.__end_)
2701{
2702    __v.__begin_ = __v.__end_ = nullptr;
2703}
2704
2705template <class _Tp>
2706valarray<_Tp>::valarray(initializer_list<value_type> __il)
2707    : __begin_(0),
2708      __end_(0)
2709{
2710    size_t __n = __il.size();
2711    if (__n)
2712    {
2713        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
2714#ifndef _LIBCPP_NO_EXCEPTIONS
2715        try
2716        {
2717#endif
2718            for (const value_type* __p = __il.begin(); __n; ++__end_, ++__p, --__n)
2719                ::new (__end_) value_type(*__p);
2720#ifndef _LIBCPP_NO_EXCEPTIONS
2721        }
2722        catch (...)
2723        {
2724            resize(0);
2725            throw;
2726        }
2727#endif
2728    }
2729}
2730
2731#endif
2732
2733template <class _Tp>
2734valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
2735    : __begin_(0),
2736      __end_(0)
2737{
2738    size_t __n = __sa.__size_;
2739    if (__n)
2740    {
2741        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
2742#ifndef _LIBCPP_NO_EXCEPTIONS
2743        try
2744        {
2745#endif
2746            for (const value_type* __p = __sa.__vp_; __n; ++__end_, __p += __sa.__stride_, --__n)
2747                ::new (__end_) value_type(*__p);
2748#ifndef _LIBCPP_NO_EXCEPTIONS
2749        }
2750        catch (...)
2751        {
2752            resize(0);
2753            throw;
2754        }
2755#endif
2756    }
2757}
2758
2759template <class _Tp>
2760valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
2761    : __begin_(0),
2762      __end_(0)
2763{
2764    size_t __n = __ga.__1d_.size();
2765    if (__n)
2766    {
2767        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
2768#ifndef _LIBCPP_NO_EXCEPTIONS
2769        try
2770        {
2771#endif
2772            typedef const size_t* _Ip;
2773            const value_type* __s = __ga.__vp_;
2774            for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
2775                    __i != __e; ++__i, ++__end_)
2776                ::new (__end_) value_type(__s[*__i]);
2777#ifndef _LIBCPP_NO_EXCEPTIONS
2778        }
2779        catch (...)
2780        {
2781            resize(0);
2782            throw;
2783        }
2784#endif
2785    }
2786}
2787
2788template <class _Tp>
2789valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
2790    : __begin_(0),
2791      __end_(0)
2792{
2793    size_t __n = __ma.__1d_.size();
2794    if (__n)
2795    {
2796        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
2797#ifndef _LIBCPP_NO_EXCEPTIONS
2798        try
2799        {
2800#endif
2801            typedef const size_t* _Ip;
2802            const value_type* __s = __ma.__vp_;
2803            for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
2804                    __i != __e; ++__i, ++__end_)
2805                ::new (__end_) value_type(__s[*__i]);
2806#ifndef _LIBCPP_NO_EXCEPTIONS
2807        }
2808        catch (...)
2809        {
2810            resize(0);
2811            throw;
2812        }
2813#endif
2814    }
2815}
2816
2817template <class _Tp>
2818valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
2819    : __begin_(0),
2820      __end_(0)
2821{
2822    size_t __n = __ia.__1d_.size();
2823    if (__n)
2824    {
2825        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
2826#ifndef _LIBCPP_NO_EXCEPTIONS
2827        try
2828        {
2829#endif
2830            typedef const size_t* _Ip;
2831            const value_type* __s = __ia.__vp_;
2832            for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
2833                    __i != __e; ++__i, ++__end_)
2834                ::new (__end_) value_type(__s[*__i]);
2835#ifndef _LIBCPP_NO_EXCEPTIONS
2836        }
2837        catch (...)
2838        {
2839            resize(0);
2840            throw;
2841        }
2842#endif
2843    }
2844}
2845
2846template <class _Tp>
2847inline _LIBCPP_ALWAYS_INLINE
2848valarray<_Tp>::~valarray()
2849{
2850    resize(0);
2851}
2852
2853template <class _Tp>
2854valarray<_Tp>&
2855valarray<_Tp>::operator=(const valarray& __v)
2856{
2857    if (this != &__v)
2858    {
2859        if (size() != __v.size())
2860            resize(__v.size());
2861        _STD::copy(__v.__begin_, __v.__end_, __begin_);
2862    }
2863    return *this;
2864}
2865
2866#ifdef _LIBCPP_MOVE
2867
2868template <class _Tp>
2869inline _LIBCPP_ALWAYS_INLINE
2870valarray<_Tp>&
2871valarray<_Tp>::operator=(valarray&& __v)
2872{
2873    resize(0);
2874    __begin_ = __v.__begin_;
2875    __end_ = __v.__end_;
2876    __v.__begin_ = nullptr;
2877    __v.__end_ = nullptr;
2878    return *this;
2879}
2880
2881template <class _Tp>
2882inline _LIBCPP_ALWAYS_INLINE
2883valarray<_Tp>&
2884valarray<_Tp>::operator=(initializer_list<value_type> __il)
2885{
2886    if (size() != __il.size())
2887        resize(__il.size());
2888    _STD::copy(__il.begin(), __il.end(), __begin_);
2889    return *this;
2890}
2891
2892#endif
2893
2894template <class _Tp>
2895inline _LIBCPP_ALWAYS_INLINE
2896valarray<_Tp>&
2897valarray<_Tp>::operator=(const value_type& __x)
2898{
2899    _STD::fill(__begin_, __end_, __x);
2900    return *this;
2901}
2902
2903template <class _Tp>
2904inline _LIBCPP_ALWAYS_INLINE
2905valarray<_Tp>&
2906valarray<_Tp>::operator=(const slice_array<value_type>& __sa)
2907{
2908    value_type* __t = __begin_;
2909    const value_type* __s = __sa.__vp_;
2910    for (size_t __n = __sa.__size_; __n; --__n, __s += __sa.__stride_, ++__t)
2911        *__t = *__s;
2912    return *this;
2913}
2914
2915template <class _Tp>
2916inline _LIBCPP_ALWAYS_INLINE
2917valarray<_Tp>&
2918valarray<_Tp>::operator=(const gslice_array<value_type>& __ga)
2919{
2920    typedef const size_t* _Ip;
2921    value_type* __t = __begin_;
2922    const value_type* __s = __ga.__vp_;
2923    for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
2924                    __i != __e; ++__i, ++__t)
2925        *__t = __s[*__i];
2926    return *this;
2927}
2928
2929template <class _Tp>
2930inline _LIBCPP_ALWAYS_INLINE
2931valarray<_Tp>&
2932valarray<_Tp>::operator=(const mask_array<value_type>& __ma)
2933{
2934    typedef const size_t* _Ip;
2935    value_type* __t = __begin_;
2936    const value_type* __s = __ma.__vp_;
2937    for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
2938                    __i != __e; ++__i, ++__t)
2939        *__t = __s[*__i];
2940    return *this;
2941}
2942
2943template <class _Tp>
2944inline _LIBCPP_ALWAYS_INLINE
2945valarray<_Tp>&
2946valarray<_Tp>::operator=(const indirect_array<value_type>& __ia)
2947{
2948    typedef const size_t* _Ip;
2949    value_type* __t = __begin_;
2950    const value_type* __s = __ia.__vp_;
2951    for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
2952                    __i != __e; ++__i, ++__t)
2953        *__t = __s[*__i];
2954    return *this;
2955}
2956
2957template <class _Tp>
2958inline _LIBCPP_ALWAYS_INLINE
2959__val_expr<__slice_expr<const valarray<_Tp>&> >
2960valarray<_Tp>::operator[](slice __s) const
2961{
2962    return __val_expr<__slice_expr<const valarray&> >(__slice_expr<const valarray&>(__s, *this));
2963}
2964
2965template <class _Tp>
2966inline _LIBCPP_ALWAYS_INLINE
2967slice_array<_Tp>
2968valarray<_Tp>::operator[](slice __s)
2969{
2970    return slice_array<value_type>(__s, *this);
2971}
2972
2973template <class _Tp>
2974inline _LIBCPP_ALWAYS_INLINE
2975__val_expr<__indirect_expr<const valarray<_Tp>&> >
2976valarray<_Tp>::operator[](const gslice& __gs) const
2977{
2978    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(__gs.__1d_, *this));
2979}
2980
2981template <class _Tp>
2982inline _LIBCPP_ALWAYS_INLINE
2983gslice_array<_Tp>
2984valarray<_Tp>::operator[](const gslice& __gs)
2985{
2986    return gslice_array<value_type>(__gs, *this);
2987}
2988
2989#ifdef _LIBCPP_MOVE
2990
2991template <class _Tp>
2992inline _LIBCPP_ALWAYS_INLINE
2993__val_expr<__indirect_expr<const valarray<_Tp>&> >
2994valarray<_Tp>::operator[](gslice&& __gs) const
2995{
2996    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__gs.__1d_), *this));
2997}
2998
2999template <class _Tp>
3000inline _LIBCPP_ALWAYS_INLINE
3001gslice_array<_Tp>
3002valarray<_Tp>::operator[](gslice&& __gs)
3003{
3004    return gslice_array<value_type>(move(__gs), *this);
3005}
3006
3007#endif
3008
3009template <class _Tp>
3010inline _LIBCPP_ALWAYS_INLINE
3011__val_expr<__mask_expr<const valarray<_Tp>&> >
3012valarray<_Tp>::operator[](const valarray<bool>& __vb) const
3013{
3014    return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(__vb, *this));
3015}
3016
3017template <class _Tp>
3018inline _LIBCPP_ALWAYS_INLINE
3019mask_array<_Tp>
3020valarray<_Tp>::operator[](const valarray<bool>& __vb)
3021{
3022    return mask_array<value_type>(__vb, *this);
3023}
3024
3025#ifdef _LIBCPP_MOVE
3026
3027template <class _Tp>
3028inline _LIBCPP_ALWAYS_INLINE
3029__val_expr<__mask_expr<const valarray<_Tp>&> >
3030valarray<_Tp>::operator[](valarray<bool>&& __vb) const
3031{
3032    return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(move(__vb), *this));
3033}
3034
3035template <class _Tp>
3036inline _LIBCPP_ALWAYS_INLINE
3037mask_array<_Tp>
3038valarray<_Tp>::operator[](valarray<bool>&& __vb)
3039{
3040    return mask_array<value_type>(move(__vb), *this);
3041}
3042
3043#endif
3044
3045template <class _Tp>
3046inline _LIBCPP_ALWAYS_INLINE
3047__val_expr<__indirect_expr<const valarray<_Tp>&> >
3048valarray<_Tp>::operator[](const valarray<size_t>& __vs) const
3049{
3050    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(__vs, *this));
3051}
3052
3053template <class _Tp>
3054inline _LIBCPP_ALWAYS_INLINE
3055indirect_array<_Tp>
3056valarray<_Tp>::operator[](const valarray<size_t>& __vs)
3057{
3058    return indirect_array<value_type>(__vs, *this);
3059}
3060
3061#ifdef _LIBCPP_MOVE
3062
3063template <class _Tp>
3064inline _LIBCPP_ALWAYS_INLINE
3065__val_expr<__indirect_expr<const valarray<_Tp>&> >
3066valarray<_Tp>::operator[](valarray<size_t>&& __vs) const
3067{
3068    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__vs), *this));
3069}
3070
3071template <class _Tp>
3072inline _LIBCPP_ALWAYS_INLINE
3073indirect_array<_Tp>
3074valarray<_Tp>::operator[](valarray<size_t>&& __vs)
3075{
3076    return indirect_array<value_type>(move(__vs), *this);
3077}
3078
3079#endif
3080
3081template <class _Tp>
3082valarray<_Tp>
3083valarray<_Tp>::operator+() const
3084{
3085    valarray<value_type> __r;
3086    size_t __n = size();
3087    if (__n)
3088    {
3089        __r.__begin_ =
3090            __r.__end_ =
3091                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3092        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
3093            ::new (__r.__end_) value_type(+*__p);
3094    }
3095    return __r;
3096}
3097
3098template <class _Tp>
3099valarray<_Tp>
3100valarray<_Tp>::operator-() const
3101{
3102    valarray<value_type> __r;
3103    size_t __n = size();
3104    if (__n)
3105    {
3106        __r.__begin_ =
3107            __r.__end_ =
3108                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3109        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
3110            ::new (__r.__end_) value_type(-*__p);
3111    }
3112    return __r;
3113}
3114
3115template <class _Tp>
3116valarray<_Tp>
3117valarray<_Tp>::operator~() const
3118{
3119    valarray<value_type> __r;
3120    size_t __n = size();
3121    if (__n)
3122    {
3123        __r.__begin_ =
3124            __r.__end_ =
3125                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3126        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
3127            ::new (__r.__end_) value_type(~*__p);
3128    }
3129    return __r;
3130}
3131
3132template <class _Tp>
3133valarray<bool>
3134valarray<_Tp>::operator!() const
3135{
3136    valarray<bool> __r;
3137    size_t __n = size();
3138    if (__n)
3139    {
3140        __r.__begin_ =
3141            __r.__end_ =
3142                static_cast<bool*>(::operator new(__n * sizeof(bool)));
3143        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
3144            ::new (__r.__end_) bool(!*__p);
3145    }
3146    return __r;
3147}
3148
3149template <class _Tp>
3150inline _LIBCPP_ALWAYS_INLINE
3151valarray<_Tp>&
3152valarray<_Tp>::operator*=(const value_type& __x)
3153{
3154    for (value_type* __p = __begin_; __p != __end_; ++__p)
3155        *__p *= __x;
3156    return *this;
3157}
3158
3159template <class _Tp>
3160inline _LIBCPP_ALWAYS_INLINE
3161valarray<_Tp>&
3162valarray<_Tp>::operator/=(const value_type& __x)
3163{
3164    for (value_type* __p = __begin_; __p != __end_; ++__p)
3165        *__p /= __x;
3166    return *this;
3167}
3168
3169template <class _Tp>
3170inline _LIBCPP_ALWAYS_INLINE
3171valarray<_Tp>&
3172valarray<_Tp>::operator%=(const value_type& __x)
3173{
3174    for (value_type* __p = __begin_; __p != __end_; ++__p)
3175        *__p %= __x;
3176    return *this;
3177}
3178
3179template <class _Tp>
3180inline _LIBCPP_ALWAYS_INLINE
3181valarray<_Tp>&
3182valarray<_Tp>::operator+=(const value_type& __x)
3183{
3184    for (value_type* __p = __begin_; __p != __end_; ++__p)
3185        *__p += __x;
3186    return *this;
3187}
3188
3189template <class _Tp>
3190inline _LIBCPP_ALWAYS_INLINE
3191valarray<_Tp>&
3192valarray<_Tp>::operator-=(const value_type& __x)
3193{
3194    for (value_type* __p = __begin_; __p != __end_; ++__p)
3195        *__p -= __x;
3196    return *this;
3197}
3198
3199template <class _Tp>
3200inline _LIBCPP_ALWAYS_INLINE
3201valarray<_Tp>&
3202valarray<_Tp>::operator^=(const value_type& __x)
3203{
3204    for (value_type* __p = __begin_; __p != __end_; ++__p)
3205        *__p ^= __x;
3206    return *this;
3207}
3208
3209template <class _Tp>
3210inline _LIBCPP_ALWAYS_INLINE
3211valarray<_Tp>&
3212valarray<_Tp>::operator&=(const value_type& __x)
3213{
3214    for (value_type* __p = __begin_; __p != __end_; ++__p)
3215        *__p &= __x;
3216    return *this;
3217}
3218
3219template <class _Tp>
3220inline _LIBCPP_ALWAYS_INLINE
3221valarray<_Tp>&
3222valarray<_Tp>::operator|=(const value_type& __x)
3223{
3224    for (value_type* __p = __begin_; __p != __end_; ++__p)
3225        *__p |= __x;
3226    return *this;
3227}
3228
3229template <class _Tp>
3230inline _LIBCPP_ALWAYS_INLINE
3231valarray<_Tp>&
3232valarray<_Tp>::operator<<=(const value_type& __x)
3233{
3234    for (value_type* __p = __begin_; __p != __end_; ++__p)
3235        *__p <<= __x;
3236    return *this;
3237}
3238
3239template <class _Tp>
3240inline _LIBCPP_ALWAYS_INLINE
3241valarray<_Tp>&
3242valarray<_Tp>::operator>>=(const value_type& __x)
3243{
3244    for (value_type* __p = __begin_; __p != __end_; ++__p)
3245        *__p >>= __x;
3246    return *this;
3247}
3248
3249template <class _Tp>
3250template <class _Expr>
3251inline _LIBCPP_ALWAYS_INLINE
3252typename enable_if
3253<
3254    __is_val_expr<_Expr>::value,
3255    valarray<_Tp>&
3256>::type
3257valarray<_Tp>::operator*=(const _Expr& __v)
3258{
3259    size_t __i = 0;
3260    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3261        *__t *= __v[__i];
3262    return *this;
3263}
3264
3265template <class _Tp>
3266template <class _Expr>
3267inline _LIBCPP_ALWAYS_INLINE
3268typename enable_if
3269<
3270    __is_val_expr<_Expr>::value,
3271    valarray<_Tp>&
3272>::type
3273valarray<_Tp>::operator/=(const _Expr& __v)
3274{
3275    size_t __i = 0;
3276    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3277        *__t /= __v[__i];
3278    return *this;
3279}
3280
3281template <class _Tp>
3282template <class _Expr>
3283inline _LIBCPP_ALWAYS_INLINE
3284typename enable_if
3285<
3286    __is_val_expr<_Expr>::value,
3287    valarray<_Tp>&
3288>::type
3289valarray<_Tp>::operator%=(const _Expr& __v)
3290{
3291    size_t __i = 0;
3292    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3293        *__t %= __v[__i];
3294    return *this;
3295}
3296
3297template <class _Tp>
3298template <class _Expr>
3299inline _LIBCPP_ALWAYS_INLINE
3300typename enable_if
3301<
3302    __is_val_expr<_Expr>::value,
3303    valarray<_Tp>&
3304>::type
3305valarray<_Tp>::operator+=(const _Expr& __v)
3306{
3307    size_t __i = 0;
3308    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3309        *__t += __v[__i];
3310    return *this;
3311}
3312
3313template <class _Tp>
3314template <class _Expr>
3315inline _LIBCPP_ALWAYS_INLINE
3316typename enable_if
3317<
3318    __is_val_expr<_Expr>::value,
3319    valarray<_Tp>&
3320>::type
3321valarray<_Tp>::operator-=(const _Expr& __v)
3322{
3323    size_t __i = 0;
3324    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3325        *__t -= __v[__i];
3326    return *this;
3327}
3328
3329template <class _Tp>
3330template <class _Expr>
3331inline _LIBCPP_ALWAYS_INLINE
3332typename enable_if
3333<
3334    __is_val_expr<_Expr>::value,
3335    valarray<_Tp>&
3336>::type
3337valarray<_Tp>::operator^=(const _Expr& __v)
3338{
3339    size_t __i = 0;
3340    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3341        *__t ^= __v[__i];
3342    return *this;
3343}
3344
3345template <class _Tp>
3346template <class _Expr>
3347inline _LIBCPP_ALWAYS_INLINE
3348typename enable_if
3349<
3350    __is_val_expr<_Expr>::value,
3351    valarray<_Tp>&
3352>::type
3353valarray<_Tp>::operator|=(const _Expr& __v)
3354{
3355    size_t __i = 0;
3356    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3357        *__t |= __v[__i];
3358    return *this;
3359}
3360
3361template <class _Tp>
3362template <class _Expr>
3363inline _LIBCPP_ALWAYS_INLINE
3364typename enable_if
3365<
3366    __is_val_expr<_Expr>::value,
3367    valarray<_Tp>&
3368>::type
3369valarray<_Tp>::operator&=(const _Expr& __v)
3370{
3371    size_t __i = 0;
3372    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3373        *__t &= __v[__i];
3374    return *this;
3375}
3376
3377template <class _Tp>
3378template <class _Expr>
3379inline _LIBCPP_ALWAYS_INLINE
3380typename enable_if
3381<
3382    __is_val_expr<_Expr>::value,
3383    valarray<_Tp>&
3384>::type
3385valarray<_Tp>::operator<<=(const _Expr& __v)
3386{
3387    size_t __i = 0;
3388    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3389        *__t <<= __v[__i];
3390    return *this;
3391}
3392
3393template <class _Tp>
3394template <class _Expr>
3395inline _LIBCPP_ALWAYS_INLINE
3396typename enable_if
3397<
3398    __is_val_expr<_Expr>::value,
3399    valarray<_Tp>&
3400>::type
3401valarray<_Tp>::operator>>=(const _Expr& __v)
3402{
3403    size_t __i = 0;
3404    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
3405        *__t >>= __v[__i];
3406    return *this;
3407}
3408
3409template <class _Tp>
3410inline _LIBCPP_ALWAYS_INLINE
3411void
3412valarray<_Tp>::swap(valarray& __v)
3413{
3414    _STD::swap(__begin_, __v.__begin_);
3415    _STD::swap(__end_, __v.__end_);
3416}
3417
3418template <class _Tp>
3419inline _LIBCPP_ALWAYS_INLINE
3420_Tp
3421valarray<_Tp>::sum() const
3422{
3423    if (__begin_ == __end_)
3424        return value_type();
3425    const value_type* __p = __begin_;
3426    _Tp __r = *__p;
3427    for (++__p; __p != __end_; ++__p)
3428        __r += *__p;
3429    return __r;
3430}
3431
3432template <class _Tp>
3433inline _LIBCPP_ALWAYS_INLINE
3434_Tp
3435valarray<_Tp>::min() const
3436{
3437    if (__begin_ == __end_)
3438        return value_type();
3439    return *_STD::min_element(__begin_, __end_);
3440}
3441
3442template <class _Tp>
3443inline _LIBCPP_ALWAYS_INLINE
3444_Tp
3445valarray<_Tp>::max() const
3446{
3447    if (__begin_ == __end_)
3448        return value_type();
3449    return *_STD::max_element(__begin_, __end_);
3450}
3451
3452template <class _Tp>
3453valarray<_Tp>
3454valarray<_Tp>::shift(int __i) const
3455{
3456    valarray<value_type> __r;
3457    size_t __n = size();
3458    if (__n)
3459    {
3460        __r.__begin_ =
3461            __r.__end_ =
3462                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3463        const value_type* __sb;
3464        value_type* __tb;
3465        value_type* __te;
3466        if (__i >= 0)
3467        {
3468            __i = _STD::min(__i, static_cast<int>(__n));
3469            __sb = __begin_ + __i;
3470            __tb = __r.__begin_;
3471            __te = __r.__begin_ + (__n - __i);
3472        }
3473        else
3474        {
3475            __i = _STD::min(-__i, static_cast<int>(__n));
3476            __sb = __begin_;
3477            __tb = __r.__begin_ + __i;
3478            __te = __r.__begin_ + __n;
3479        }
3480        for (; __r.__end_ != __tb; ++__r.__end_)
3481            ::new (__r.__end_) value_type();
3482        for (; __r.__end_ != __te; ++__r.__end_, ++__sb)
3483            ::new (__r.__end_) value_type(*__sb);
3484        for (__te = __r.__begin_ + __n; __r.__end_ != __te; ++__r.__end_)
3485            ::new (__r.__end_) value_type();
3486    }
3487    return __r;
3488}
3489
3490template <class _Tp>
3491valarray<_Tp>
3492valarray<_Tp>::cshift(int __i) const
3493{
3494    valarray<value_type> __r;
3495    size_t __n = size();
3496    if (__n)
3497    {
3498        __r.__begin_ =
3499            __r.__end_ =
3500                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3501        __i %= static_cast<int>(__n);
3502        const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i;
3503        for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s)
3504            ::new (__r.__end_) value_type(*__s);
3505        for (const value_type* __s = __begin_; __s != __m; ++__r.__end_, ++__s)
3506            ::new (__r.__end_) value_type(*__s);
3507    }
3508    return __r;
3509}
3510
3511template <class _Tp>
3512valarray<_Tp>
3513valarray<_Tp>::apply(value_type __f(value_type)) const
3514{
3515    valarray<value_type> __r;
3516    size_t __n = size();
3517    if (__n)
3518    {
3519        __r.__begin_ =
3520            __r.__end_ =
3521                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3522        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
3523            ::new (__r.__end_) value_type(__f(*__p));
3524    }
3525    return __r;
3526}
3527
3528template <class _Tp>
3529valarray<_Tp>
3530valarray<_Tp>::apply(value_type __f(const value_type&)) const
3531{
3532    valarray<value_type> __r;
3533    size_t __n = size();
3534    if (__n)
3535    {
3536        __r.__begin_ =
3537            __r.__end_ =
3538                static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3539        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
3540            ::new (__r.__end_) value_type(__f(*__p));
3541    }
3542    return __r;
3543}
3544
3545template <class _Tp>
3546void
3547valarray<_Tp>::resize(size_t __n, value_type __x)
3548{
3549    if (__begin_ != nullptr)
3550    {
3551        while (__end_ != __begin_)
3552            (--__end_)->~value_type();
3553        ::operator delete(__begin_);
3554        __begin_ = __end_ = nullptr;
3555    }
3556    if (__n)
3557    {
3558        __begin_ = __end_ = static_cast<value_type*>(::operator new(__n * sizeof(value_type)));
3559#ifndef _LIBCPP_NO_EXCEPTIONS
3560        try
3561        {
3562#endif
3563            for (; __n; --__n, ++__end_)
3564                ::new (__end_) value_type(__x);
3565#ifndef _LIBCPP_NO_EXCEPTIONS
3566        }
3567        catch (...)
3568        {
3569            resize(0);
3570            throw;
3571        }
3572#endif
3573    }
3574}
3575
3576template<class _Tp>
3577inline _LIBCPP_ALWAYS_INLINE
3578void
3579swap(valarray<_Tp>& __x, valarray<_Tp>& __y)
3580{
3581    __x.swap(__y);
3582}
3583
3584template<class _Expr1, class _Expr2>
3585inline _LIBCPP_ALWAYS_INLINE
3586typename enable_if
3587<
3588    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3589    __val_expr<_BinaryOp<multiplies<typename _Expr1::value_type>, _Expr1, _Expr2> >
3590>::type
3591operator*(const _Expr1& __x, const _Expr2& __y)
3592{
3593    typedef typename _Expr1::value_type value_type;
3594    typedef _BinaryOp<multiplies<value_type>, _Expr1, _Expr2> _Op;
3595    return __val_expr<_Op>(_Op(multiplies<value_type>(), __x, __y));
3596}
3597
3598template<class _Expr>
3599inline _LIBCPP_ALWAYS_INLINE
3600typename enable_if
3601<
3602    __is_val_expr<_Expr>::value,
3603    __val_expr<_BinaryOp<multiplies<typename _Expr::value_type>,
3604               _Expr, __scalar_expr<typename _Expr::value_type> > >
3605>::type
3606operator*(const _Expr& __x, const typename _Expr::value_type& __y)
3607{
3608    typedef typename _Expr::value_type value_type;
3609    typedef _BinaryOp<multiplies<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3610    return __val_expr<_Op>(_Op(multiplies<value_type>(),
3611                           __x, __scalar_expr<value_type>(__y, __x.size())));
3612}
3613
3614template<class _Expr>
3615inline _LIBCPP_ALWAYS_INLINE
3616typename enable_if
3617<
3618    __is_val_expr<_Expr>::value,
3619    __val_expr<_BinaryOp<multiplies<typename _Expr::value_type>,
3620               __scalar_expr<typename _Expr::value_type>, _Expr> >
3621>::type
3622operator*(const typename _Expr::value_type& __x, const _Expr& __y)
3623{
3624    typedef typename _Expr::value_type value_type;
3625    typedef _BinaryOp<multiplies<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3626    return __val_expr<_Op>(_Op(multiplies<value_type>(),
3627                           __scalar_expr<value_type>(__x, __y.size()), __y));
3628}
3629
3630template<class _Expr1, class _Expr2>
3631inline _LIBCPP_ALWAYS_INLINE
3632typename enable_if
3633<
3634    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3635    __val_expr<_BinaryOp<divides<typename _Expr1::value_type>, _Expr1, _Expr2> >
3636>::type
3637operator/(const _Expr1& __x, const _Expr2& __y)
3638{
3639    typedef typename _Expr1::value_type value_type;
3640    typedef _BinaryOp<divides<value_type>, _Expr1, _Expr2> _Op;
3641    return __val_expr<_Op>(_Op(divides<value_type>(), __x, __y));
3642}
3643
3644template<class _Expr>
3645inline _LIBCPP_ALWAYS_INLINE
3646typename enable_if
3647<
3648    __is_val_expr<_Expr>::value,
3649    __val_expr<_BinaryOp<divides<typename _Expr::value_type>,
3650               _Expr, __scalar_expr<typename _Expr::value_type> > >
3651>::type
3652operator/(const _Expr& __x, const typename _Expr::value_type& __y)
3653{
3654    typedef typename _Expr::value_type value_type;
3655    typedef _BinaryOp<divides<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3656    return __val_expr<_Op>(_Op(divides<value_type>(),
3657                           __x, __scalar_expr<value_type>(__y, __x.size())));
3658}
3659
3660template<class _Expr>
3661inline _LIBCPP_ALWAYS_INLINE
3662typename enable_if
3663<
3664    __is_val_expr<_Expr>::value,
3665    __val_expr<_BinaryOp<divides<typename _Expr::value_type>,
3666               __scalar_expr<typename _Expr::value_type>, _Expr> >
3667>::type
3668operator/(const typename _Expr::value_type& __x, const _Expr& __y)
3669{
3670    typedef typename _Expr::value_type value_type;
3671    typedef _BinaryOp<divides<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3672    return __val_expr<_Op>(_Op(divides<value_type>(),
3673                           __scalar_expr<value_type>(__x, __y.size()), __y));
3674}
3675
3676template<class _Expr1, class _Expr2>
3677inline _LIBCPP_ALWAYS_INLINE
3678typename enable_if
3679<
3680    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3681    __val_expr<_BinaryOp<modulus<typename _Expr1::value_type>, _Expr1, _Expr2> >
3682>::type
3683operator%(const _Expr1& __x, const _Expr2& __y)
3684{
3685    typedef typename _Expr1::value_type value_type;
3686    typedef _BinaryOp<modulus<value_type>, _Expr1, _Expr2> _Op;
3687    return __val_expr<_Op>(_Op(modulus<value_type>(), __x, __y));
3688}
3689
3690template<class _Expr>
3691inline _LIBCPP_ALWAYS_INLINE
3692typename enable_if
3693<
3694    __is_val_expr<_Expr>::value,
3695    __val_expr<_BinaryOp<modulus<typename _Expr::value_type>,
3696               _Expr, __scalar_expr<typename _Expr::value_type> > >
3697>::type
3698operator%(const _Expr& __x, const typename _Expr::value_type& __y)
3699{
3700    typedef typename _Expr::value_type value_type;
3701    typedef _BinaryOp<modulus<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3702    return __val_expr<_Op>(_Op(modulus<value_type>(),
3703                           __x, __scalar_expr<value_type>(__y, __x.size())));
3704}
3705
3706template<class _Expr>
3707inline _LIBCPP_ALWAYS_INLINE
3708typename enable_if
3709<
3710    __is_val_expr<_Expr>::value,
3711    __val_expr<_BinaryOp<modulus<typename _Expr::value_type>,
3712               __scalar_expr<typename _Expr::value_type>, _Expr> >
3713>::type
3714operator%(const typename _Expr::value_type& __x, const _Expr& __y)
3715{
3716    typedef typename _Expr::value_type value_type;
3717    typedef _BinaryOp<modulus<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3718    return __val_expr<_Op>(_Op(modulus<value_type>(),
3719                           __scalar_expr<value_type>(__x, __y.size()), __y));
3720}
3721
3722template<class _Expr1, class _Expr2>
3723inline _LIBCPP_ALWAYS_INLINE
3724typename enable_if
3725<
3726    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3727    __val_expr<_BinaryOp<plus<typename _Expr1::value_type>, _Expr1, _Expr2> >
3728>::type
3729operator+(const _Expr1& __x, const _Expr2& __y)
3730{
3731    typedef typename _Expr1::value_type value_type;
3732    typedef _BinaryOp<plus<value_type>, _Expr1, _Expr2> _Op;
3733    return __val_expr<_Op>(_Op(plus<value_type>(), __x, __y));
3734}
3735
3736template<class _Expr>
3737inline _LIBCPP_ALWAYS_INLINE
3738typename enable_if
3739<
3740    __is_val_expr<_Expr>::value,
3741    __val_expr<_BinaryOp<plus<typename _Expr::value_type>,
3742               _Expr, __scalar_expr<typename _Expr::value_type> > >
3743>::type
3744operator+(const _Expr& __x, const typename _Expr::value_type& __y)
3745{
3746    typedef typename _Expr::value_type value_type;
3747    typedef _BinaryOp<plus<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3748    return __val_expr<_Op>(_Op(plus<value_type>(),
3749                           __x, __scalar_expr<value_type>(__y, __x.size())));
3750}
3751
3752template<class _Expr>
3753inline _LIBCPP_ALWAYS_INLINE
3754typename enable_if
3755<
3756    __is_val_expr<_Expr>::value,
3757    __val_expr<_BinaryOp<plus<typename _Expr::value_type>,
3758               __scalar_expr<typename _Expr::value_type>, _Expr> >
3759>::type
3760operator+(const typename _Expr::value_type& __x, const _Expr& __y)
3761{
3762    typedef typename _Expr::value_type value_type;
3763    typedef _BinaryOp<plus<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3764    return __val_expr<_Op>(_Op(plus<value_type>(),
3765                           __scalar_expr<value_type>(__x, __y.size()), __y));
3766}
3767
3768template<class _Expr1, class _Expr2>
3769inline _LIBCPP_ALWAYS_INLINE
3770typename enable_if
3771<
3772    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3773    __val_expr<_BinaryOp<minus<typename _Expr1::value_type>, _Expr1, _Expr2> >
3774>::type
3775operator-(const _Expr1& __x, const _Expr2& __y)
3776{
3777    typedef typename _Expr1::value_type value_type;
3778    typedef _BinaryOp<minus<value_type>, _Expr1, _Expr2> _Op;
3779    return __val_expr<_Op>(_Op(minus<value_type>(), __x, __y));
3780}
3781
3782template<class _Expr>
3783inline _LIBCPP_ALWAYS_INLINE
3784typename enable_if
3785<
3786    __is_val_expr<_Expr>::value,
3787    __val_expr<_BinaryOp<minus<typename _Expr::value_type>,
3788               _Expr, __scalar_expr<typename _Expr::value_type> > >
3789>::type
3790operator-(const _Expr& __x, const typename _Expr::value_type& __y)
3791{
3792    typedef typename _Expr::value_type value_type;
3793    typedef _BinaryOp<minus<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3794    return __val_expr<_Op>(_Op(minus<value_type>(),
3795                           __x, __scalar_expr<value_type>(__y, __x.size())));
3796}
3797
3798template<class _Expr>
3799inline _LIBCPP_ALWAYS_INLINE
3800typename enable_if
3801<
3802    __is_val_expr<_Expr>::value,
3803    __val_expr<_BinaryOp<minus<typename _Expr::value_type>,
3804               __scalar_expr<typename _Expr::value_type>, _Expr> >
3805>::type
3806operator-(const typename _Expr::value_type& __x, const _Expr& __y)
3807{
3808    typedef typename _Expr::value_type value_type;
3809    typedef _BinaryOp<minus<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3810    return __val_expr<_Op>(_Op(minus<value_type>(),
3811                           __scalar_expr<value_type>(__x, __y.size()), __y));
3812}
3813
3814template<class _Expr1, class _Expr2>
3815inline _LIBCPP_ALWAYS_INLINE
3816typename enable_if
3817<
3818    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3819    __val_expr<_BinaryOp<bit_xor<typename _Expr1::value_type>, _Expr1, _Expr2> >
3820>::type
3821operator^(const _Expr1& __x, const _Expr2& __y)
3822{
3823    typedef typename _Expr1::value_type value_type;
3824    typedef _BinaryOp<bit_xor<value_type>, _Expr1, _Expr2> _Op;
3825    return __val_expr<_Op>(_Op(bit_xor<value_type>(), __x, __y));
3826}
3827
3828template<class _Expr>
3829inline _LIBCPP_ALWAYS_INLINE
3830typename enable_if
3831<
3832    __is_val_expr<_Expr>::value,
3833    __val_expr<_BinaryOp<bit_xor<typename _Expr::value_type>,
3834               _Expr, __scalar_expr<typename _Expr::value_type> > >
3835>::type
3836operator^(const _Expr& __x, const typename _Expr::value_type& __y)
3837{
3838    typedef typename _Expr::value_type value_type;
3839    typedef _BinaryOp<bit_xor<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3840    return __val_expr<_Op>(_Op(bit_xor<value_type>(),
3841                           __x, __scalar_expr<value_type>(__y, __x.size())));
3842}
3843
3844template<class _Expr>
3845inline _LIBCPP_ALWAYS_INLINE
3846typename enable_if
3847<
3848    __is_val_expr<_Expr>::value,
3849    __val_expr<_BinaryOp<bit_xor<typename _Expr::value_type>,
3850               __scalar_expr<typename _Expr::value_type>, _Expr> >
3851>::type
3852operator^(const typename _Expr::value_type& __x, const _Expr& __y)
3853{
3854    typedef typename _Expr::value_type value_type;
3855    typedef _BinaryOp<bit_xor<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3856    return __val_expr<_Op>(_Op(bit_xor<value_type>(),
3857                           __scalar_expr<value_type>(__x, __y.size()), __y));
3858}
3859
3860template<class _Expr1, class _Expr2>
3861inline _LIBCPP_ALWAYS_INLINE
3862typename enable_if
3863<
3864    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3865    __val_expr<_BinaryOp<bit_and<typename _Expr1::value_type>, _Expr1, _Expr2> >
3866>::type
3867operator&(const _Expr1& __x, const _Expr2& __y)
3868{
3869    typedef typename _Expr1::value_type value_type;
3870    typedef _BinaryOp<bit_and<value_type>, _Expr1, _Expr2> _Op;
3871    return __val_expr<_Op>(_Op(bit_and<value_type>(), __x, __y));
3872}
3873
3874template<class _Expr>
3875inline _LIBCPP_ALWAYS_INLINE
3876typename enable_if
3877<
3878    __is_val_expr<_Expr>::value,
3879    __val_expr<_BinaryOp<bit_and<typename _Expr::value_type>,
3880               _Expr, __scalar_expr<typename _Expr::value_type> > >
3881>::type
3882operator&(const _Expr& __x, const typename _Expr::value_type& __y)
3883{
3884    typedef typename _Expr::value_type value_type;
3885    typedef _BinaryOp<bit_and<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3886    return __val_expr<_Op>(_Op(bit_and<value_type>(),
3887                           __x, __scalar_expr<value_type>(__y, __x.size())));
3888}
3889
3890template<class _Expr>
3891inline _LIBCPP_ALWAYS_INLINE
3892typename enable_if
3893<
3894    __is_val_expr<_Expr>::value,
3895    __val_expr<_BinaryOp<bit_and<typename _Expr::value_type>,
3896               __scalar_expr<typename _Expr::value_type>, _Expr> >
3897>::type
3898operator&(const typename _Expr::value_type& __x, const _Expr& __y)
3899{
3900    typedef typename _Expr::value_type value_type;
3901    typedef _BinaryOp<bit_and<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3902    return __val_expr<_Op>(_Op(bit_and<value_type>(),
3903                           __scalar_expr<value_type>(__x, __y.size()), __y));
3904}
3905
3906template<class _Expr1, class _Expr2>
3907inline _LIBCPP_ALWAYS_INLINE
3908typename enable_if
3909<
3910    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3911    __val_expr<_BinaryOp<bit_or<typename _Expr1::value_type>, _Expr1, _Expr2> >
3912>::type
3913operator|(const _Expr1& __x, const _Expr2& __y)
3914{
3915    typedef typename _Expr1::value_type value_type;
3916    typedef _BinaryOp<bit_or<value_type>, _Expr1, _Expr2> _Op;
3917    return __val_expr<_Op>(_Op(bit_or<value_type>(), __x, __y));
3918}
3919
3920template<class _Expr>
3921inline _LIBCPP_ALWAYS_INLINE
3922typename enable_if
3923<
3924    __is_val_expr<_Expr>::value,
3925    __val_expr<_BinaryOp<bit_or<typename _Expr::value_type>,
3926               _Expr, __scalar_expr<typename _Expr::value_type> > >
3927>::type
3928operator|(const _Expr& __x, const typename _Expr::value_type& __y)
3929{
3930    typedef typename _Expr::value_type value_type;
3931    typedef _BinaryOp<bit_or<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3932    return __val_expr<_Op>(_Op(bit_or<value_type>(),
3933                           __x, __scalar_expr<value_type>(__y, __x.size())));
3934}
3935
3936template<class _Expr>
3937inline _LIBCPP_ALWAYS_INLINE
3938typename enable_if
3939<
3940    __is_val_expr<_Expr>::value,
3941    __val_expr<_BinaryOp<bit_or<typename _Expr::value_type>,
3942               __scalar_expr<typename _Expr::value_type>, _Expr> >
3943>::type
3944operator|(const typename _Expr::value_type& __x, const _Expr& __y)
3945{
3946    typedef typename _Expr::value_type value_type;
3947    typedef _BinaryOp<bit_or<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3948    return __val_expr<_Op>(_Op(bit_or<value_type>(),
3949                           __scalar_expr<value_type>(__x, __y.size()), __y));
3950}
3951
3952template<class _Expr1, class _Expr2>
3953inline _LIBCPP_ALWAYS_INLINE
3954typename enable_if
3955<
3956    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
3957    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr1::value_type>, _Expr1, _Expr2> >
3958>::type
3959operator<<(const _Expr1& __x, const _Expr2& __y)
3960{
3961    typedef typename _Expr1::value_type value_type;
3962    typedef _BinaryOp<__bit_shift_left<value_type>, _Expr1, _Expr2> _Op;
3963    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(), __x, __y));
3964}
3965
3966template<class _Expr>
3967inline _LIBCPP_ALWAYS_INLINE
3968typename enable_if
3969<
3970    __is_val_expr<_Expr>::value,
3971    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,
3972               _Expr, __scalar_expr<typename _Expr::value_type> > >
3973>::type
3974operator<<(const _Expr& __x, const typename _Expr::value_type& __y)
3975{
3976    typedef typename _Expr::value_type value_type;
3977    typedef _BinaryOp<__bit_shift_left<value_type>, _Expr, __scalar_expr<value_type> > _Op;
3978    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(),
3979                           __x, __scalar_expr<value_type>(__y, __x.size())));
3980}
3981
3982template<class _Expr>
3983inline _LIBCPP_ALWAYS_INLINE
3984typename enable_if
3985<
3986    __is_val_expr<_Expr>::value,
3987    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,
3988               __scalar_expr<typename _Expr::value_type>, _Expr> >
3989>::type
3990operator<<(const typename _Expr::value_type& __x, const _Expr& __y)
3991{
3992    typedef typename _Expr::value_type value_type;
3993    typedef _BinaryOp<__bit_shift_left<value_type>, __scalar_expr<value_type>, _Expr> _Op;
3994    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(),
3995                           __scalar_expr<value_type>(__x, __y.size()), __y));
3996}
3997
3998template<class _Expr1, class _Expr2>
3999inline _LIBCPP_ALWAYS_INLINE
4000typename enable_if
4001<
4002    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4003    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr1::value_type>, _Expr1, _Expr2> >
4004>::type
4005operator>>(const _Expr1& __x, const _Expr2& __y)
4006{
4007    typedef typename _Expr1::value_type value_type;
4008    typedef _BinaryOp<__bit_shift_right<value_type>, _Expr1, _Expr2> _Op;
4009    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(), __x, __y));
4010}
4011
4012template<class _Expr>
4013inline _LIBCPP_ALWAYS_INLINE
4014typename enable_if
4015<
4016    __is_val_expr<_Expr>::value,
4017    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr::value_type>,
4018               _Expr, __scalar_expr<typename _Expr::value_type> > >
4019>::type
4020operator>>(const _Expr& __x, const typename _Expr::value_type& __y)
4021{
4022    typedef typename _Expr::value_type value_type;
4023    typedef _BinaryOp<__bit_shift_right<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4024    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(),
4025                           __x, __scalar_expr<value_type>(__y, __x.size())));
4026}
4027
4028template<class _Expr>
4029inline _LIBCPP_ALWAYS_INLINE
4030typename enable_if
4031<
4032    __is_val_expr<_Expr>::value,
4033    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr::value_type>,
4034               __scalar_expr<typename _Expr::value_type>, _Expr> >
4035>::type
4036operator>>(const typename _Expr::value_type& __x, const _Expr& __y)
4037{
4038    typedef typename _Expr::value_type value_type;
4039    typedef _BinaryOp<__bit_shift_right<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4040    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(),
4041                           __scalar_expr<value_type>(__x, __y.size()), __y));
4042}
4043
4044template<class _Expr1, class _Expr2>
4045inline _LIBCPP_ALWAYS_INLINE
4046typename enable_if
4047<
4048    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4049    __val_expr<_BinaryOp<logical_and<typename _Expr1::value_type>, _Expr1, _Expr2> >
4050>::type
4051operator&&(const _Expr1& __x, const _Expr2& __y)
4052{
4053    typedef typename _Expr1::value_type value_type;
4054    typedef _BinaryOp<logical_and<value_type>, _Expr1, _Expr2> _Op;
4055    return __val_expr<_Op>(_Op(logical_and<value_type>(), __x, __y));
4056}
4057
4058template<class _Expr>
4059inline _LIBCPP_ALWAYS_INLINE
4060typename enable_if
4061<
4062    __is_val_expr<_Expr>::value,
4063    __val_expr<_BinaryOp<logical_and<typename _Expr::value_type>,
4064               _Expr, __scalar_expr<typename _Expr::value_type> > >
4065>::type
4066operator&&(const _Expr& __x, const typename _Expr::value_type& __y)
4067{
4068    typedef typename _Expr::value_type value_type;
4069    typedef _BinaryOp<logical_and<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4070    return __val_expr<_Op>(_Op(logical_and<value_type>(),
4071                           __x, __scalar_expr<value_type>(__y, __x.size())));
4072}
4073
4074template<class _Expr>
4075inline _LIBCPP_ALWAYS_INLINE
4076typename enable_if
4077<
4078    __is_val_expr<_Expr>::value,
4079    __val_expr<_BinaryOp<logical_and<typename _Expr::value_type>,
4080               __scalar_expr<typename _Expr::value_type>, _Expr> >
4081>::type
4082operator&&(const typename _Expr::value_type& __x, const _Expr& __y)
4083{
4084    typedef typename _Expr::value_type value_type;
4085    typedef _BinaryOp<logical_and<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4086    return __val_expr<_Op>(_Op(logical_and<value_type>(),
4087                           __scalar_expr<value_type>(__x, __y.size()), __y));
4088}
4089
4090template<class _Expr1, class _Expr2>
4091inline _LIBCPP_ALWAYS_INLINE
4092typename enable_if
4093<
4094    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4095    __val_expr<_BinaryOp<logical_or<typename _Expr1::value_type>, _Expr1, _Expr2> >
4096>::type
4097operator||(const _Expr1& __x, const _Expr2& __y)
4098{
4099    typedef typename _Expr1::value_type value_type;
4100    typedef _BinaryOp<logical_or<value_type>, _Expr1, _Expr2> _Op;
4101    return __val_expr<_Op>(_Op(logical_or<value_type>(), __x, __y));
4102}
4103
4104template<class _Expr>
4105inline _LIBCPP_ALWAYS_INLINE
4106typename enable_if
4107<
4108    __is_val_expr<_Expr>::value,
4109    __val_expr<_BinaryOp<logical_or<typename _Expr::value_type>,
4110               _Expr, __scalar_expr<typename _Expr::value_type> > >
4111>::type
4112operator||(const _Expr& __x, const typename _Expr::value_type& __y)
4113{
4114    typedef typename _Expr::value_type value_type;
4115    typedef _BinaryOp<logical_or<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4116    return __val_expr<_Op>(_Op(logical_or<value_type>(),
4117                           __x, __scalar_expr<value_type>(__y, __x.size())));
4118}
4119
4120template<class _Expr>
4121inline _LIBCPP_ALWAYS_INLINE
4122typename enable_if
4123<
4124    __is_val_expr<_Expr>::value,
4125    __val_expr<_BinaryOp<logical_or<typename _Expr::value_type>,
4126               __scalar_expr<typename _Expr::value_type>, _Expr> >
4127>::type
4128operator||(const typename _Expr::value_type& __x, const _Expr& __y)
4129{
4130    typedef typename _Expr::value_type value_type;
4131    typedef _BinaryOp<logical_or<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4132    return __val_expr<_Op>(_Op(logical_or<value_type>(),
4133                           __scalar_expr<value_type>(__x, __y.size()), __y));
4134}
4135
4136template<class _Expr1, class _Expr2>
4137inline _LIBCPP_ALWAYS_INLINE
4138typename enable_if
4139<
4140    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4141    __val_expr<_BinaryOp<equal_to<typename _Expr1::value_type>, _Expr1, _Expr2> >
4142>::type
4143operator==(const _Expr1& __x, const _Expr2& __y)
4144{
4145    typedef typename _Expr1::value_type value_type;
4146    typedef _BinaryOp<equal_to<value_type>, _Expr1, _Expr2> _Op;
4147    return __val_expr<_Op>(_Op(equal_to<value_type>(), __x, __y));
4148}
4149
4150template<class _Expr>
4151inline _LIBCPP_ALWAYS_INLINE
4152typename enable_if
4153<
4154    __is_val_expr<_Expr>::value,
4155    __val_expr<_BinaryOp<equal_to<typename _Expr::value_type>,
4156               _Expr, __scalar_expr<typename _Expr::value_type> > >
4157>::type
4158operator==(const _Expr& __x, const typename _Expr::value_type& __y)
4159{
4160    typedef typename _Expr::value_type value_type;
4161    typedef _BinaryOp<equal_to<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4162    return __val_expr<_Op>(_Op(equal_to<value_type>(),
4163                           __x, __scalar_expr<value_type>(__y, __x.size())));
4164}
4165
4166template<class _Expr>
4167inline _LIBCPP_ALWAYS_INLINE
4168typename enable_if
4169<
4170    __is_val_expr<_Expr>::value,
4171    __val_expr<_BinaryOp<equal_to<typename _Expr::value_type>,
4172               __scalar_expr<typename _Expr::value_type>, _Expr> >
4173>::type
4174operator==(const typename _Expr::value_type& __x, const _Expr& __y)
4175{
4176    typedef typename _Expr::value_type value_type;
4177    typedef _BinaryOp<equal_to<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4178    return __val_expr<_Op>(_Op(equal_to<value_type>(),
4179                           __scalar_expr<value_type>(__x, __y.size()), __y));
4180}
4181
4182template<class _Expr1, class _Expr2>
4183inline _LIBCPP_ALWAYS_INLINE
4184typename enable_if
4185<
4186    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4187    __val_expr<_BinaryOp<not_equal_to<typename _Expr1::value_type>, _Expr1, _Expr2> >
4188>::type
4189operator!=(const _Expr1& __x, const _Expr2& __y)
4190{
4191    typedef typename _Expr1::value_type value_type;
4192    typedef _BinaryOp<not_equal_to<value_type>, _Expr1, _Expr2> _Op;
4193    return __val_expr<_Op>(_Op(not_equal_to<value_type>(), __x, __y));
4194}
4195
4196template<class _Expr>
4197inline _LIBCPP_ALWAYS_INLINE
4198typename enable_if
4199<
4200    __is_val_expr<_Expr>::value,
4201    __val_expr<_BinaryOp<not_equal_to<typename _Expr::value_type>,
4202               _Expr, __scalar_expr<typename _Expr::value_type> > >
4203>::type
4204operator!=(const _Expr& __x, const typename _Expr::value_type& __y)
4205{
4206    typedef typename _Expr::value_type value_type;
4207    typedef _BinaryOp<not_equal_to<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4208    return __val_expr<_Op>(_Op(not_equal_to<value_type>(),
4209                           __x, __scalar_expr<value_type>(__y, __x.size())));
4210}
4211
4212template<class _Expr>
4213inline _LIBCPP_ALWAYS_INLINE
4214typename enable_if
4215<
4216    __is_val_expr<_Expr>::value,
4217    __val_expr<_BinaryOp<not_equal_to<typename _Expr::value_type>,
4218               __scalar_expr<typename _Expr::value_type>, _Expr> >
4219>::type
4220operator!=(const typename _Expr::value_type& __x, const _Expr& __y)
4221{
4222    typedef typename _Expr::value_type value_type;
4223    typedef _BinaryOp<not_equal_to<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4224    return __val_expr<_Op>(_Op(not_equal_to<value_type>(),
4225                           __scalar_expr<value_type>(__x, __y.size()), __y));
4226}
4227
4228template<class _Expr1, class _Expr2>
4229inline _LIBCPP_ALWAYS_INLINE
4230typename enable_if
4231<
4232    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4233    __val_expr<_BinaryOp<less<typename _Expr1::value_type>, _Expr1, _Expr2> >
4234>::type
4235operator<(const _Expr1& __x, const _Expr2& __y)
4236{
4237    typedef typename _Expr1::value_type value_type;
4238    typedef _BinaryOp<less<value_type>, _Expr1, _Expr2> _Op;
4239    return __val_expr<_Op>(_Op(less<value_type>(), __x, __y));
4240}
4241
4242template<class _Expr>
4243inline _LIBCPP_ALWAYS_INLINE
4244typename enable_if
4245<
4246    __is_val_expr<_Expr>::value,
4247    __val_expr<_BinaryOp<less<typename _Expr::value_type>,
4248               _Expr, __scalar_expr<typename _Expr::value_type> > >
4249>::type
4250operator<(const _Expr& __x, const typename _Expr::value_type& __y)
4251{
4252    typedef typename _Expr::value_type value_type;
4253    typedef _BinaryOp<less<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4254    return __val_expr<_Op>(_Op(less<value_type>(),
4255                           __x, __scalar_expr<value_type>(__y, __x.size())));
4256}
4257
4258template<class _Expr>
4259inline _LIBCPP_ALWAYS_INLINE
4260typename enable_if
4261<
4262    __is_val_expr<_Expr>::value,
4263    __val_expr<_BinaryOp<less<typename _Expr::value_type>,
4264               __scalar_expr<typename _Expr::value_type>, _Expr> >
4265>::type
4266operator<(const typename _Expr::value_type& __x, const _Expr& __y)
4267{
4268    typedef typename _Expr::value_type value_type;
4269    typedef _BinaryOp<less<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4270    return __val_expr<_Op>(_Op(less<value_type>(),
4271                           __scalar_expr<value_type>(__x, __y.size()), __y));
4272}
4273
4274template<class _Expr1, class _Expr2>
4275inline _LIBCPP_ALWAYS_INLINE
4276typename enable_if
4277<
4278    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4279    __val_expr<_BinaryOp<greater<typename _Expr1::value_type>, _Expr1, _Expr2> >
4280>::type
4281operator>(const _Expr1& __x, const _Expr2& __y)
4282{
4283    typedef typename _Expr1::value_type value_type;
4284    typedef _BinaryOp<greater<value_type>, _Expr1, _Expr2> _Op;
4285    return __val_expr<_Op>(_Op(greater<value_type>(), __x, __y));
4286}
4287
4288template<class _Expr>
4289inline _LIBCPP_ALWAYS_INLINE
4290typename enable_if
4291<
4292    __is_val_expr<_Expr>::value,
4293    __val_expr<_BinaryOp<greater<typename _Expr::value_type>,
4294               _Expr, __scalar_expr<typename _Expr::value_type> > >
4295>::type
4296operator>(const _Expr& __x, const typename _Expr::value_type& __y)
4297{
4298    typedef typename _Expr::value_type value_type;
4299    typedef _BinaryOp<greater<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4300    return __val_expr<_Op>(_Op(greater<value_type>(),
4301                           __x, __scalar_expr<value_type>(__y, __x.size())));
4302}
4303
4304template<class _Expr>
4305inline _LIBCPP_ALWAYS_INLINE
4306typename enable_if
4307<
4308    __is_val_expr<_Expr>::value,
4309    __val_expr<_BinaryOp<greater<typename _Expr::value_type>,
4310               __scalar_expr<typename _Expr::value_type>, _Expr> >
4311>::type
4312operator>(const typename _Expr::value_type& __x, const _Expr& __y)
4313{
4314    typedef typename _Expr::value_type value_type;
4315    typedef _BinaryOp<greater<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4316    return __val_expr<_Op>(_Op(greater<value_type>(),
4317                           __scalar_expr<value_type>(__x, __y.size()), __y));
4318}
4319
4320template<class _Expr1, class _Expr2>
4321inline _LIBCPP_ALWAYS_INLINE
4322typename enable_if
4323<
4324    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4325    __val_expr<_BinaryOp<less_equal<typename _Expr1::value_type>, _Expr1, _Expr2> >
4326>::type
4327operator<=(const _Expr1& __x, const _Expr2& __y)
4328{
4329    typedef typename _Expr1::value_type value_type;
4330    typedef _BinaryOp<less_equal<value_type>, _Expr1, _Expr2> _Op;
4331    return __val_expr<_Op>(_Op(less_equal<value_type>(), __x, __y));
4332}
4333
4334template<class _Expr>
4335inline _LIBCPP_ALWAYS_INLINE
4336typename enable_if
4337<
4338    __is_val_expr<_Expr>::value,
4339    __val_expr<_BinaryOp<less_equal<typename _Expr::value_type>,
4340               _Expr, __scalar_expr<typename _Expr::value_type> > >
4341>::type
4342operator<=(const _Expr& __x, const typename _Expr::value_type& __y)
4343{
4344    typedef typename _Expr::value_type value_type;
4345    typedef _BinaryOp<less_equal<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4346    return __val_expr<_Op>(_Op(less_equal<value_type>(),
4347                           __x, __scalar_expr<value_type>(__y, __x.size())));
4348}
4349
4350template<class _Expr>
4351inline _LIBCPP_ALWAYS_INLINE
4352typename enable_if
4353<
4354    __is_val_expr<_Expr>::value,
4355    __val_expr<_BinaryOp<less_equal<typename _Expr::value_type>,
4356               __scalar_expr<typename _Expr::value_type>, _Expr> >
4357>::type
4358operator<=(const typename _Expr::value_type& __x, const _Expr& __y)
4359{
4360    typedef typename _Expr::value_type value_type;
4361    typedef _BinaryOp<less_equal<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4362    return __val_expr<_Op>(_Op(less_equal<value_type>(),
4363                           __scalar_expr<value_type>(__x, __y.size()), __y));
4364}
4365
4366template<class _Expr1, class _Expr2>
4367inline _LIBCPP_ALWAYS_INLINE
4368typename enable_if
4369<
4370    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4371    __val_expr<_BinaryOp<greater_equal<typename _Expr1::value_type>, _Expr1, _Expr2> >
4372>::type
4373operator>=(const _Expr1& __x, const _Expr2& __y)
4374{
4375    typedef typename _Expr1::value_type value_type;
4376    typedef _BinaryOp<greater_equal<value_type>, _Expr1, _Expr2> _Op;
4377    return __val_expr<_Op>(_Op(greater_equal<value_type>(), __x, __y));
4378}
4379
4380template<class _Expr>
4381inline _LIBCPP_ALWAYS_INLINE
4382typename enable_if
4383<
4384    __is_val_expr<_Expr>::value,
4385    __val_expr<_BinaryOp<greater_equal<typename _Expr::value_type>,
4386               _Expr, __scalar_expr<typename _Expr::value_type> > >
4387>::type
4388operator>=(const _Expr& __x, const typename _Expr::value_type& __y)
4389{
4390    typedef typename _Expr::value_type value_type;
4391    typedef _BinaryOp<greater_equal<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4392    return __val_expr<_Op>(_Op(greater_equal<value_type>(),
4393                           __x, __scalar_expr<value_type>(__y, __x.size())));
4394}
4395
4396template<class _Expr>
4397inline _LIBCPP_ALWAYS_INLINE
4398typename enable_if
4399<
4400    __is_val_expr<_Expr>::value,
4401    __val_expr<_BinaryOp<greater_equal<typename _Expr::value_type>,
4402               __scalar_expr<typename _Expr::value_type>, _Expr> >
4403>::type
4404operator>=(const typename _Expr::value_type& __x, const _Expr& __y)
4405{
4406    typedef typename _Expr::value_type value_type;
4407    typedef _BinaryOp<greater_equal<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4408    return __val_expr<_Op>(_Op(greater_equal<value_type>(),
4409                           __scalar_expr<value_type>(__x, __y.size()), __y));
4410}
4411
4412template<class _Expr>
4413inline _LIBCPP_ALWAYS_INLINE
4414typename enable_if
4415<
4416    __is_val_expr<_Expr>::value,
4417    __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
4418>::type
4419abs(const _Expr& __x)
4420{
4421    typedef typename _Expr::value_type value_type;
4422    typedef _UnaryOp<__abs_expr<value_type>, _Expr> _Op;
4423    return __val_expr<_Op>(_Op(__abs_expr<value_type>(), __x));
4424}
4425
4426template<class _Expr>
4427inline _LIBCPP_ALWAYS_INLINE
4428typename enable_if
4429<
4430    __is_val_expr<_Expr>::value,
4431    __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
4432>::type
4433acos(const _Expr& __x)
4434{
4435    typedef typename _Expr::value_type value_type;
4436    typedef _UnaryOp<__acos_expr<value_type>, _Expr> _Op;
4437    return __val_expr<_Op>(_Op(__acos_expr<value_type>(), __x));
4438}
4439
4440template<class _Expr>
4441inline _LIBCPP_ALWAYS_INLINE
4442typename enable_if
4443<
4444    __is_val_expr<_Expr>::value,
4445    __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
4446>::type
4447asin(const _Expr& __x)
4448{
4449    typedef typename _Expr::value_type value_type;
4450    typedef _UnaryOp<__asin_expr<value_type>, _Expr> _Op;
4451    return __val_expr<_Op>(_Op(__asin_expr<value_type>(), __x));
4452}
4453
4454template<class _Expr>
4455inline _LIBCPP_ALWAYS_INLINE
4456typename enable_if
4457<
4458    __is_val_expr<_Expr>::value,
4459    __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
4460>::type
4461atan(const _Expr& __x)
4462{
4463    typedef typename _Expr::value_type value_type;
4464    typedef _UnaryOp<__atan_expr<value_type>, _Expr> _Op;
4465    return __val_expr<_Op>(_Op(__atan_expr<value_type>(), __x));
4466}
4467
4468template<class _Expr1, class _Expr2>
4469inline _LIBCPP_ALWAYS_INLINE
4470typename enable_if
4471<
4472    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4473    __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
4474>::type
4475atan2(const _Expr1& __x, const _Expr2& __y)
4476{
4477    typedef typename _Expr1::value_type value_type;
4478    typedef _BinaryOp<__atan2_expr<value_type>, _Expr1, _Expr2> _Op;
4479    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(), __x, __y));
4480}
4481
4482template<class _Expr>
4483inline _LIBCPP_ALWAYS_INLINE
4484typename enable_if
4485<
4486    __is_val_expr<_Expr>::value,
4487    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
4488               _Expr, __scalar_expr<typename _Expr::value_type> > >
4489>::type
4490atan2(const _Expr& __x, const typename _Expr::value_type& __y)
4491{
4492    typedef typename _Expr::value_type value_type;
4493    typedef _BinaryOp<__atan2_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4494    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
4495                           __x, __scalar_expr<value_type>(__y, __x.size())));
4496}
4497
4498template<class _Expr>
4499inline _LIBCPP_ALWAYS_INLINE
4500typename enable_if
4501<
4502    __is_val_expr<_Expr>::value,
4503    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
4504               __scalar_expr<typename _Expr::value_type>, _Expr> >
4505>::type
4506atan2(const typename _Expr::value_type& __x, const _Expr& __y)
4507{
4508    typedef typename _Expr::value_type value_type;
4509    typedef _BinaryOp<__atan2_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4510    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
4511                           __scalar_expr<value_type>(__x, __y.size()), __y));
4512}
4513
4514template<class _Expr>
4515inline _LIBCPP_ALWAYS_INLINE
4516typename enable_if
4517<
4518    __is_val_expr<_Expr>::value,
4519    __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
4520>::type
4521cos(const _Expr& __x)
4522{
4523    typedef typename _Expr::value_type value_type;
4524    typedef _UnaryOp<__cos_expr<value_type>, _Expr> _Op;
4525    return __val_expr<_Op>(_Op(__cos_expr<value_type>(), __x));
4526}
4527
4528template<class _Expr>
4529inline _LIBCPP_ALWAYS_INLINE
4530typename enable_if
4531<
4532    __is_val_expr<_Expr>::value,
4533    __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
4534>::type
4535cosh(const _Expr& __x)
4536{
4537    typedef typename _Expr::value_type value_type;
4538    typedef _UnaryOp<__cosh_expr<value_type>, _Expr> _Op;
4539    return __val_expr<_Op>(_Op(__cosh_expr<value_type>(), __x));
4540}
4541
4542template<class _Expr>
4543inline _LIBCPP_ALWAYS_INLINE
4544typename enable_if
4545<
4546    __is_val_expr<_Expr>::value,
4547    __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
4548>::type
4549exp(const _Expr& __x)
4550{
4551    typedef typename _Expr::value_type value_type;
4552    typedef _UnaryOp<__exp_expr<value_type>, _Expr> _Op;
4553    return __val_expr<_Op>(_Op(__exp_expr<value_type>(), __x));
4554}
4555
4556template<class _Expr>
4557inline _LIBCPP_ALWAYS_INLINE
4558typename enable_if
4559<
4560    __is_val_expr<_Expr>::value,
4561    __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
4562>::type
4563log(const _Expr& __x)
4564{
4565    typedef typename _Expr::value_type value_type;
4566    typedef _UnaryOp<__log_expr<value_type>, _Expr> _Op;
4567    return __val_expr<_Op>(_Op(__log_expr<value_type>(), __x));
4568}
4569
4570template<class _Expr>
4571inline _LIBCPP_ALWAYS_INLINE
4572typename enable_if
4573<
4574    __is_val_expr<_Expr>::value,
4575    __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
4576>::type
4577log10(const _Expr& __x)
4578{
4579    typedef typename _Expr::value_type value_type;
4580    typedef _UnaryOp<__log10_expr<value_type>, _Expr> _Op;
4581    return __val_expr<_Op>(_Op(__log10_expr<value_type>(), __x));
4582}
4583
4584template<class _Expr1, class _Expr2>
4585inline _LIBCPP_ALWAYS_INLINE
4586typename enable_if
4587<
4588    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
4589    __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
4590>::type
4591pow(const _Expr1& __x, const _Expr2& __y)
4592{
4593    typedef typename _Expr1::value_type value_type;
4594    typedef _BinaryOp<__pow_expr<value_type>, _Expr1, _Expr2> _Op;
4595    return __val_expr<_Op>(_Op(__pow_expr<value_type>(), __x, __y));
4596}
4597
4598template<class _Expr>
4599inline _LIBCPP_ALWAYS_INLINE
4600typename enable_if
4601<
4602    __is_val_expr<_Expr>::value,
4603    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
4604               _Expr, __scalar_expr<typename _Expr::value_type> > >
4605>::type
4606pow(const _Expr& __x, const typename _Expr::value_type& __y)
4607{
4608    typedef typename _Expr::value_type value_type;
4609    typedef _BinaryOp<__pow_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;
4610    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
4611                           __x, __scalar_expr<value_type>(__y, __x.size())));
4612}
4613
4614template<class _Expr>
4615inline _LIBCPP_ALWAYS_INLINE
4616typename enable_if
4617<
4618    __is_val_expr<_Expr>::value,
4619    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
4620               __scalar_expr<typename _Expr::value_type>, _Expr> >
4621>::type
4622pow(const typename _Expr::value_type& __x, const _Expr& __y)
4623{
4624    typedef typename _Expr::value_type value_type;
4625    typedef _BinaryOp<__pow_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;
4626    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
4627                           __scalar_expr<value_type>(__x, __y.size()), __y));
4628}
4629
4630template<class _Expr>
4631inline _LIBCPP_ALWAYS_INLINE
4632typename enable_if
4633<
4634    __is_val_expr<_Expr>::value,
4635    __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
4636>::type
4637sin(const _Expr& __x)
4638{
4639    typedef typename _Expr::value_type value_type;
4640    typedef _UnaryOp<__sin_expr<value_type>, _Expr> _Op;
4641    return __val_expr<_Op>(_Op(__sin_expr<value_type>(), __x));
4642}
4643
4644template<class _Expr>
4645inline _LIBCPP_ALWAYS_INLINE
4646typename enable_if
4647<
4648    __is_val_expr<_Expr>::value,
4649    __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
4650>::type
4651sinh(const _Expr& __x)
4652{
4653    typedef typename _Expr::value_type value_type;
4654    typedef _UnaryOp<__sinh_expr<value_type>, _Expr> _Op;
4655    return __val_expr<_Op>(_Op(__sinh_expr<value_type>(), __x));
4656}
4657
4658template<class _Expr>
4659inline _LIBCPP_ALWAYS_INLINE
4660typename enable_if
4661<
4662    __is_val_expr<_Expr>::value,
4663    __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
4664>::type
4665sqrt(const _Expr& __x)
4666{
4667    typedef typename _Expr::value_type value_type;
4668    typedef _UnaryOp<__sqrt_expr<value_type>, _Expr> _Op;
4669    return __val_expr<_Op>(_Op(__sqrt_expr<value_type>(), __x));
4670}
4671
4672template<class _Expr>
4673inline _LIBCPP_ALWAYS_INLINE
4674typename enable_if
4675<
4676    __is_val_expr<_Expr>::value,
4677    __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
4678>::type
4679tan(const _Expr& __x)
4680{
4681    typedef typename _Expr::value_type value_type;
4682    typedef _UnaryOp<__tan_expr<value_type>, _Expr> _Op;
4683    return __val_expr<_Op>(_Op(__tan_expr<value_type>(), __x));
4684}
4685
4686template<class _Expr>
4687inline _LIBCPP_ALWAYS_INLINE
4688typename enable_if
4689<
4690    __is_val_expr<_Expr>::value,
4691    __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
4692>::type
4693tanh(const _Expr& __x)
4694{
4695    typedef typename _Expr::value_type value_type;
4696    typedef _UnaryOp<__tanh_expr<value_type>, _Expr> _Op;
4697    return __val_expr<_Op>(_Op(__tanh_expr<value_type>(), __x));
4698}
4699
4700template <class _Tp>
4701inline _LIBCPP_ALWAYS_INLINE
4702_Tp*
4703begin(valarray<_Tp>& __v)
4704{
4705    return __v.__begin_;
4706}
4707
4708template <class _Tp>
4709inline _LIBCPP_ALWAYS_INLINE
4710const _Tp*
4711begin(const valarray<_Tp>& __v)
4712{
4713    return __v.__begin_;
4714}
4715
4716template <class _Tp>
4717inline _LIBCPP_ALWAYS_INLINE
4718_Tp*
4719end(valarray<_Tp>& __v)
4720{
4721    return __v.__end_;
4722}
4723
4724template <class _Tp>
4725inline _LIBCPP_ALWAYS_INLINE
4726const _Tp*
4727end(const valarray<_Tp>& __v)
4728{
4729    return __v.__end_;
4730}
4731
4732extern template valarray<size_t>::valarray(size_t);
4733extern template valarray<size_t>::~valarray();
4734extern template void valarray<size_t>::resize(size_t, size_t);
4735
4736_LIBCPP_END_NAMESPACE_STD
4737
4738#endif  // _LIBCPP_VALARRAY
4739