diff options
Diffstat (limited to 'vendor/gmp-6.3.0/tests/cxx/t-cxx11.cc')
-rw-r--r-- | vendor/gmp-6.3.0/tests/cxx/t-cxx11.cc | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/vendor/gmp-6.3.0/tests/cxx/t-cxx11.cc b/vendor/gmp-6.3.0/tests/cxx/t-cxx11.cc new file mode 100644 index 0000000..8d6fccb --- /dev/null +++ b/vendor/gmp-6.3.0/tests/cxx/t-cxx11.cc @@ -0,0 +1,232 @@ +/* Test C++11 features + +Copyright 2011, 2012 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include "config.h" + +#include "gmpxx.h" +#include "gmp-impl.h" +#include "tests.h" + +#if __GMPXX_USE_CXX11 + +#include <utility> +#include <type_traits> + +void check_noexcept () +{ + mpz_class z1, z2; + mpq_class q1, q2; + mpf_class f1, f2; + 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"); + + // Only mpz has lazy allocation for now + static_assert(std::is_nothrow_default_constructible<mpz_class>::value, "sorry"); + static_assert(std::is_nothrow_move_constructible<mpz_class>::value, "sorry"); + static_assert(!std::is_nothrow_default_constructible<mpq_class>::value, "sorry"); + static_assert(!std::is_nothrow_move_constructible<mpq_class>::value, "sorry"); + static_assert(!std::is_nothrow_default_constructible<mpf_class>::value, "sorry"); + static_assert(!std::is_nothrow_move_constructible<mpf_class>::value, "sorry"); +} + +void check_common_type () +{ +#define CHECK_COMMON_TYPE1(T, Res) \ + static_assert(std::is_same<std::common_type<T>::type, Res>::value, "sorry") +#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); + CHECK_COMMON_TYPE (decltype(-q), mpq_class, mpq_class); + CHECK_COMMON_TYPE (decltype(-f), mpf_class, mpf_class); + + CHECK_COMMON_TYPE (decltype(-z), mpq_class, mpq_class); + CHECK_COMMON_TYPE (decltype(-z), mpf_class, mpf_class); + CHECK_COMMON_TYPE (decltype(-q), mpf_class, mpf_class); + + /* 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), mpf_class); + CHECK_COMMON_TYPE (decltype(-q), decltype(-f), mpf_class); + + /* common_type now decays */ + CHECK_COMMON_TYPE (decltype(-z), decltype(-z), mpz_class); + CHECK_COMMON_TYPE (decltype(-q), decltype(-q), mpq_class); + CHECK_COMMON_TYPE (decltype(-f), decltype(-f), mpf_class); + CHECK_COMMON_TYPE1 (decltype(-z), mpz_class); + CHECK_COMMON_TYPE1 (decltype(-q), mpq_class); + CHECK_COMMON_TYPE1 (decltype(-f), mpf_class); + + /* Painful */ + CHECK_COMMON_TYPE_BUILTIN (decltype(-z), mpz_class); + CHECK_COMMON_TYPE_BUILTIN (decltype(-q), mpq_class); + CHECK_COMMON_TYPE_BUILTIN (decltype(-f), mpf_class); +} + +template<class T, class U = T> +void check_move_init () +{ + { + // Delete moved-from x1 + T x1 = 3; + U x2 = std::move(x1); + ASSERT_ALWAYS (x2 == 3); + } + { + // Assign to moved-from x1 + T x1 = 2; + U x2 = std::move(x1); + x1 = -7; + ASSERT_ALWAYS (x1 == -7); + ASSERT_ALWAYS (x2 == 2); + } +} + +template<class T, class U = T> +void check_move_assign () +{ + { + // Delete moved-from x1 + T x1 = 3; U x2; + x2 = std::move(x1); + ASSERT_ALWAYS (x2 == 3); + } + { + // Assign to moved-from x1 + T x1 = 2; U x2; + x2 = std::move(x1); + x1 = -7; + ASSERT_ALWAYS (x1 == -7); + ASSERT_ALWAYS (x2 == 2); + } + { + // Self move-assign (not necessary, but it happens to work...) + T x = 4; + x = std::move(x); + ASSERT_ALWAYS (x == 4); + } +} + +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); + } +} + +// Check for explicit conversion to bool +void implicit_bool(bool); +int implicit_bool(...); + +void check_bool_conversion () +{ + const mpz_class zn = -2; + const mpq_class qn = -2; + const mpf_class fn = -2; + const mpz_class z0 = 0; + const mpq_class q0 = 0; + const mpf_class f0 = 0; + const mpz_class zp = +2; + const mpq_class qp = +2; + const mpf_class fp = +2; + if (zn && qn && fn && zp && qp && fp && !z0 && !q0 && !f0) + { + if (z0 || q0 || f0) ASSERT_ALWAYS(false); + } + else ASSERT_ALWAYS(false); + decltype(implicit_bool(zn)) zi = 1; + decltype(implicit_bool(qn)) qi = 1; + decltype(implicit_bool(fn)) fi = 1; + (void)(zi+qi+fi); +} + +int +main (void) +{ + tests_start(); + + check_noexcept(); + check_common_type(); + check_move_init<mpz_class>(); + check_move_init<mpq_class>(); + check_move_init<mpf_class>(); + check_move_assign<mpz_class>(); + check_move_assign<mpq_class>(); + check_move_assign<mpf_class>(); + check_move_init<mpz_class,mpq_class>(); + check_move_assign<mpz_class,mpq_class>(); + check_user_defined_literal(); + check_bool_conversion(); + + tests_end(); + return 0; +} + +#else +int main () { return 0; } +#endif |