diff options
author | Jonathan Wakely <jwakely.gcc@gmail.com> | 2011-11-12 15:57:03 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely.gcc@gmail.com> | 2011-11-12 15:57:03 +0000 |
commit | 2318453f961fcda9be3d97ec50bbabe1e35d6207 (patch) | |
tree | b28a063e9a478a87290e6b1ddea155409d4e9cb1 /libstdc++-v3/include/ext | |
parent | ffbaa7fe165512a9f6ce4d8e420cad23dde0e21a (diff) |
PR libstdc++/51083
* include/ext/type_traits.h (__promote): Only define __type member
for integral and floating point types, to prevent math functions
participating in overload resolution for other types.
(__promote_2, __promote_3, __promote_4): Use __promote in default
template argument values, so deduction only succeeds for integral and
floating point types.
* testsuite/26_numerics/cmath/51083.cc: New.
* testsuite/26_numerics/complex/51083.cc: New.
* testsuite/tr1/8_c_compatibility/cmath/51083.cc: New.
* testsuite/tr1/8_c_compatibility/complex/51083.cc: New.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@181321 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/ext')
-rw-r--r-- | libstdc++-v3/include/ext/type_traits.h | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/libstdc++-v3/include/ext/type_traits.h b/libstdc++-v3/include/ext/type_traits.h index 92747268a06..b0fa36bcec8 100644 --- a/libstdc++-v3/include/ext/type_traits.h +++ b/libstdc++-v3/include/ext/type_traits.h @@ -161,44 +161,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __promote { typedef double __type; }; + // No nested __type member for non-integer non-floating point types, + // allows this type to be used for SFINAE to constrain overloads in + // <cmath> and <complex> to only the intended types. template<typename _Tp> struct __promote<_Tp, false> - { typedef _Tp __type; }; + { }; + + template<> + struct __promote<long double> + { typedef long double __type; }; + + template<> + struct __promote<double> + { typedef double __type; }; + + template<> + struct __promote<float> + { typedef float __type; }; - template<typename _Tp, typename _Up> + template<typename _Tp, typename _Up, + typename _Tp2 = typename __promote<_Tp>::__type, + typename _Up2 = typename __promote<_Up>::__type> struct __promote_2 { - private: - typedef typename __promote<_Tp>::__type __type1; - typedef typename __promote<_Up>::__type __type2; - - public: - typedef __typeof__(__type1() + __type2()) __type; + typedef __typeof__(_Tp2() + _Up2()) __type; }; - template<typename _Tp, typename _Up, typename _Vp> + template<typename _Tp, typename _Up, typename _Vp, + typename _Tp2 = typename __promote<_Tp>::__type, + typename _Up2 = typename __promote<_Up>::__type, + typename _Vp2 = typename __promote<_Vp>::__type> struct __promote_3 { - private: - typedef typename __promote<_Tp>::__type __type1; - typedef typename __promote<_Up>::__type __type2; - typedef typename __promote<_Vp>::__type __type3; - - public: - typedef __typeof__(__type1() + __type2() + __type3()) __type; + typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type; }; - template<typename _Tp, typename _Up, typename _Vp, typename _Wp> + template<typename _Tp, typename _Up, typename _Vp, typename _Wp, + typename _Tp2 = typename __promote<_Tp>::__type, + typename _Up2 = typename __promote<_Up>::__type, + typename _Vp2 = typename __promote<_Vp>::__type, + typename _Wp2 = typename __promote<_Wp>::__type> struct __promote_4 { - private: - typedef typename __promote<_Tp>::__type __type1; - typedef typename __promote<_Up>::__type __type2; - typedef typename __promote<_Vp>::__type __type3; - typedef typename __promote<_Wp>::__type __type4; - - public: - typedef __typeof__(__type1() + __type2() + __type3() + __type4()) __type; + typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type; }; _GLIBCXX_END_NAMESPACE_VERSION |