/* 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
