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

I am not sure if I understand the comment about [17.6.5.4] correctly. It is not 
clear to me how this part of the standard prevents the user from specifying 
explicit template parameters for standard functions. It seems odd that the 
standard would disallow, for example, to use `std::max<double>(1, 2.0)`.

New patch changes the transcendentals that accepted any `Expr` (i.e. `valarray` 
or `__val_expr`) to only accept `__val_expr`. In two cases (`atan2()` and 
`pow()`) the original template had to be split into four functions:

- `func(const __val_expr&, const __val_expr&)`
- `func(const __val_expr&, const valarray&)`
- `func(const valarray&, const __val_expr&)`
- `func(const valarray&, const valarray&)`

`is_same` checks on `value_type` of both operands are also added in these cases.

Missing thing is a better test coverage. The tests currently do not instantiate 
the `__val_expr` templates. I am working on this. 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?


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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,29 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,29 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,26 @@
 
 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]);
         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));
     }
+    {
+        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,22 @@
 
 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]);
         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]);
     }
+    {
+        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
@@ -4556,294 +4556,498 @@
                            __scalar_expr<value_type>(__x, __y.size()), __y));
 }
 
-template<class _Expr>
+template<class _ValExpr>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
->::type
-abs(const _Expr& __x)
+__val_expr<_UnaryOp<__abs_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+abs(const __val_expr<_ValExpr>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__abs_expr<value_type>, _Expr> _Op;
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__abs_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__abs_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
->::type
-acos(const _Expr& __x)
+__val_expr<_UnaryOp<__abs_expr<_Tp>, valarray<_Tp> > >
+abs(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__acos_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__abs_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__abs_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__acos_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+acos(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__acos_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__acos_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
->::type
-asin(const _Expr& __x)
+__val_expr<_UnaryOp<__acos_expr<_Tp>, valarray<_Tp> > >
+acos(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__asin_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__acos_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__acos_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__asin_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+asin(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__asin_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__asin_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
->::type
-atan(const _Expr& __x)
+__val_expr<_UnaryOp<__asin_expr<_Tp>, valarray<_Tp> > >
+asin(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__atan_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__asin_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__asin_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__atan_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+atan(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__atan_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__atan_expr<value_type>(), __x));
 }
 
-template<class _Expr1, class _Expr2>
+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 _ValExpr1, class _ValExpr2>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
-    __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
+    is_same<typename __val_expr<_ValExpr1>::value_type,
+            typename __val_expr<_ValExpr2>::value_type>::value,
+    __val_expr<_BinaryOp<__atan2_expr<typename __val_expr<_ValExpr1>::value_type>,
+                         __val_expr<_ValExpr1>, __val_expr<_ValExpr2> > >
 >::type
-atan2(const _Expr1& __x, const _Expr2& __y)
+atan2(const __val_expr<_ValExpr1>& __x, const __val_expr<_ValExpr2>& __y)
 {
-    typedef typename _Expr1::value_type value_type;
-    typedef _BinaryOp<__atan2_expr<value_type>, _Expr1, _Expr2> _Op;
+    typedef typename __val_expr<_ValExpr1>::value_type value_type;
+    typedef _BinaryOp<__atan2_expr<value_type>, __val_expr<_ValExpr1>,
+                      __val_expr<_ValExpr2> > _Op;
     return __val_expr<_Op>(_Op(__atan2_expr<value_type>(), __x, __y));
 }
 
-template<class _Expr>
+template<class _ValExpr, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
-    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
-               _Expr, __scalar_expr<typename _Expr::value_type> > >
+    is_same<typename __val_expr<_ValExpr>::value_type, _Tp>::value,
+    __val_expr<_BinaryOp<__atan2_expr<_Tp>, __val_expr<_ValExpr>,
+                         valarray<_Tp> > >
 >::type
-atan2(const _Expr& __x, const typename _Expr::value_type& __y)
+atan2(const __val_expr<_ValExpr>& __x, const valarray<_Tp>& __y)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _BinaryOp<__atan2_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;
-    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
-                           __x, __scalar_expr<value_type>(__y, __x.size())));
+    typedef _BinaryOp<__atan2_expr<_Tp>, __val_expr<_ValExpr>,
+                      valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<_Tp>(), __x, __y));
 }
 
-template<class _Expr>
+template<class _Tp, class _ValExpr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
-    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
-               __scalar_expr<typename _Expr::value_type>, _Expr> >
+    is_same<_Tp, typename __val_expr<_ValExpr>::value_type>::value,
+    __val_expr<_BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>,
+                         __val_expr<_ValExpr> > >
 >::type
