[Gmp-commit] /var/hg/gmp: Specialize std::common_type in C++11.
mercurial at gmplib.org
mercurial at gmplib.org
Sat Feb 18 13:22:24 CET 2012
details: /var/hg/gmp/rev/4e059a4847ec
changeset: 14641:4e059a4847ec
user: Marc Glisse <marc.glisse at inria.fr>
date: Sat Feb 18 13:22:19 2012 +0100
description:
Specialize std::common_type in C++11.
diffstat:
ChangeLog | 5 +++++
gmpxx.h | 28 +++++++++++++++++++++++++---
tests/cxx/t-cxx11.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 77 insertions(+), 6 deletions(-)
diffs (137 lines):
diff -r 4bb45d7afdc4 -r 4e059a4847ec ChangeLog
--- a/ChangeLog Fri Feb 17 21:57:04 2012 +0100
+++ b/ChangeLog Sat Feb 18 13:22:19 2012 +0100
@@ -1,3 +1,8 @@
+2012-02-18 Marc Glisse <marc.glisse at inria.fr>
+
+ * gmpxx.h (std::common_type): New partial specialization in C++11.
+ * tests/cxx/t-cxx11.cc: Test it.
+
2012-02-17 Marc Glisse <marc.glisse at inria.fr>
* gmp-h.in (__GMP_WITHIN_GMP): Test with #ifdef instead of #if, for
diff -r 4bb45d7afdc4 -r 4e059a4847ec gmpxx.h
--- a/gmpxx.h Fri Feb 17 21:57:04 2012 +0100
+++ b/gmpxx.h Sat Feb 18 13:22:19 2012 +0100
@@ -42,12 +42,17 @@
#if (__cplusplus >= 201103L) \
|| (__GMP_GNUC_PREREQ(4, 6) && defined __GXX_EXPERIMENTAL_CXX0X__)
#define __GMPXX_USE_CXX11 1
-#define __GMPXX_NOEXCEPT noexcept
#else
#define __GMPXX_USE_CXX11 0
+#endif
+#endif
+
+#if __GMPXX_USE_CXX11
+#define __GMPXX_NOEXCEPT noexcept
+#include <type_traits> // for common_type
+#else
#define __GMPXX_NOEXCEPT
#endif
-#endif
// Max allocations for plain types when converted to mpz_t
#define __GMPZ_DBL_LIMBS (2 + DBL_MAX_EXP / GMP_NUMB_BITS)
@@ -1339,7 +1344,24 @@
typedef mpf_t value_type;
};
-
+#if __GMPXX_USE_CXX11
+namespace std {
+ template <class T, class U, class V, class W>
+ struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
+ {
+ private:
+ typedef typename __gmp_resolve_expr<T, V>::value_type X;
+ public:
+ typedef __gmp_expr<X, X> type;
+ };
+
+ template <class T, class U>
+ struct common_type <__gmp_expr<T, U>, __gmp_expr<T, U> >
+ {
+ typedef __gmp_expr<T, U> type;
+ };
+}
+#endif
// classes for evaluating unary and binary expressions
template <class T, class Op>
diff -r 4bb45d7afdc4 -r 4e059a4847ec tests/cxx/t-cxx11.cc
--- a/tests/cxx/t-cxx11.cc Fri Feb 17 21:57:04 2012 +0100
+++ b/tests/cxx/t-cxx11.cc Sat Feb 18 13:22:19 2012 +0100
@@ -45,10 +45,40 @@
{
#define CHECK_COMMON_TYPE(T, U, Res) \
static_assert(std::is_same<std::common_type<T, U>::type, Res>::value, "sorry")
+#define CHECK_COMMON_TYPE_BUILTIN1(T, Res) \
+ CHECK_COMMON_TYPE( signed char , T, Res); \
+ CHECK_COMMON_TYPE(unsigned char , T, Res); \
+ CHECK_COMMON_TYPE( signed short, T, Res); \
+ CHECK_COMMON_TYPE(unsigned short, T, Res); \
+ CHECK_COMMON_TYPE( signed int , T, Res); \
+ CHECK_COMMON_TYPE(unsigned int , T, Res); \
+ CHECK_COMMON_TYPE( signed long , T, Res); \
+ CHECK_COMMON_TYPE(unsigned long , T, Res); \
+ CHECK_COMMON_TYPE(float , T, Res); \
+ CHECK_COMMON_TYPE(double, T, Res)
+#define CHECK_COMMON_TYPE_BUILTIN2(T, Res) \
+ CHECK_COMMON_TYPE(T, signed char , Res); \
+ CHECK_COMMON_TYPE(T, unsigned char , Res); \
+ CHECK_COMMON_TYPE(T, signed short, Res); \
+ CHECK_COMMON_TYPE(T, unsigned short, Res); \
+ CHECK_COMMON_TYPE(T, signed int , Res); \
+ CHECK_COMMON_TYPE(T, unsigned int , Res); \
+ CHECK_COMMON_TYPE(T, signed long , Res); \
+ CHECK_COMMON_TYPE(T, unsigned long , Res); \
+ CHECK_COMMON_TYPE(T, float , Res); \
+ CHECK_COMMON_TYPE(T, double, Res)
+#define CHECK_COMMON_TYPE_BUILTIN(T, Res) \
+ CHECK_COMMON_TYPE_BUILTIN1(T, Res); \
+ CHECK_COMMON_TYPE_BUILTIN2(T, Res)
+ /* These would just work with implicit conversions */
CHECK_COMMON_TYPE (mpz_class, mpq_class, mpq_class);
CHECK_COMMON_TYPE (mpz_class, mpf_class, mpf_class);
CHECK_COMMON_TYPE (mpf_class, mpq_class, mpf_class);
+ CHECK_COMMON_TYPE_BUILTIN (mpz_class, mpz_class);
+ CHECK_COMMON_TYPE_BUILTIN (mpq_class, mpq_class);
+ CHECK_COMMON_TYPE_BUILTIN (mpf_class, mpf_class);
+
mpz_class z; mpq_class q; mpf_class f;
CHECK_COMMON_TYPE (decltype(-z), mpz_class, mpz_class);
@@ -59,14 +89,28 @@
CHECK_COMMON_TYPE (decltype(-z), mpf_class, mpf_class);
CHECK_COMMON_TYPE (decltype(-q), mpf_class, mpf_class);
- /* Not currently supported
+ /* These require a common_type specialization */
+ CHECK_COMMON_TYPE (decltype(-z), decltype(z+z), mpz_class);
+ CHECK_COMMON_TYPE (decltype(-q), decltype(q+q), mpq_class);
+ CHECK_COMMON_TYPE (decltype(-f), decltype(f+f), mpf_class);
+
CHECK_COMMON_TYPE (decltype(-q), mpz_class, mpq_class);
CHECK_COMMON_TYPE (decltype(-f), mpz_class, mpf_class);
CHECK_COMMON_TYPE (decltype(-f), mpq_class, mpf_class);
CHECK_COMMON_TYPE (decltype(-z), decltype(-q), mpq_class);
- CHECK_COMMON_TYPE (decltype(-z), decltype(-f), mpq_class);
- CHECK_COMMON_TYPE (decltype(-q), decltype(-f), mpq_class);
+ CHECK_COMMON_TYPE (decltype(-z), decltype(-f), mpf_class);
+ CHECK_COMMON_TYPE (decltype(-q), decltype(-f), mpf_class);
+
+ /* These could be broken by a naive common_type specialization */
+ CHECK_COMMON_TYPE (decltype(-z), decltype(-z), decltype(-z));
+ CHECK_COMMON_TYPE (decltype(-q), decltype(-q), decltype(-q));
+ CHECK_COMMON_TYPE (decltype(-f), decltype(-f), decltype(-f));
+
+ /* Not yet supported
+ CHECK_COMMON_TYPE_BUILTIN (decltype(-z), mpz_class);
+ CHECK_COMMON_TYPE_BUILTIN (decltype(-q), mpq_class);
+ CHECK_COMMON_TYPE_BUILTIN (decltype(-f), mpf_class);
*/
}
More information about the gmp-commit
mailing list