boost/libs/multiprecision/test/test_mixed_move_cpp_int.cpp

224 lines
4.9 KiB
C++
Raw Normal View History

2021-10-05 21:37:46 +02:00
///////////////////////////////////////////////////////////////
// Copyright 2020 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
//
// Compare arithmetic results using fixed_int to GMP results.
//
#ifdef _MSC_VER
#define _SCL_SECURE_NO_WARNINGS
#endif
#include <boost/multiprecision/cpp_int.hpp>
#include "test.hpp"
#ifdef __clang__
#if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer)
// memory sanitizer is incompatible with this test:
# define DISABLE_THIS_TEST
#endif
#endif
#ifdef BOOST_CI_ASAN_BUILD
#define DISABLE_THIS_TEST
#endif
#ifndef DISABLE_THIS_TEST
unsigned alloc_count = 0;
void* operator new(std::size_t count)
{
++alloc_count;
return std::malloc(count);
}
void* operator new[](std::size_t count)
{
++alloc_count;
return std::malloc(count);
}
void operator delete(void * p)noexcept
{
return std::free(p);
}
void operator delete[](void* p)noexcept
{
return std::free(p);
}
template <class From, class To>
void test_one(From val)
{
From copy(val);
To target(val);
alloc_count = 0;
To moved(std::move(copy));
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(moved, target);
copy = val;
moved = 0;
BOOST_CHECK_EQUAL(copy, val);
BOOST_CHECK_EQUAL(moved, 0);
alloc_count = 0;
moved = std::move(copy);
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(moved, target);
}
template <class From, class To>
void test()
{
From val(10);
From limit = pow(From(2), 1000);
while (val < limit)
{
test_one<From, To>(val);
test_one<From, To>(-val);
val *= 100;
val /= 3;
}
}
template <class From, class To>
void test_operations()
{
From a = From(1) << 150;
From b = From(1) << 149;
{
alloc_count = 0;
To c = a * b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a * b);
}
{
alloc_count = 0;
To c;
multiply(c, a, b);
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a * b);
}
{
alloc_count = 0;
To c = a + b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a + b);
}
{
alloc_count = 0;
To c;
add(c, a, b);
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a + b);
}
{
alloc_count = 0;
To c = -a;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, -a);
}
{
alloc_count = 0;
To c = a - b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a - b);
}
{
alloc_count = 0;
To c;
subtract(c, a, b);
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a - b);
}
{
alloc_count = 0;
To c = a / b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a / b);
}
{
alloc_count = 0;
To c = a % b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a % b);
}
{
alloc_count = 0;
To c = a << 1;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a << 1);
}
{
alloc_count = 0;
To c = a >> 1;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a >> 1);
}
{
alloc_count = 0;
To c = a | b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a | b);
}
{
alloc_count = 0;
To c = a & b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a & b);
}
{
alloc_count = 0;
To c = a ^ b;
BOOST_CHECK_EQUAL(alloc_count, 0);
BOOST_CHECK_EQUAL(c, a ^ b);
}
{
alloc_count = 0;
To c = gcd(a, b);
BOOST_CHECK_EQUAL(c, gcd(a, b));
}
{
alloc_count = 0;
To c = lcm(a, b);
BOOST_CHECK_EQUAL(c, lcm(a, b));
}
{
alloc_count = 0;
To c = pow(a, 2);
BOOST_CHECK_EQUAL(c, pow(a, 2));
}
{
alloc_count = 0;
To c = powm(a, b, 2);
BOOST_CHECK_EQUAL(c, powm(a, b, 2));
}
{
alloc_count = 0;
To c = sqrt(a);
BOOST_CHECK_EQUAL(c, sqrt(a));
}
}
int main()
{
using namespace boost::multiprecision;
//
// Our "From" type has the MinBits argument as small as possible,
// should it be larger than the default used in cpp_int then we
// may get allocations causing the tests above to fail since the
// internal cache in type From is larger than that of cpp_int and so
// allocation may be needed even on a move.
//
test<number<cpp_int_backend<sizeof(limb_type) * CHAR_BIT * 2> >, cpp_int>();
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512> > To;
test_operations<cpp_int, To>();
return boost::report_errors();
}
#else
int main(){ return 0; }
#endif