aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/ext
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely.gcc@gmail.com>2011-11-12 15:57:03 +0000
committerJonathan Wakely <jwakely.gcc@gmail.com>2011-11-12 15:57:03 +0000
commit2318453f961fcda9be3d97ec50bbabe1e35d6207 (patch)
treeb28a063e9a478a87290e6b1ddea155409d4e9cb1 /libstdc++-v3/include/ext
parentffbaa7fe165512a9f6ce4d8e420cad23dde0e21a (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.h56
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