summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--doc/gmp.texi16
-rw-r--r--gmpxx.h24
-rw-r--r--tests/cxx/t-cxx11.cc21
4 files changed, 63 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 46e519349..cb896b291 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-02-29 Marc Glisse <marc.glisse@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@mail.dm.unipi.it>
* acinclude.m4 (GMP_H_ANSI): Remove.
diff --git a/doc/gmp.texi b/doc/gmp.texi
index 6e4b6e475..5baa83127 100644
--- a/doc/gmp.texi
+++ b/doc/gmp.texi
@@ -6542,6 +6542,11 @@ If the string is not a valid integer, an @code{std::invalid_argument}
exception is thrown. The same applies to @code{operator=}.
@end deftypefun
+@deftypefun mpz_class operator"" _mpz (const char *@var{str})
+With C++11 compilers, integers can be constructed with the syntax
+@code{123_mpz} which is equivalent to @code{mpz_class("123")}.
+@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 @@ If the string is not a valid rational, an @code{std::invalid_argument}
exception is thrown. The same applies to @code{operator=}.
@end deftypefun
+@deftypefun mpq_class operator"" _mpq (const char *@var{str})
+With C++11 compilers, integral rationals can be constructed with the syntax
+@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}.
+@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 @@ If the string is not a valid float, an @code{std::invalid_argument} exception
is thrown. The same applies to @code{operator=}.
@end deftypefun
+@deftypefun mpf_class operator"" _mpf (const char *@var{str})
+With C++11 compilers, floats can be constructed with the syntax
+@code{1.23e-1_mpf} which is equivalent to @code{mpf_class("1.23e-1")}.
+@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 --git a/gmpxx.h b/gmpxx.h
index 3a0684036..a218166d7 100644
--- a/gmpxx.h
+++ b/gmpxx.h
@@ -40,8 +40,7 @@ along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
// 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 @@ typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
+/**************** 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 --git a/tests/cxx/t-cxx11.cc b/tests/cxx/t-cxx11.cc
index 578f9b7e5..3fd3f0da7 100644
--- a/tests/cxx/t-cxx11.cc
+++ b/tests/cxx/t-cxx11.cc
@@ -34,11 +34,10 @@ void check_noexcept ()
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_move_assign ()
}
}
+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 @@ main (void)
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;