Index: include/complex =================================================================== --- include/complex +++ include/complex @@ -789,45 +789,41 @@ // 26.3.7 values: -// real +template ::value, + bool = is_floating_point<_Tp>::value + > +struct __libcpp_complex_overload_traits {}; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_Tp -real(const complex<_Tp>& __c) +// Integral Types +template +struct __libcpp_complex_overload_traits<_Tp, true, false> { - return __c.real(); -} + typedef double _ValueType; + typedef complex _ComplexType; +}; -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -long double -real(long double __re) +// Floating point types +template +struct __libcpp_complex_overload_traits<_Tp, false, true> { - return __re; -} + typedef _Tp _ValueType; + typedef complex<_Tp> _ComplexType; +}; -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -double -real(double __re) -{ - return __re; -} +// real template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename enable_if -< - is_integral<_Tp>::value, - double ->::type -real(_Tp __re) +_Tp +real(const complex<_Tp>& __c) { - return __re; + return __c.real(); } +template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -float -real(float __re) +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +real(_Tp __re) { return __re; } @@ -842,35 +838,10 @@ return __c.imag(); } +template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -long double -imag(long double __re) -{ - return 0; -} - -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -double -imag(double __re) -{ - return 0; -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename enable_if -< - is_integral<_Tp>::value, - double ->::type -imag(_Tp __re) -{ - return 0; -} - -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -float -imag(float __re) +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +imag(_Tp __re) { return 0; } @@ -895,25 +866,22 @@ return atan2(__c.imag(), __c.real()); } +template inline _LIBCPP_INLINE_VISIBILITY -long double -arg(long double __re) +typename enable_if< + is_same<_Tp, long double>::value, + long double +>::type +arg(_Tp __re) { return atan2l(0.L, __re); } -inline _LIBCPP_INLINE_VISIBILITY -double -arg(double __re) -{ - return atan2(0., __re); -} - template inline _LIBCPP_INLINE_VISIBILITY typename enable_if < - is_integral<_Tp>::value, + is_integral<_Tp>::value || is_same<_Tp, double>::value, double >::type arg(_Tp __re) @@ -921,9 +889,13 @@ return atan2(0., __re); } +template inline _LIBCPP_INLINE_VISIBILITY -float -arg(float __re) +typename enable_if< + is_same<_Tp, float>::value, + float +>::type +arg(_Tp __re) { return atan2f(0.F, __re); } @@ -942,37 +914,13 @@ return __c.real() * __c.real() + __c.imag() * __c.imag(); } +template inline _LIBCPP_INLINE_VISIBILITY -long double -norm(long double __re) -{ - return __re * __re; -} - -inline _LIBCPP_INLINE_VISIBILITY -double -norm(double __re) -{ - return __re * __re; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - double ->::type +typename __libcpp_complex_overload_traits<_Tp>::_ValueType norm(_Tp __re) { - return (double)__re * __re; -} - -inline _LIBCPP_INLINE_VISIBILITY -float -norm(float __re) -{ - return __re * __re; + typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; + return static_cast<_ValueType>(__re) * __re; } // conj @@ -985,38 +933,16 @@ return complex<_Tp>(__c.real(), -__c.imag()); } +template inline _LIBCPP_INLINE_VISIBILITY -complex -conj(long double __re) -{ - return complex(__re); -} - -inline _LIBCPP_INLINE_VISIBILITY -complex -conj(double __re) -{ - return complex(__re); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - complex ->::type +typename __libcpp_complex_overload_traits<_Tp>::_ComplexType conj(_Tp __re) { - return complex(__re); + typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; + return _ComplexType(__re); } -inline _LIBCPP_INLINE_VISIBILITY -complex -conj(float __re) -{ - return complex(__re); -} + // proj @@ -1031,44 +957,33 @@ return __r; } +template inline _LIBCPP_INLINE_VISIBILITY -complex -proj(long double __re) -{ - if (isinf(__re)) - __re = abs(__re); - return complex(__re); -} - -inline _LIBCPP_INLINE_VISIBILITY -complex -proj(double __re) +typename enable_if +< + is_floating_point<_Tp>::value, + typename __libcpp_complex_overload_traits<_Tp>::_ComplexType +>::type +proj(_Tp __re) { if (isinf(__re)) __re = abs(__re); - return complex(__re); + return complex<_Tp>(__re); } -template +template inline _LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value, - complex + typename __libcpp_complex_overload_traits<_Tp>::_ComplexType >::type proj(_Tp __re) { - return complex(__re); + typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; + return _ComplexType(__re); } -inline _LIBCPP_INLINE_VISIBILITY -complex -proj(float __re) -{ - if (isinf(__re)) - __re = abs(__re); - return complex(__re); -} // polar Index: test/numerics/complex.number/cmplx.over/arg.convertible/double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/arg.convertible/double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// arg(T x); + +#include + +struct double_type +{ + operator double() const { return 1; } +}; + + +int main() +{ + double_type v; + std::arg(v); +} Index: test/numerics/complex.number/cmplx.over/arg.convertible/float.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/arg.convertible/float.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// arg(T x); + +#include + +struct float_type +{ + operator float() const { return 1; } +}; + + +int main() +{ + float_type v; + std::arg(v); +} Index: test/numerics/complex.number/cmplx.over/arg.convertible/int.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/arg.convertible/int.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// arg(T x); + +#include + +struct integral_type +{ + operator int() const { return 1; } +}; + + +int main() +{ + integral_type v; + std::arg(v); +} Index: test/numerics/complex.number/cmplx.over/arg.convertible/long_double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/arg.convertible/long_double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// arg(T x); + +#include + +struct long_double_type +{ + operator long double() const { return 1; } +}; + + +int main() +{ + long_double_type v; + std::arg(v); +} Index: test/numerics/complex.number/cmplx.over/conj.convertible/double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/conj.convertible/double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// conj(T x); + +#include + +struct double_type +{ + operator double() const { return 1; } +}; + + +int main() +{ + double_type v; + std::conj(v); +} Index: test/numerics/complex.number/cmplx.over/conj.convertible/float.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/conj.convertible/float.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// conj(T x); + +#include + +struct float_type +{ + operator float() const { return 1; } +}; + + +int main() +{ + float_type v; + std::conj(v); +} Index: test/numerics/complex.number/cmplx.over/conj.convertible/int.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/conj.convertible/int.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// conj(T x); + +#include + +struct integral_type +{ + operator int() const { return 1; } +}; + + +int main() +{ + integral_type v; + std::conj(v); +} Index: test/numerics/complex.number/cmplx.over/conj.convertible/long_double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/conj.convertible/long_double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// conj(T x); + +#include + +struct long_double_type +{ + operator long double() const { return 1; } +}; + + +int main() +{ + long_double_type v; + std::conj(v); +} Index: test/numerics/complex.number/cmplx.over/imag.convertible/double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/imag.convertible/double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// imag(T x); + +#include + +struct double_type +{ + operator double() const { return 1; } +}; + + +int main() +{ + double_type v; + std::imag(v); +} Index: test/numerics/complex.number/cmplx.over/imag.convertible/float.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/imag.convertible/float.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// imag(T x); + +#include + +struct float_type +{ + operator float() const { return 1; } +}; + + +int main() +{ + float_type v; + std::imag(v); +} Index: test/numerics/complex.number/cmplx.over/imag.convertible/int.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/imag.convertible/int.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// imag(T x); + +#include + +struct integral_type +{ + operator int() const { return 1; } +}; + + +int main() +{ + integral_type v; + std::imag(v); +} Index: test/numerics/complex.number/cmplx.over/imag.convertible/long_double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/imag.convertible/long_double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// imag(T x); + +#include + +struct long_double_type +{ + operator long double() const { return 1; } +}; + + +int main() +{ + long_double_type v; + std::imag(v); +} Index: test/numerics/complex.number/cmplx.over/norm.convertible/double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/norm.convertible/double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// norm(T x); + +#include + +struct double_type +{ + operator double() const { return 1; } +}; + + +int main() +{ + double_type v; + std::norm(v); +} Index: test/numerics/complex.number/cmplx.over/norm.convertible/float.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/norm.convertible/float.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// norm(T x); + +#include + +struct float_type +{ + operator float() const { return 1; } +}; + + +int main() +{ + float_type v; + std::norm(v); +} Index: test/numerics/complex.number/cmplx.over/norm.convertible/int.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/norm.convertible/int.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// norm(T x); + +#include + +struct integral_type +{ + operator int() const { return 1; } +}; + + +int main() +{ + integral_type v; + std::norm(v); +} Index: test/numerics/complex.number/cmplx.over/norm.convertible/long_double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/norm.convertible/long_double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// norm(T x); + +#include + +struct long_double_type +{ + operator long double() const { return 1; } +}; + + +int main() +{ + long_double_type v; + std::norm(v); +} Index: test/numerics/complex.number/cmplx.over/proj.convertible/double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/proj.convertible/double.fail.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + + +// template +// complex +// proj(T x); + +#include + +struct double_type +{ + operator double() const { return 1; } +}; + + +int main() +{ + double_type v; + std::proj(v); +} Index: test/numerics/complex.number/cmplx.over/proj.convertible/float.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/proj.convertible/float.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// proj(T x); + +#include + +struct float_type +{ + operator float() const { return 1; } +}; + + +int main() +{ + float_type v; + std::proj(v); +} Index: test/numerics/complex.number/cmplx.over/proj.convertible/int.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/proj.convertible/int.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// proj(T x); + +#include + +struct integral_type +{ + operator int() const { return 1; } +}; + + +int main() +{ + integral_type v; + std::proj(v); +} Index: test/numerics/complex.number/cmplx.over/proj.convertible/long_double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/proj.convertible/long_double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// proj(T x); + +#include + +struct long_double_type +{ + operator long double() const { return 1; } +}; + + +int main() +{ + long_double_type v; + std::proj(v); +} Index: test/numerics/complex.number/cmplx.over/real.convertible/double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/real.convertible/double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// real(T x); + +#include + +struct double_type +{ + operator double() const { return 1; } +}; + + +int main() +{ + double_type v; + std::real(v); +} Index: test/numerics/complex.number/cmplx.over/real.convertible/float.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/real.convertible/float.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// real(T x); + +#include + +struct float_type +{ + operator float() const { return 1; } +}; + + +int main() +{ + float_type v; + std::real(v); +} Index: test/numerics/complex.number/cmplx.over/real.convertible/int.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/real.convertible/int.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// real(T x); + +#include + +struct integral_type +{ + operator int() const { return 1; } +}; + +int main() +{ + integral_type v; + std::real(v); +} Index: test/numerics/complex.number/cmplx.over/real.convertible/long_double.fail.cpp =================================================================== --- /dev/null +++ test/numerics/complex.number/cmplx.over/real.convertible/long_double.fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// T +// real(T x); + +#include + +struct long_double_type +{ + operator long double() const { return 1; } +}; + + +int main() +{ + long_double_type v; + std::real(v); +}