petpav01 updated this revision to Diff 42506.
petpav01 added a comment.

Updated patch adds more tests and fixes a problem introduced in the previous 
revision where templates taking `__val_expr` were not correctly protected by 
SFINAE from immediate context (it introduced same problem with explicit 
template parameters that I am trying to solve).

@Eric: Could you please send me an example that shows the problem with the 
ranking in overload resolution so I can add a test for it too? I would like to 
understand this case because if it is not needed then a number of `atan2()` and 
`pow()` templates can be reduced (to the same amount as in the original patch).


http://reviews.llvm.org/D13289

Files:
  include/valarray
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp
  
test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp

Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-7.1629787019902447e-01,
+              -4.6211715726000974e-01,
+               0.0000000000000000e+00,
+               4.6211715726000974e-01,
+               6.3514895238728730e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-7.1629787019902447e-01,
-                  -4.6211715726000974e-01,
-                   0.0000000000000000e+00,
-                   4.6211715726000974e-01,
-                   6.3514895238728730e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // tanh(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = tanh(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // tanh(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = tanh(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // tanh<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::tanh<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-1.2601582175503390e+00,
+              -5.4630248984379048e-01,
+               0.0000000000000000e+00,
+               5.4630248984379048e-01,
+               9.3159645994407259e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-1.2601582175503390e+00,
-                  -5.4630248984379048e-01,
-                   0.0000000000000000e+00,
-                   5.4630248984379048e-01,
-                   9.3159645994407259e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // tan(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = tan(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // tan(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = tan(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // tan<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::tan<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {.5, .75, 1, 3, 7};
+    T a3[] = {7.0710678118654757e-01,
+              8.6602540378443860e-01,
+              1.0000000000000000e+00,
+              1.7320508075688772e+00,
+              2.6457513110645907e+00};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {.5, .75, 1, 3, 7};
-        T a3[] = {7.0710678118654757e-01,
-                  8.6602540378443860e-01,
-                  1.0000000000000000e+00,
-                  1.7320508075688772e+00,
-                  2.6457513110645907e+00};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // sqrt(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = sqrt(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // sqrt(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = sqrt(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // sqrt<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::sqrt<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-1.0265167257081753e+00,
+              -5.2109530549374738e-01,
+               0.0000000000000000e+00,
+               5.2109530549374738e-01,
+               8.2231673193582999e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-1.0265167257081753e+00,
-                  -5.2109530549374738e-01,
-                   0.0000000000000000e+00,
-                   5.2109530549374738e-01,
-                   8.2231673193582999e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // sinh(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = sinh(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // sinh(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = sinh(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // sinh<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::sinh<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-7.8332690962748330e-01,
+              -4.7942553860420301e-01,
+               0.0000000000000000e+00,
+               4.7942553860420301e-01,
+               6.8163876002333423e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-7.8332690962748330e-01,
-                  -4.7942553860420301e-01,
-                   0.0000000000000000e+00,
-                   4.7942553860420301e-01,
-                   6.8163876002333423e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // sin(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = sin(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // sin(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = sin(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // sin<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::sin<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {.9, .5, 0., .5, .75};
+    T a3[] = {1.8660659830736148e+00,
+              1.4142135623730951e+00,
+              1.0000000000000000e+00,
+              1.4142135623730951e+00,
+              1.6817928305074290e+00};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {.9, .5, 0., .5, .75};
-        T a3[] = {1.8660659830736148e+00,
-                  1.4142135623730951e+00,
-                  1.0000000000000000e+00,
-                  1.4142135623730951e+00,
-                  1.6817928305074290e+00};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // pow(T, valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = pow(2.0, v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // pow(T, __val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = pow(2.0, v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // pow<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::pow<T>(2.0, v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {.9, .5, 0., .5, .75};
+    T a3[] = {8.1000000000000005e-01,
+              2.5000000000000000e-01,
+              0.0000000000000000e+00,
+              2.5000000000000000e-01,
+              5.6250000000000000e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {.9, .5, 0., .5, .75};
-        T a3[] = {8.1000000000000005e-01,
-                  2.5000000000000000e-01,
-                  0.0000000000000000e+00,
-                  2.5000000000000000e-01,
-                  5.6250000000000000e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // pow(valarray&, T)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = pow(v1, 2.0);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // pow(__val_expr&, T)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = pow(v1 + 0.0, 2.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // pow<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::pow<T>(v1, 2.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp
@@ -33,21 +33,58 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {.9, .5, 0., .5, .75};
+    T a2[] = {-.8,  .25, 0.375, -.5, .75};
+    T a3[] = {1.0879426248455297e+00,
+              8.4089641525371450e-01,
+              0.0000000000000000e+00,
+              1.4142135623730949e+00,
+              8.0592744886765644e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {.9, .5, 0., .5, .75};
-        T a2[] = {-.8,  .25, 0.375, -.5, .75};
-        T a3[] = {1.0879426248455297e+00,
-                  8.4089641525371450e-01,
-                  0.0000000000000000e+00,
-                  1.4142135623730949e+00,
-                  8.0592744886765644e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // pow(valarray&, valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v2(a2, N);
         std::valarray<T> v3 = pow(v1, v2);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // pow(valarray&, __val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = pow(v1, v2 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // pow(__val_expr&, valarray&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = pow(v1 + 0.0, v2);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // pow(__val_expr&, __val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = pow(v1 + 0.0, v2 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // pow<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = std::pow<T>(v1, v2);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {.5, .75, 1, 3, 7};
+    T a3[] = {-6.9314718055994529e-01,
+              -2.8768207245178090e-01,
+               0.0000000000000000e+00,
+               1.0986122886681098e+00,
+               1.9459101490553132e+00};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {.5, .75, 1, 3, 7};
-        T a3[] = {-6.9314718055994529e-01,
-                  -2.8768207245178090e-01,
-                   0.0000000000000000e+00,
-                   1.0986122886681098e+00,
-                   1.9459101490553132e+00};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // log(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = log(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // log(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = log(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // log<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::log<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {.5, .75, 1, 3, 7};
+    T a3[] = {-3.0102999566398120e-01,
+              -1.2493873660829995e-01,
+               0.0000000000000000e+00,
+               4.7712125471966244e-01,
+               8.4509804001425681e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {.5, .75, 1, 3, 7};
-        T a3[] = {-3.0102999566398120e-01,
-                  -1.2493873660829995e-01,
-                   0.0000000000000000e+00,
-                   4.7712125471966244e-01,
-                   8.4509804001425681e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // log10(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = log10(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // log10(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = log10(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // log10<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::log10<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {4.0656965974059911e-01,
+              6.0653065971263342e-01,
+              1.0000000000000000e+00,
+              1.6487212707001282e+00,
+              2.1170000166126748e+00};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {4.0656965974059911e-01,
-                  6.0653065971263342e-01,
-                  1.0000000000000000e+00,
-                  1.6487212707001282e+00,
-                  2.1170000166126748e+00};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // exp(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = exp(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // exp(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = exp(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // exp<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::exp<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {1.4330863854487743e+00,
+              1.1276259652063807e+00,
+              1.0000000000000000e+00,
+              1.1276259652063807e+00,
+              1.2946832846768448e+00};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {1.4330863854487743e+00,
-                  1.1276259652063807e+00,
-                  1.0000000000000000e+00,
-                  1.1276259652063807e+00,
-                  1.2946832846768448e+00};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // cosh(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = cosh(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // cosh(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = cosh(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // cosh<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::cosh<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {6.2160996827066450e-01,
+              8.7758256189037276e-01,
+              1.0000000000000000e+00,
+              8.7758256189037276e-01,
+              7.3168886887382090e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {6.2160996827066450e-01,
-                  8.7758256189037276e-01,
-                  1.0000000000000000e+00,
-                  8.7758256189037276e-01,
-                  7.3168886887382090e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // cos(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = cos(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // cos(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = cos(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // cos<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::cos<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-7.3281510178650666e-01,
+              -4.6364760900080615e-01,
+               0.0000000000000000e+00,
+               4.6364760900080615e-01,
+               6.4350110879328437e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-7.3281510178650666e-01,
-                  -4.6364760900080615e-01,
-                   0.0000000000000000e+00,
-                   4.6364760900080615e-01,
-                   6.4350110879328437e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // atan(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = atan(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // atan(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = atan(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // atan<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::atan<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {2.4468543773930902e+00,
+              2.1587989303424640e+00,
+              1.5707963267948966e+00,
+              9.8279372324732905e-01,
+              7.8539816339744828e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {2.4468543773930902e+00,
-                  2.1587989303424640e+00,
-                  1.5707963267948966e+00,
-                  9.8279372324732905e-01,
-                  7.8539816339744828e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // atan2(T, valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = atan2(.75, v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // atan2(T, __val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = atan2(.75, v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // atan2<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::atan2<T>(.75, v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-8.7605805059819342e-01,
+              -5.8800260354756750e-01,
+               0.0000000000000000e+00,
+               5.8800260354756750e-01,
+               7.8539816339744828e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-8.7605805059819342e-01,
-                  -5.8800260354756750e-01,
-                   0.0000000000000000e+00,
-                   5.8800260354756750e-01,
-                   7.8539816339744828e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // atan2(valarray&, T)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = atan2(v1, .75);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // atan2(__val_expr&, T)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = atan2(v1 + 0.0, .75);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // atan2<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::atan2<T>(v1, .75);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp
@@ -33,21 +33,58 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a2[] = {-.8,  .25, 0.375, -.5, .75};
+    T a3[] = {-2.2974386674766221e+00,
+              -1.1071487177940904e+00,
+               0.0000000000000000e+00,
+               2.3561944901923448e+00,
+               7.8539816339744828e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a2[] = {-.8,  .25, 0.375, -.5, .75};
-        T a3[] = {-2.2974386674766221e+00,
-                  -1.1071487177940904e+00,
-                   0.0000000000000000e+00,
-                   2.3561944901923448e+00,
-                   7.8539816339744828e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // atan2(valarray&, valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v2(a2, N);
         std::valarray<T> v3 = atan2(v1, v2);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // atan2(valarray&, __val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = atan2(v1, v2 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // atan2(__val_expr&, valarray&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = atan2(v1 + 0.0, v2);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // atan2(__val_expr&, __val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = atan2(v1 + 0.0, v2 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // atan2<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v2(a2, N);
+        std::valarray<T> v3 = std::atan2<T>(v1, v2);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {-1.1197695149986342e+00,
+              -5.2359877559829882e-01,
+              0.0000000000000000e+00,
+              5.2359877559829882e-01,
+              8.4806207898148100e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {-1.1197695149986342e+00,
-                  -5.2359877559829882e-01,
-                  0.0000000000000000e+00,
-                  5.2359877559829882e-01,
-                  8.4806207898148100e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // asin(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = asin(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // asin(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = asin(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // asin<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::asin<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp
@@ -33,19 +33,36 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {-.9, -.5, 0., .5, .75};
+    T a3[] = {2.6905658417935308e+00,
+              2.0943951023931957e+00,
+              1.5707963267948966e+00,
+              1.0471975511965976e+00,
+              7.2273424781341566e-01};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {-.9, -.5, 0., .5, .75};
-        T a3[] = {2.6905658417935308e+00,
-                  2.0943951023931957e+00,
-                  1.5707963267948966e+00,
-                  1.0471975511965976e+00,
-                  7.2273424781341566e-01};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // acos(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = acos(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(is_about(v3[i], a3[i], 10));
     }
+    {
+        // acos(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = acos(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
+    {
+        // acos<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::acos<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(is_about(v3[i], a3[i], 10));
+    }
 }
Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp
===================================================================
--- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp
+++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp
@@ -20,15 +20,32 @@
 
 int main()
 {
+    typedef double T;
+    T a1[] = {1.5,  -2.5,  3.4,  -4.5,  -5.0};
+    T a3[] = {1.5,   2.5,  3.4,   4.5,   5.0};
+    const unsigned N = sizeof(a1)/sizeof(a1[0]);
     {
-        typedef double T;
-        T a1[] = {1.5,  -2.5,  3.4,  -4.5,  -5.0};
-        T a3[] = {1.5,   2.5,  3.4,   4.5,   5.0};
-        const unsigned N = sizeof(a1)/sizeof(a1[0]);
+        // abs(valarray&)
         std::valarray<T> v1(a1, N);
         std::valarray<T> v3 = abs(v1);
         assert(v3.size() == v1.size());
         for (int i = 0; i < v3.size(); ++i)
             assert(v3[i] == a3[i]);
     }
+    {
+        // abs(__val_expr&)
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = abs(v1 + 0.0);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(v3[i] == a3[i]);
+    }
+    {
+        // abs<T>()
+        std::valarray<T> v1(a1, N);
+        std::valarray<T> v3 = std::abs<T>(v1);
+        assert(v3.size() == v1.size());
+        for (int i = 0; i < v3.size(); ++i)
+            assert(v3[i] == a3[i]);
+    }
 }
Index: include/valarray
===================================================================
--- include/valarray
+++ include/valarray
@@ -787,6 +787,12 @@
 template<class _Tp>
 struct __is_val_expr<valarray<_Tp> > : true_type {};
 
+template<class _ValExpr>
+struct __is_val_expr_only : false_type {};
+
+template<class _ValExpr>
+struct __is_val_expr_only<__val_expr<_ValExpr> > : true_type {};
+
 template<class _Tp>
 class _LIBCPP_TYPE_VIS_ONLY valarray
 {
@@ -4560,7 +4566,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
 >::type
 abs(const _Expr& __x)
@@ -4570,11 +4576,20 @@
     return __val_expr<_Op>(_Op(__abs_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__abs_expr<_Tp>, valarray<_Tp> > >
+abs(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__abs_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__abs_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
 >::type
 acos(const _Expr& __x)
@@ -4584,11 +4599,20 @@
     return __val_expr<_Op>(_Op(__acos_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__acos_expr<_Tp>, valarray<_Tp> > >
+acos(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__acos_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__acos_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
 >::type
 asin(const _Expr& __x)
@@ -4598,11 +4622,20 @@
     return __val_expr<_Op>(_Op(__asin_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__asin_expr<_Tp>, valarray<_Tp> > >
+asin(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__asin_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__asin_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
 >::type
 atan(const _Expr& __x)
@@ -4612,11 +4645,21 @@
     return __val_expr<_Op>(_Op(__atan_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__atan_expr<_Tp>, valarray<_Tp> > >
+atan(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__atan_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__atan_expr<_Tp>(), __x));
+}
+
 template<class _Expr1, class _Expr2>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __is_val_expr_only<_Expr1>::value && __is_val_expr_only<_Expr2>::value &&
+    is_same<typename _Expr1::value_type, typename _Expr2::value_type>::value,
     __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
 >::type
 atan2(const _Expr1& __x, const _Expr2& __y)
@@ -4626,11 +4669,48 @@
     return __val_expr<_Op>(_Op(__atan2_expr<value_type>(), __x, __y));
 }
 
+template<class _Expr, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr_only<_Expr>::value &&
+    is_same<typename _Expr::value_type, _Tp>::value,
+    __val_expr<_BinaryOp<__atan2_expr<_Tp>, _Expr, valarray<_Tp> > >
+>::type
+atan2(const _Expr& __x, const valarray<_Tp>& __y)
+{
+    typedef _BinaryOp<__atan2_expr<_Tp>, _Expr, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<_Tp>(), __x, __y));
+}
+
+template<class _Tp, class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr_only<_Expr>::value &&
+    is_same<_Tp, typename _Expr::value_type>::value,
+    __val_expr<_BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>, _Expr> >
+>::type
+atan2(const valarray<_Tp>& __x, const _Expr& __y)
+{
+    typedef _BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<_Tp>(), __x, __y));
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>, valarray<_Tp> > >
+atan2(const valarray<_Tp>& __x, const valarray<_Tp>& __y)
+{
+    typedef _BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<_Tp>(), __x, __y));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
                _Expr, __scalar_expr<typename _Expr::value_type> > >
 >::type
@@ -4642,11 +4722,21 @@
                            __x, __scalar_expr<value_type>(__y, __x.size())));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>, __scalar_expr<_Tp> > >
+atan2(const valarray<_Tp>& __x, const _Tp& __y)
+{
+    typedef _BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>, __scalar_expr<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<_Tp>(),
+                           __x, __scalar_expr<_Tp>(__y, __x.size())));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
                __scalar_expr<typename _Expr::value_type>, _Expr> >
 >::type
@@ -4658,11 +4748,21 @@
                            __scalar_expr<value_type>(__x, __y.size()), __y));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__atan2_expr<_Tp>, __scalar_expr<_Tp>, valarray<_Tp> > >
+atan2(const _Tp& __x, const valarray<_Tp>& __y)
+{
+    typedef _BinaryOp<__atan2_expr<_Tp>, __scalar_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<_Tp>(),
+                           __scalar_expr<_Tp>(__x, __y.size()), __y));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
 >::type
 cos(const _Expr& __x)
@@ -4672,11 +4772,20 @@
     return __val_expr<_Op>(_Op(__cos_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__cos_expr<_Tp>, valarray<_Tp> > >
+cos(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__cos_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__cos_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
 >::type
 cosh(const _Expr& __x)
@@ -4686,11 +4795,20 @@
     return __val_expr<_Op>(_Op(__cosh_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__cosh_expr<_Tp>, valarray<_Tp> > >
+cosh(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__cosh_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__cosh_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
 >::type
 exp(const _Expr& __x)
@@ -4700,11 +4818,20 @@
     return __val_expr<_Op>(_Op(__exp_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__exp_expr<_Tp>, valarray<_Tp> > >
+exp(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__exp_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__exp_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
 >::type
 log(const _Expr& __x)
@@ -4714,11 +4841,20 @@
     return __val_expr<_Op>(_Op(__log_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__log_expr<_Tp>, valarray<_Tp> > >
+log(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__log_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__log_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
 >::type
 log10(const _Expr& __x)
@@ -4728,11 +4864,21 @@
     return __val_expr<_Op>(_Op(__log10_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__log10_expr<_Tp>, valarray<_Tp> > >
+log10(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__log10_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__log10_expr<_Tp>(), __x));
+}
+
 template<class _Expr1, class _Expr2>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __is_val_expr_only<_Expr1>::value && __is_val_expr_only<_Expr2>::value &&
+    is_same<typename _Expr1::value_type, typename _Expr2::value_type>::value,
     __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
 >::type
 pow(const _Expr1& __x, const _Expr2& __y)
@@ -4742,11 +4888,48 @@
     return __val_expr<_Op>(_Op(__pow_expr<value_type>(), __x, __y));
 }
 
+template<class _Expr, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr_only<_Expr>::value &&
+    is_same<typename _Expr::value_type, _Tp>::value,
+    __val_expr<_BinaryOp<__pow_expr<_Tp>, _Expr, valarray<_Tp> > >
+>::type
+pow(const _Expr& __x, const valarray<_Tp>& __y)
+{
+    typedef _BinaryOp<__pow_expr<_Tp>, _Expr, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<_Tp>(), __x, __y));
+}
+
+template<class _Tp, class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr_only<_Expr>::value &&
+    is_same<_Tp, typename _Expr::value_type>::value,
+    __val_expr<_BinaryOp<__pow_expr<_Tp>, valarray<_Tp>, _Expr> >
+>::type
+pow(const valarray<_Tp>& __x, const _Expr& __y)
+{
+    typedef _BinaryOp<__pow_expr<_Tp>, valarray<_Tp>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<_Tp>(), __x, __y));
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__pow_expr<_Tp>, valarray<_Tp>, valarray<_Tp> > >
+pow(const valarray<_Tp>& __x, const valarray<_Tp>& __y)
+{
+    typedef _BinaryOp<__pow_expr<_Tp>, valarray<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<_Tp>(), __x, __y));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
                _Expr, __scalar_expr<typename _Expr::value_type> > >
 >::type
@@ -4758,11 +4941,21 @@
                            __x, __scalar_expr<value_type>(__y, __x.size())));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__pow_expr<_Tp>, valarray<_Tp>, __scalar_expr<_Tp> > >
+pow(const valarray<_Tp>& __x, const _Tp& __y)
+{
+    typedef _BinaryOp<__pow_expr<_Tp>, valarray<_Tp>, __scalar_expr<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<_Tp>(),
+                           __x, __scalar_expr<_Tp>(__y, __x.size())));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
                __scalar_expr<typename _Expr::value_type>, _Expr> >
 >::type
@@ -4774,11 +4967,21 @@
                            __scalar_expr<value_type>(__x, __y.size()), __y));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__pow_expr<_Tp>, __scalar_expr<_Tp>, valarray<_Tp> > >
+pow(const _Tp& __x, const valarray<_Tp>& __y)
+{
+    typedef _BinaryOp<__pow_expr<_Tp>, __scalar_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<_Tp>(),
+                           __scalar_expr<_Tp>(__x, __y.size()), __y));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
 >::type
 sin(const _Expr& __x)
@@ -4788,11 +4991,20 @@
     return __val_expr<_Op>(_Op(__sin_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__sin_expr<_Tp>, valarray<_Tp> > >
+sin(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__sin_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__sin_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
 >::type
 sinh(const _Expr& __x)
@@ -4802,11 +5014,20 @@
     return __val_expr<_Op>(_Op(__sinh_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__sinh_expr<_Tp>, valarray<_Tp> > >
+sinh(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__sinh_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__sinh_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
 >::type
 sqrt(const _Expr& __x)
@@ -4816,11 +5037,19 @@
     return __val_expr<_Op>(_Op(__sqrt_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__sqrt_expr<_Tp>, valarray<_Tp> > >
+sqrt(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__sqrt_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__sqrt_expr<_Tp>(), __x));
+}
+
+template<class _Expr>
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
 >::type
 tan(const _Expr& __x)
@@ -4830,11 +5059,20 @@
     return __val_expr<_Op>(_Op(__tan_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__tan_expr<_Tp>, valarray<_Tp> > >
+tan(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__tan_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__tan_expr<_Tp>(), __x));
+}
+
 template<class _Expr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
+    __is_val_expr_only<_Expr>::value,
     __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
 >::type
 tanh(const _Expr& __x)
@@ -4844,6 +5082,15 @@
     return __val_expr<_Op>(_Op(__tanh_expr<value_type>(), __x));
 }
 
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__tanh_expr<_Tp>, valarray<_Tp> > >
+tanh(const valarray<_Tp>& __x)
+{
+    typedef _UnaryOp<__tanh_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__tanh_expr<_Tp>(), __x));
+}
+
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 _Tp*
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to