diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | doc/gmp.texi | 16 | ||||
-rw-r--r-- | gmpxx.h | 24 | ||||
-rw-r--r-- | tests/cxx/t-cxx11.cc | 21 |
4 files changed, 63 insertions, 7 deletions
@@ -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. @@ -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; |