[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();}