@@ -733,6 +733,50 @@ struct __is_val_expr<__val_expr<_ValExpr> > : true_type {};
733
733
template <class _Tp >
734
734
struct __is_val_expr <valarray<_Tp> > : true_type {};
735
735
736
+ template <class _Tp >
737
+ struct __is_val_expr <slice_array<_Tp> > : true_type {};
738
+
739
+ template <class _Tp >
740
+ struct __is_val_expr <gslice_array<_Tp> > : true_type {};
741
+
742
+ template <class _Tp >
743
+ struct __is_val_expr <mask_array<_Tp> > : true_type {};
744
+
745
+ template <class _Tp >
746
+ struct __is_val_expr <indirect_array<_Tp> > : true_type {};
747
+
748
+ // The functions using a __val_expr access the elements by their index.
749
+ // valarray and the libc++ lazy proxies have an operator[]. The
750
+ // Standard proxy array's don't have this operator, instead they have a
751
+ // implementation specific accessor
752
+ // __get(size_t)
753
+ //
754
+ // The functions use the non-member function
755
+ // __get(__val_expr, size_t)
756
+ //
757
+ // If the __val_expr is a specialization of __val_expr_use_member_functions it
758
+ // uses the __val_expr's member function
759
+ // __get(size_t)
760
+ // else it uses the __val_expr's member function
761
+ // operator[](size_t)
762
+ template <class _ValExpr >
763
+ struct __val_expr_use_member_functions ;
764
+
765
+ template <class >
766
+ struct __val_expr_use_member_functions : false_type {};
767
+
768
+ template <class _Tp >
769
+ struct __val_expr_use_member_functions <slice_array<_Tp> > : true_type {};
770
+
771
+ template <class _Tp >
772
+ struct __val_expr_use_member_functions <gslice_array<_Tp> > : true_type {};
773
+
774
+ template <class _Tp >
775
+ struct __val_expr_use_member_functions <mask_array<_Tp> > : true_type {};
776
+
777
+ template <class _Tp >
778
+ struct __val_expr_use_member_functions <indirect_array<_Tp> > : true_type {};
779
+
736
780
template <class _Tp >
737
781
class _LIBCPP_TEMPLATE_VIS valarray {
738
782
public:
@@ -903,6 +947,18 @@ template <class _Tp, size_t _Size>
903
947
valarray (const _Tp (&)[_Size], size_t) -> valarray<_Tp>;
904
948
#endif
905
949
950
+ template <class _Expr ,
951
+ __enable_if_t <__is_val_expr<_Expr>::value && __val_expr_use_member_functions<_Expr>::value, int > = 0 >
952
+ _LIBCPP_HIDE_FROM_ABI typename _Expr::value_type __get (const _Expr& __v, size_t __i) {
953
+ return __v.__get (__i);
954
+ }
955
+
956
+ template <class _Expr ,
957
+ __enable_if_t <__is_val_expr<_Expr>::value && !__val_expr_use_member_functions<_Expr>::value, int > = 0 >
958
+ _LIBCPP_HIDE_FROM_ABI typename _Expr::value_type __get (const _Expr& __v, size_t __i) {
959
+ return __v[__i];
960
+ }
961
+
906
962
extern template _LIBCPP_EXPORTED_FROM_ABI void valarray<size_t >::resize(size_t , size_t );
907
963
908
964
template <class _Op , class _Tp >
@@ -1025,6 +1081,12 @@ public:
1025
1081
1026
1082
_LIBCPP_HIDE_FROM_ABI void operator =(const valarray<value_type>& __va) const ;
1027
1083
1084
+ // Behaves like __val_expr::operator[], which returns by value.
1085
+ _LIBCPP_HIDE_FROM_ABI value_type __get (size_t __i) const {
1086
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (__i < __size_, " slice_array.__get() index out of bounds" );
1087
+ return __vp_[__i * __stride_];
1088
+ }
1089
+
1028
1090
private:
1029
1091
_LIBCPP_HIDE_FROM_ABI slice_array (const slice& __sl, const valarray<value_type>& __v)
1030
1092
: __vp_(const_cast <value_type*>(__v.__begin_ + __sl.start())), __size_(__sl.size()), __stride_(__sl.stride()) {}
@@ -1246,6 +1308,12 @@ public:
1246
1308
1247
1309
gslice_array (const gslice_array&) = default ;
1248
1310
1311
+ // Behaves like __val_expr::operator[], which returns by value.
1312
+ _LIBCPP_HIDE_FROM_ABI value_type __get (size_t __i) const {
1313
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (__i < __1d_.size (), " gslice_array.__get() index out of bounds" );
1314
+ return __vp_[__1d_[__i]];
1315
+ }
1316
+
1249
1317
private:
1250
1318
gslice_array (const gslice& __gs, const valarray<value_type>& __v)
1251
1319
: __vp_(const_cast <value_type*>(__v.__begin_)), __1d_(__gs.__1d_) {}
@@ -1425,6 +1493,12 @@ public:
1425
1493
1426
1494
_LIBCPP_HIDE_FROM_ABI void operator =(const value_type& __x) const ;
1427
1495
1496
+ // Behaves like __val_expr::operator[], which returns by value.
1497
+ _LIBCPP_HIDE_FROM_ABI value_type __get (size_t __i) const {
1498
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (__i < __1d_.size (), " mask_array.__get() index out of bounds" );
1499
+ return __vp_[__1d_[__i]];
1500
+ }
1501
+
1428
1502
private:
1429
1503
_LIBCPP_HIDE_FROM_ABI mask_array (const valarray<bool >& __vb, const valarray<value_type>& __v)
1430
1504
: __vp_(const_cast <value_type*>(__v.__begin_)),
@@ -1624,6 +1698,12 @@ public:
1624
1698
1625
1699
_LIBCPP_HIDE_FROM_ABI void operator =(const value_type& __x) const ;
1626
1700
1701
+ // Behaves like __val_expr::operator[], which returns by value.
1702
+ _LIBCPP_HIDE_FROM_ABI value_type __get (size_t __i) const {
1703
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (__i < __1d_.size (), " indirect_array.__get() index out of bounds" );
1704
+ return __vp_[__1d_[__i]];
1705
+ }
1706
+
1627
1707
private:
1628
1708
_LIBCPP_HIDE_FROM_ABI indirect_array (const valarray<size_t >& __ia, const valarray<value_type>& __v)
1629
1709
: __vp_(const_cast <value_type*>(__v.__begin_)), __1d_(__ia) {}
@@ -2355,7 +2435,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2355
2435
inline valarray<_Tp>& valarray<_Tp>::operator *=(const _Expr& __v) {
2356
2436
size_t __i = 0 ;
2357
2437
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2358
- *__t *= __v[ __i] ;
2438
+ *__t *= std::__get ( __v, __i) ;
2359
2439
return *this ;
2360
2440
}
2361
2441
@@ -2364,7 +2444,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2364
2444
inline valarray<_Tp>& valarray<_Tp>::operator /=(const _Expr& __v) {
2365
2445
size_t __i = 0 ;
2366
2446
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2367
- *__t /= __v[ __i] ;
2447
+ *__t /= std::__get ( __v, __i) ;
2368
2448
return *this ;
2369
2449
}
2370
2450
@@ -2373,7 +2453,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2373
2453
inline valarray<_Tp>& valarray<_Tp>::operator %=(const _Expr& __v) {
2374
2454
size_t __i = 0 ;
2375
2455
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2376
- *__t %= __v[ __i] ;
2456
+ *__t %= std::__get ( __v, __i) ;
2377
2457
return *this ;
2378
2458
}
2379
2459
@@ -2382,7 +2462,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2382
2462
inline valarray<_Tp>& valarray<_Tp>::operator +=(const _Expr& __v) {
2383
2463
size_t __i = 0 ;
2384
2464
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2385
- *__t += __v[ __i] ;
2465
+ *__t += std::__get ( __v, __i) ;
2386
2466
return *this ;
2387
2467
}
2388
2468
@@ -2391,7 +2471,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2391
2471
inline valarray<_Tp>& valarray<_Tp>::operator -=(const _Expr& __v) {
2392
2472
size_t __i = 0 ;
2393
2473
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2394
- *__t -= __v[ __i] ;
2474
+ *__t -= std::__get ( __v, __i) ;
2395
2475
return *this ;
2396
2476
}
2397
2477
@@ -2400,7 +2480,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2400
2480
inline valarray<_Tp>& valarray<_Tp>::operator ^=(const _Expr& __v) {
2401
2481
size_t __i = 0 ;
2402
2482
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2403
- *__t ^= __v[ __i] ;
2483
+ *__t ^= std::__get ( __v, __i) ;
2404
2484
return *this ;
2405
2485
}
2406
2486
@@ -2409,7 +2489,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2409
2489
inline valarray<_Tp>& valarray<_Tp>::operator |=(const _Expr& __v) {
2410
2490
size_t __i = 0 ;
2411
2491
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2412
- *__t |= __v[ __i] ;
2492
+ *__t |= std::__get ( __v, __i) ;
2413
2493
return *this ;
2414
2494
}
2415
2495
@@ -2418,7 +2498,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2418
2498
inline valarray<_Tp>& valarray<_Tp>::operator &=(const _Expr& __v) {
2419
2499
size_t __i = 0 ;
2420
2500
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2421
- *__t &= __v[ __i] ;
2501
+ *__t &= std::__get ( __v, __i) ;
2422
2502
return *this ;
2423
2503
}
2424
2504
@@ -2427,7 +2507,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2427
2507
inline valarray<_Tp>& valarray<_Tp>::operator <<=(const _Expr& __v) {
2428
2508
size_t __i = 0 ;
2429
2509
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2430
- *__t <<= __v[ __i] ;
2510
+ *__t <<= std::__get ( __v, __i) ;
2431
2511
return *this ;
2432
2512
}
2433
2513
@@ -2436,7 +2516,7 @@ template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> >
2436
2516
inline valarray<_Tp>& valarray<_Tp>::operator >>=(const _Expr& __v) {
2437
2517
size_t __i = 0 ;
2438
2518
for (value_type* __t = __begin_; __t != __end_; ++__t , ++__i)
2439
- *__t >>= __v[ __i] ;
2519
+ *__t >>= std::__get ( __v, __i) ;
2440
2520
return *this ;
2441
2521
}
2442
2522
0 commit comments