-atan2(const typename _Expr::value_type& __x, const _Expr& __y)
+atan2(const valarray<_Tp>& __x, const __val_expr<_ValExpr>& __y)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _BinaryOp<__atan2_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    typedef _BinaryOp<__atan2_expr<_Tp>, valarray<_Tp>,
+                      __val_expr<_ValExpr> > _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 _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__atan2_expr<typename __val_expr<_ValExpr>::value_type>,
+                     __val_expr<_ValExpr>,
+                     __scalar_expr<typename __val_expr<_ValExpr>::value_type> > >
+atan2(const __val_expr<_ValExpr>& __x,
+      const typename __val_expr<_ValExpr>::value_type& __y)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _BinaryOp<__atan2_expr<value_type>, __val_expr<_ValExpr>,
+                      __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
+                           __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 _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__atan2_expr<typename __val_expr<_ValExpr>::value_type>,
+                     __scalar_expr<typename __val_expr<_ValExpr>::value_type>,
+                     __val_expr<_ValExpr> > >
+atan2(const typename __val_expr<_ValExpr>::value_type& __x,
+      const __val_expr<_ValExpr>& __y)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _BinaryOp<__atan2_expr<value_type>, __scalar_expr<value_type>,
+                      __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
                            __scalar_expr<value_type>(__x, __y.size()), __y));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
->::type
-cos(const _Expr& __x)
+__val_expr<_BinaryOp<__atan2_expr<_Tp>, __scalar_expr<_Tp>, valarray<_Tp> > >
+atan2(const _Tp& __x, const valarray<_Tp>& __y)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__cos_expr<value_type>, _Expr> _Op;
+    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 _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__cos_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+cos(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__cos_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__cos_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
->::type
-cosh(const _Expr& __x)
+__val_expr<_UnaryOp<__cos_expr<_Tp>, valarray<_Tp> > >
+cos(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__cosh_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__cos_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__cos_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__cosh_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+cosh(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__cosh_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__cosh_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
->::type
-exp(const _Expr& __x)
+__val_expr<_UnaryOp<__cosh_expr<_Tp>, valarray<_Tp> > >
+cosh(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__exp_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__cosh_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__cosh_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__exp_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+exp(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__exp_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__exp_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
->::type
-log(const _Expr& __x)
+__val_expr<_UnaryOp<__exp_expr<_Tp>, valarray<_Tp> > >
+exp(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__log_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__exp_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__exp_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__log_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+log(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__log_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__log_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
->::type
-log10(const _Expr& __x)
+__val_expr<_UnaryOp<__log_expr<_Tp>, valarray<_Tp> > >
+log(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__log10_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__log_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__log_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__log10_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+log10(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__log10_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__log10_expr<value_type>(), __x));
 }
 
-template<class _Expr1, class _Expr2>
+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 _ValExpr1, class _ValExpr2>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
-    __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
+    is_same<typename __val_expr<_ValExpr1>::value_type,
+            typename __val_expr<_ValExpr2>::value_type>::value,
+    __val_expr<_BinaryOp<__pow_expr<typename __val_expr<_ValExpr1>::value_type>,
+                         __val_expr<_ValExpr1>, __val_expr<_ValExpr2> > >
 >::type
-pow(const _Expr1& __x, const _Expr2& __y)
+pow(const __val_expr<_ValExpr1>& __x, const __val_expr<_ValExpr2>& __y)
 {
-    typedef typename _Expr1::value_type value_type;
-    typedef _BinaryOp<__pow_expr<value_type>, _Expr1, _Expr2> _Op;
+    typedef typename __val_expr<_ValExpr1>::value_type value_type;
+    typedef _BinaryOp<__pow_expr<value_type>, __val_expr<_ValExpr1>,
+                      __val_expr<_ValExpr2> > _Op;
     return __val_expr<_Op>(_Op(__pow_expr<value_type>(), __x, __y));
 }
 
-template<class _Expr>
+template<class _ValExpr, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
-    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
-               _Expr, __scalar_expr<typename _Expr::value_type> > >
+    is_same<typename __val_expr<_ValExpr>::value_type, _Tp>::value,
+    __val_expr<_BinaryOp<__pow_expr<_Tp>, __val_expr<_ValExpr>,
+                         valarray<_Tp> > >
 >::type
-pow(const _Expr& __x, const typename _Expr::value_type& __y)
+pow(const __val_expr<_ValExpr>& __x, const valarray<_Tp>& __y)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _BinaryOp<__pow_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;
-    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
-                           __x, __scalar_expr<value_type>(__y, __x.size())));
+    typedef _BinaryOp<__pow_expr<_Tp>, __val_expr<_ValExpr>,
+                      valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<_Tp>(), __x, __y));
 }
 
-template<class _Expr>
+template<class _Tp, class _ValExpr>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    __is_val_expr<_Expr>::value,
-    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
-               __scalar_expr<typename _Expr::value_type>, _Expr> >
+    is_same<_Tp, typename __val_expr<_ValExpr>::value_type>::value,
+    __val_expr<_BinaryOp<__pow_expr<_Tp>, valarray<_Tp>,
+                         __val_expr<_ValExpr> > >
 >::type
-pow(const typename _Expr::value_type& __x, const _Expr& __y)
+pow(const valarray<_Tp>& __x, const __val_expr<_ValExpr>& __y)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _BinaryOp<__pow_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    typedef _BinaryOp<__pow_expr<_Tp>, valarray<_Tp>,
+                      __val_expr<_ValExpr> > _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 _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__pow_expr<typename __val_expr<_ValExpr>::value_type>,
+                     __val_expr<_ValExpr>,
+                     __scalar_expr<typename __val_expr<_ValExpr>::value_type> > >
+pow(const __val_expr<_ValExpr>& __x,
+    const typename __val_expr<_ValExpr>::value_type& __y)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _BinaryOp<__pow_expr<value_type>, __val_expr<_ValExpr>,
+                      __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
+                           __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 _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_BinaryOp<__pow_expr<typename __val_expr<_ValExpr>::value_type>,
+                     __scalar_expr<typename __val_expr<_ValExpr>::value_type>,
+                     __val_expr<_ValExpr> > >
+pow(const typename __val_expr<_ValExpr>::value_type& __x,
+    const __val_expr<_ValExpr>& __y)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _BinaryOp<__pow_expr<value_type>, __scalar_expr<value_type>,
+                      __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
                            __scalar_expr<value_type>(__x, __y.size()), __y));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
