github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/cxx/t-cxx11.cc (about)

     1  /* Test C++11 features
     2  
     3  Copyright 2011, 2012 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include "config.h"
    21  
    22  #include "gmp.h"
    23  #include "gmpxx.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  #if __GMPXX_USE_CXX11
    28  
    29  #include <utility>
    30  #include <type_traits>
    31  
    32  void check_noexcept ()
    33  {
    34    mpz_class z1, z2;
    35    mpq_class q1, q2;
    36    mpf_class f1, f2;
    37    static_assert(noexcept(z1 = std::move(z2)), "sorry");
    38    static_assert(noexcept(q1 = std::move(q2)), "sorry");
    39    static_assert(noexcept(f1 = std::move(f2)), "sorry");
    40    static_assert(noexcept(q1 = std::move(z1)), "sorry");
    41  }
    42  
    43  void check_common_type ()
    44  {
    45  #define CHECK_COMMON_TYPE1(T, Res) \
    46    static_assert(std::is_same<std::common_type<T>::type, Res>::value, "sorry")
    47  #define CHECK_COMMON_TYPE(T, U, Res) \
    48    static_assert(std::is_same<std::common_type<T, U>::type, Res>::value, "sorry")
    49  #define CHECK_COMMON_TYPE_BUILTIN1(T, Res) \
    50    CHECK_COMMON_TYPE(  signed char , T, Res); \
    51    CHECK_COMMON_TYPE(unsigned char , T, Res); \
    52    CHECK_COMMON_TYPE(  signed short, T, Res); \
    53    CHECK_COMMON_TYPE(unsigned short, T, Res); \
    54    CHECK_COMMON_TYPE(  signed int  , T, Res); \
    55    CHECK_COMMON_TYPE(unsigned int  , T, Res); \
    56    CHECK_COMMON_TYPE(  signed long , T, Res); \
    57    CHECK_COMMON_TYPE(unsigned long , T, Res); \
    58    CHECK_COMMON_TYPE(float , T, Res); \
    59    CHECK_COMMON_TYPE(double, T, Res)
    60  #define CHECK_COMMON_TYPE_BUILTIN2(T, Res) \
    61    CHECK_COMMON_TYPE(T,   signed char , Res); \
    62    CHECK_COMMON_TYPE(T, unsigned char , Res); \
    63    CHECK_COMMON_TYPE(T,   signed short, Res); \
    64    CHECK_COMMON_TYPE(T, unsigned short, Res); \
    65    CHECK_COMMON_TYPE(T,   signed int  , Res); \
    66    CHECK_COMMON_TYPE(T, unsigned int  , Res); \
    67    CHECK_COMMON_TYPE(T,   signed long , Res); \
    68    CHECK_COMMON_TYPE(T, unsigned long , Res); \
    69    CHECK_COMMON_TYPE(T, float , Res); \
    70    CHECK_COMMON_TYPE(T, double, Res)
    71  #define CHECK_COMMON_TYPE_BUILTIN(T, Res) \
    72    CHECK_COMMON_TYPE_BUILTIN1(T, Res); \
    73    CHECK_COMMON_TYPE_BUILTIN2(T, Res)
    74    /* These would just work with implicit conversions */
    75    CHECK_COMMON_TYPE (mpz_class, mpq_class, mpq_class);
    76    CHECK_COMMON_TYPE (mpz_class, mpf_class, mpf_class);
    77    CHECK_COMMON_TYPE (mpf_class, mpq_class, mpf_class);
    78  
    79    CHECK_COMMON_TYPE_BUILTIN (mpz_class, mpz_class);
    80    CHECK_COMMON_TYPE_BUILTIN (mpq_class, mpq_class);
    81    CHECK_COMMON_TYPE_BUILTIN (mpf_class, mpf_class);
    82  
    83    mpz_class z; mpq_class q; mpf_class f;
    84  
    85    CHECK_COMMON_TYPE (decltype(-z), mpz_class, mpz_class);
    86    CHECK_COMMON_TYPE (decltype(-q), mpq_class, mpq_class);
    87    CHECK_COMMON_TYPE (decltype(-f), mpf_class, mpf_class);
    88  
    89    CHECK_COMMON_TYPE (decltype(-z), mpq_class, mpq_class);
    90    CHECK_COMMON_TYPE (decltype(-z), mpf_class, mpf_class);
    91    CHECK_COMMON_TYPE (decltype(-q), mpf_class, mpf_class);
    92  
    93    /* These require a common_type specialization */
    94    CHECK_COMMON_TYPE (decltype(-z), decltype(z+z), mpz_class);
    95    CHECK_COMMON_TYPE (decltype(-q), decltype(q+q), mpq_class);
    96    CHECK_COMMON_TYPE (decltype(-f), decltype(f+f), mpf_class);
    97  
    98    CHECK_COMMON_TYPE (decltype(-q), mpz_class, mpq_class);
    99    CHECK_COMMON_TYPE (decltype(-f), mpz_class, mpf_class);
   100    CHECK_COMMON_TYPE (decltype(-f), mpq_class, mpf_class);
   101  
   102    CHECK_COMMON_TYPE (decltype(-z), decltype(-q), mpq_class);
   103    CHECK_COMMON_TYPE (decltype(-z), decltype(-f), mpf_class);
   104    CHECK_COMMON_TYPE (decltype(-q), decltype(-f), mpf_class);
   105  
   106    /* common_type now decays */
   107    CHECK_COMMON_TYPE (decltype(-z), decltype(-z), mpz_class);
   108    CHECK_COMMON_TYPE (decltype(-q), decltype(-q), mpq_class);
   109    CHECK_COMMON_TYPE (decltype(-f), decltype(-f), mpf_class);
   110    CHECK_COMMON_TYPE1 (decltype(-z), mpz_class);
   111    CHECK_COMMON_TYPE1 (decltype(-q), mpq_class);
   112    CHECK_COMMON_TYPE1 (decltype(-f), mpf_class);
   113  
   114    /* Painful */
   115    CHECK_COMMON_TYPE_BUILTIN (decltype(-z), mpz_class);
   116    CHECK_COMMON_TYPE_BUILTIN (decltype(-q), mpq_class);
   117    CHECK_COMMON_TYPE_BUILTIN (decltype(-f), mpf_class);
   118  }
   119  
   120  template<class T, class U = T>
   121  void check_move_init ()
   122  {
   123    {
   124      // Delete moved-from x1
   125      T x1 = 3;
   126      U x2 = std::move(x1);
   127      ASSERT_ALWAYS (x2 == 3);
   128    }
   129    {
   130      // Assign to moved-from x1
   131      T x1 = 2;
   132      U x2 = std::move(x1);
   133      x1 = -7;
   134      ASSERT_ALWAYS (x1 == -7);
   135      ASSERT_ALWAYS (x2 == 2);
   136    }
   137  }
   138  
   139  template<class T, class U = T>
   140  void check_move_assign ()
   141  {
   142    {
   143      // Delete moved-from x1
   144      T x1 = 3; U x2;
   145      x2 = std::move(x1);
   146      ASSERT_ALWAYS (x2 == 3);
   147    }
   148    {
   149      // Assign to moved-from x1
   150      T x1 = 2; U x2;
   151      x2 = std::move(x1);
   152      x1 = -7;
   153      ASSERT_ALWAYS (x1 == -7);
   154      ASSERT_ALWAYS (x2 == 2);
   155    }
   156    {
   157      // Self move-assign (not necessary, but it happens to work...)
   158      T x = 4;
   159      x = std::move(x);
   160      ASSERT_ALWAYS (x == 4);
   161    }
   162  }
   163  
   164  void check_user_defined_literal ()
   165  {
   166    ASSERT_ALWAYS (123_mpz % 5 == 3);
   167    ASSERT_ALWAYS (-11_mpq / 22 == -.5);
   168    ASSERT_ALWAYS (112.5e-1_mpf * 4 == 45);
   169    {
   170      mpz_class ref ( "123456789abcdef0123456789abcdef0123", 16);
   171      ASSERT_ALWAYS (0x123456789abcdef0123456789abcdef0123_mpz == ref);
   172    }
   173  }
   174  
   175  // Check for explicit conversion to bool
   176  void implicit_bool(bool);
   177  int implicit_bool(...);
   178  
   179  void check_bool_conversion ()
   180  {
   181    const mpz_class zn = -2;
   182    const mpq_class qn = -2;
   183    const mpf_class fn = -2;
   184    const mpz_class z0 =  0;
   185    const mpq_class q0 =  0;
   186    const mpf_class f0 =  0;
   187    const mpz_class zp = +2;
   188    const mpq_class qp = +2;
   189    const mpf_class fp = +2;
   190    if (zn && qn && fn && zp && qp && fp && !z0 && !q0 && !f0)
   191      {
   192        if (z0 || q0 || f0) ASSERT_ALWAYS(false);
   193      }
   194    else ASSERT_ALWAYS(false);
   195    decltype(implicit_bool(zn)) zi = 1;
   196    decltype(implicit_bool(qn)) qi = 1;
   197    decltype(implicit_bool(fn)) fi = 1;
   198    (void)(zi+qi+fi);
   199  }
   200  
   201  int
   202  main (void)
   203  {
   204    tests_start();
   205  
   206    check_noexcept();
   207    check_common_type();
   208    check_move_init<mpz_class>();
   209    check_move_init<mpq_class>();
   210    check_move_init<mpf_class>();
   211    check_move_assign<mpz_class>();
   212    check_move_assign<mpq_class>();
   213    check_move_assign<mpf_class>();
   214    check_move_init<mpz_class,mpq_class>();
   215    check_move_assign<mpz_class,mpq_class>();
   216    check_user_defined_literal();
   217    check_bool_conversion();
   218  
   219    tests_end();
   220    return 0;
   221  }
   222  
   223  #else
   224  int main () { return 0; }
   225  #endif