[Gmp-commit] /var/hg/gmp: C++11 user-defined literals
mercurial at gmplib.org
mercurial at gmplib.org
Thu Mar 8 22:34:40 CET 2012
details: /var/hg/gmp/rev/e42cc37b852e
changeset: 14742:e42cc37b852e
user: Marc Glisse <marc.glisse at inria.fr>
date: Thu Mar 08 22:34:36 2012 +0100
description:
C++11 user-defined literals
diffstat:
ChangeLog | 9 +++++++++
doc/gmp.texi | 16 ++++++++++++++++
gmpxx.h | 24 ++++++++++++++++++++++--
tests/cxx/t-cxx11.cc | 21 ++++++++++++++++-----
4 files changed, 63 insertions(+), 7 deletions(-)
diffs (142 lines):
diff -r 04042f0812b8 -r e42cc37b852e ChangeLog
--- a/ChangeLog Thu Mar 08 17:49:12 2012 +0100
+++ b/ChangeLog Thu Mar 08 22:34:36 2012 +0100
@@ -1,3 +1,12 @@
+2012-02-29 Marc Glisse <marc.glisse at inria.fr>
+
+ * gmpxx.h: Ignore partial C++11 support in g++-4.6.
+ * tests/cxx/t-cxx11.cc: Likewise.
+
+ * gmpxx.h (operator""): New functions.
+ * tests/cxx/t-cxx11.cc: Test the above.
+ * doc/gmp.texi: Document the above.
+
2012-03-08 Marco Bodrato <bodrato at mail.dm.unipi.it>
* acinclude.m4 (GMP_H_ANSI): Remove.
diff -r 04042f0812b8 -r e42cc37b852e doc/gmp.texi
--- a/doc/gmp.texi Thu Mar 08 17:49:12 2012 +0100
+++ b/doc/gmp.texi Thu Mar 08 22:34:36 2012 +0100
@@ -6542,6 +6542,11 @@
exception is thrown. The same applies to @code{operator=}.
@end deftypefun
+ at deftypefun mpz_class operator"" _mpz (const char *@var{str})
+With C++11 compilers, integers can be constructed with the syntax
+ at code{123_mpz} which is equivalent to @code{mpz_class("123")}.
+ at end deftypefun
+
@deftypefun mpz_class operator/ (mpz_class @var{a}, mpz_class @var{d})
@deftypefunx mpz_class operator% (mpz_class @var{a}, mpz_class @var{d})
Divisions involving @code{mpz_class} round towards zero, as per the
@@ -6637,6 +6642,12 @@
exception is thrown. The same applies to @code{operator=}.
@end deftypefun
+ at deftypefun mpq_class operator"" _mpq (const char *@var{str})
+With C++11 compilers, integral rationals can be constructed with the syntax
+ at code{123_mpq} which is equivalent to @code{mpq_class(123_mpz)}. Other
+rationals can be built as @code{-1_mpq/2} or @code{0xb_mpq/123456_mpz}.
+ at end deftypefun
+
@deftypefun void mpq_class::canonicalize ()
Put an @code{mpq_class} into canonical form, as per @ref{Rational Number
Functions}. All arithmetic operators require their operands in canonical
@@ -6748,6 +6759,11 @@
is thrown. The same applies to @code{operator=}.
@end deftypefun
+ at deftypefun mpf_class operator"" _mpf (const char *@var{str})
+With C++11 compilers, floats can be constructed with the syntax
+ at code{1.23e-1_mpf} which is equivalent to @code{mpf_class("1.23e-1")}.
+ at end deftypefun
+
@deftypefun {mpf_class&} mpf_class::operator= (type @var{op})
Convert and store the given @var{op} value to an @code{mpf_class} object. The
same types are accepted as for the constructors above.
diff -r 04042f0812b8 -r e42cc37b852e gmpxx.h
--- a/gmpxx.h Thu Mar 08 17:49:12 2012 +0100
+++ b/gmpxx.h Thu Mar 08 22:34:36 2012 +0100
@@ -40,8 +40,7 @@
// Use C++11 features
#ifndef __GMPXX_USE_CXX11
-#if (__cplusplus >= 201103L) \
- || (__GMP_GNUC_PREREQ(4, 6) && defined __GXX_EXPERIMENTAL_CXX0X__)
+#if __cplusplus >= 201103L
#define __GMPXX_USE_CXX11 1
#else
#define __GMPXX_USE_CXX11 0
@@ -1981,6 +1980,27 @@
+/**************** User-defined literals ****************/
+
+#if __GMPXX_USE_CXX11
+inline mpz_class operator"" _mpz(const char* s)
+{
+ return mpz_class(s);
+}
+
+inline mpq_class operator"" _mpq(const char* s)
+{
+ mpq_class q;
+ q.get_num() = s;
+ return q;
+}
+
+inline mpf_class operator"" _mpf(const char* s)
+{
+ return mpf_class(s);
+}
+#endif
+
/**************** I/O operators ****************/
// these should (and will) be provided separately
diff -r 04042f0812b8 -r e42cc37b852e tests/cxx/t-cxx11.cc
--- a/tests/cxx/t-cxx11.cc Thu Mar 08 17:49:12 2012 +0100
+++ b/tests/cxx/t-cxx11.cc Thu Mar 08 22:34:36 2012 +0100
@@ -34,11 +34,10 @@
mpz_class z1, z2;
mpq_class q1, q2;
mpf_class f1, f2;
- // gcc 4.6 is missing noexcept on std::move
- static_assert(noexcept(z1 = static_cast<mpz_class&&>(z2)), "sorry");
- static_assert(noexcept(q1 = static_cast<mpq_class&&>(q2)), "sorry");
- static_assert(noexcept(f1 = static_cast<mpf_class&&>(f2)), "sorry");
- static_assert(noexcept(q1 = static_cast<mpz_class&&>(z1)), "sorry");
+ static_assert(noexcept(z1 = std::move(z2)), "sorry");
+ static_assert(noexcept(q1 = std::move(q2)), "sorry");
+ static_assert(noexcept(f1 = std::move(f2)), "sorry");
+ static_assert(noexcept(q1 = std::move(z1)), "sorry");
}
void check_common_type ()
@@ -158,6 +157,17 @@
}
}
+void check_user_defined_literal ()
+{
+ ASSERT_ALWAYS (123_mpz % 5 == 3);
+ ASSERT_ALWAYS (-11_mpq / 22 == -.5);
+ ASSERT_ALWAYS (112.5e-1_mpf * 4 == 45);
+ {
+ mpz_class ref ( "123456789abcdef0123456789abcdef0123", 16);
+ ASSERT_ALWAYS (0x123456789abcdef0123456789abcdef0123_mpz == ref);
+ }
+}
+
int
main (void)
{
@@ -173,6 +183,7 @@
check_move_assign<mpf_class>();
check_move_init<mpz_class,mpq_class>();
check_move_assign<mpz_class,mpq_class>();
+ check_user_defined_literal();
tests_end();
return 0;
More information about the gmp-commit
mailing list