->::type
-sin(const _Expr& __x)
+__val_expr<_BinaryOp<__pow_expr<_Tp>, __scalar_expr<_Tp>, valarray<_Tp> > >
+pow(const _Tp& __x, const valarray<_Tp>& __y)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__sin_expr<value_type>, _Expr> _Op;
+    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 _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__sin_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+sin(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__sin_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__sin_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
->::type
-sinh(const _Expr& __x)
+__val_expr<_UnaryOp<__sin_expr<_Tp>, valarray<_Tp> > >
+sin(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__sinh_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__sin_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__sin_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__sinh_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+sinh(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__sinh_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__sinh_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
->::type
-sqrt(const _Expr& __x)
+__val_expr<_UnaryOp<__sinh_expr<_Tp>, valarray<_Tp> > >
+sinh(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__sqrt_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__sinh_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__sinh_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__sqrt_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+sqrt(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__sqrt_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__sqrt_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
->::type
-tan(const _Expr& __x)
+__val_expr<_UnaryOp<__sqrt_expr<_Tp>, valarray<_Tp> > >
+sqrt(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__tan_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__sqrt_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__sqrt_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__tan_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+tan(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__tan_expr<value_type>, __val_expr<_ValExpr> > _Op;
     return __val_expr<_Op>(_Op(__tan_expr<value_type>(), __x));
 }
 
-template<class _Expr>
+template<class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_val_expr<_Expr>::value,
-    __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
->::type
-tanh(const _Expr& __x)
+__val_expr<_UnaryOp<__tan_expr<_Tp>, valarray<_Tp> > >
+tan(const valarray<_Tp>& __x)
 {
-    typedef typename _Expr::value_type value_type;
-    typedef _UnaryOp<__tanh_expr<value_type>, _Expr> _Op;
+    typedef _UnaryOp<__tan_expr<_Tp>, valarray<_Tp> > _Op;
+    return __val_expr<_Op>(_Op(__tan_expr<_Tp>(), __x));
+}
+
+template<class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<_UnaryOp<__tanh_expr<typename __val_expr<_ValExpr>::value_type>,
+                    __val_expr<_ValExpr> > >
+tanh(const __val_expr<_ValExpr>& __x)
+{
+    typedef typename __val_expr<_ValExpr>::value_type value_type;
+    typedef _UnaryOp<__tanh_expr<value_type>, __val_expr<_ValExpr> > _Op;
     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