[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