[libc++] Fix result-type and value_type computation in <valarray>.
The `operator[]` of `_UnaryOp` and `_BinaryOp` returns the result of
calling `__op_`, so its return type should be `__result_type`, not
e.g. `_A0::value_type`. However, `_UnaryOp::value_type` also should
never have been `_A0::value_type`; it needs to be the correct type
for the result of the unary op, e.g. `bool` when the op is `logical_not`.
This turns out to matter when multiple operators are nested, e.g.
`+(v == v)` needs to have a `value_type` of `bool`, not `int`,
even when `v` is of type `valarray<int>`.
Differential Revision: https://reviews.llvm.org/D103416
NOKEYCHECK=True
GitOrigin-RevId: 469d18c06446259aaaa8ec57f1548b1a42691512
diff --git a/include/valarray b/include/valarray
index 1eb25fd..6e25514 100644
--- a/include/valarray
+++ b/include/valarray
@@ -413,7 +413,7 @@
struct _UnaryOp
{
typedef typename _Op::__result_type __result_type;
- typedef typename _A0::value_type value_type;
+ typedef typename decay<__result_type>::type value_type;
_Op __op_;
_A0 __a0_;
@@ -432,7 +432,7 @@
struct _BinaryOp
{
typedef typename _Op::__result_type __result_type;
- typedef typename _A0::value_type value_type;
+ typedef typename decay<__result_type>::type value_type;
_Op __op_;
_A0 __a0_;
@@ -443,7 +443,7 @@
: __op_(__op), __a0_(__a0), __a1_(__a1) {}
_LIBCPP_INLINE_VISIBILITY
- value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+ __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
_LIBCPP_INLINE_VISIBILITY
size_t size() const {return __a0_.size();}
@@ -1087,7 +1087,7 @@
struct _UnaryOp<_Op, valarray<_Tp> >
{
typedef typename _Op::__result_type __result_type;
- typedef _Tp value_type;
+ typedef typename decay<__result_type>::type value_type;
_Op __op_;
const valarray<_Tp>& __a0_;
@@ -1106,7 +1106,7 @@
struct _BinaryOp<_Op, valarray<_Tp>, _A1>
{
typedef typename _Op::__result_type __result_type;
- typedef _Tp value_type;
+ typedef typename decay<__result_type>::type value_type;
_Op __op_;
const valarray<_Tp>& __a0_;
@@ -1117,7 +1117,7 @@
: __op_(__op), __a0_(__a0), __a1_(__a1) {}
_LIBCPP_INLINE_VISIBILITY
- value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+ __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
_LIBCPP_INLINE_VISIBILITY
size_t size() const {return __a0_.size();}
@@ -1127,7 +1127,7 @@
struct _BinaryOp<_Op, _A0, valarray<_Tp> >
{
typedef typename _Op::__result_type __result_type;
- typedef _Tp value_type;
+ typedef typename decay<__result_type>::type value_type;
_Op __op_;
_A0 __a0_;
@@ -1138,7 +1138,7 @@
: __op_(__op), __a0_(__a0), __a1_(__a1) {}
_LIBCPP_INLINE_VISIBILITY
- value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+ __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
_LIBCPP_INLINE_VISIBILITY
size_t size() const {return __a0_.size();}
@@ -1148,7 +1148,7 @@
struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
{
typedef typename _Op::__result_type __result_type;
- typedef _Tp value_type;
+ typedef typename decay<__result_type>::type value_type;
_Op __op_;
const valarray<_Tp>& __a0_;
@@ -1159,7 +1159,7 @@
: __op_(__op), __a0_(__a0), __a1_(__a1) {}
_LIBCPP_INLINE_VISIBILITY
- value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+ __result_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
_LIBCPP_INLINE_VISIBILITY
size_t size() const {return __a0_.size();}