<commit_before>// Copyright 2016-2017 <NAME> (<EMAIL>)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <mp++/config.hpp>

#include <mp++/detail/mpfr.hpp>
#include <mp++/real.hpp>
#include <utility>

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

using namespace mppp;

#if defined(_MSC_VER)

template <typename... Args>
auto fma_wrap(Args &&... args) -> decltype(mppp::fma(std::forward<Args>(args)...))
{
    return mppp::fma(std::forward<Args>(args)...);
}

template <typename... Args>
auto fms_wrap(Args &&... args) -> decltype(mppp::fms(std::forward<Args>(args)...))
{
    return mppp::fms(std::forward<Args>(args)...);
}

#else

#define fma_wrap fma
#define fms_wrap fms

#endif

TEST_CASE("real arith nary steal")
{
    real r1, r2, r3;
    auto p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, r3);
    REQUIRE(!p.first);
    REQUIRE(p.second == r1.get_prec());
    r1.set_prec(r1.get_prec() + 1);
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, r3);
    REQUIRE(!p.first);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, std::move(r2), r3);
    REQUIRE(p.first == &r2);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, std::move(r3));
    REQUIRE(p.first == &r3);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, std::move(r2), std::move(r3));
    REQUIRE(p.first == &r2);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, std::move(r2), std::move(r3));
    REQUIRE(p.first == &r1);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, static_cast<const real &>(r2), r3);
    REQUIRE(p.first == &r1);
    REQUIRE(p.second == r1.get_prec());
    r3.set_prec(r1.get_prec() + 1);
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, r3);
    REQUIRE(p.first == &r1);
    REQUIRE(p.second == r3.get_prec());
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, std::move(r3));
    REQUIRE(p.first == &r3);
    REQUIRE(p.second == r3.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, std::move(r3));
    REQUIRE(p.first == &r3);
    REQUIRE(p.second == r3.get_prec());
}

TEST_CASE("real add")
{
    real r1, r2, r3;
    add(r1, r2, r3);
    REQUIRE(r1.zero_p());
    REQUIRE(r1.get_prec() == r3.get_prec());
    r1 = 56;
    add(r1, r2, r3);
    REQUIRE(r1.zero_p());
    REQUIRE(r1.get_prec() == r3.get_prec());
    r2 = 56;
    r3 = -45;
    r1 = -4;
    add(r1, r2, r3);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{11}.get_mpfr_t()));
    REQUIRE(r1.get_prec() == r3.get_prec());
    r1.prec_round(real_prec_min());
    add(r1, r2, r3);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{11}.get_mpfr_t()));
    REQUIRE(r1.get_prec() == r3.get_prec());
    add(r1, real{12, 123}, real{34, 128});
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{46}.get_mpfr_t()));
    REQUIRE(r1.get_prec() == 128);
    // Some tests with rvalue refs/overlapping arguments.
    add(r1,std::move(r1),std::move(r1));
    REQUIRE(r1.get_prec() == 128);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{92}.get_mpfr_t()));
    add(r1,r1,std::move(r1));
    REQUIRE(r1.get_prec() == 128);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{184}.get_mpfr_t()));
    add(r1,std::move(r1),r1);
    REQUIRE(r1.get_prec() == 128);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{368}.get_mpfr_t()));
    r1 = real{};
    add(r1,real{10,50},real{12,51});
    REQUIRE(r1.get_prec() == 51);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{22}.get_mpfr_t()));
    r1 = real{};
    add(r1,real{10,52},real{12,51});<commit_msg>Some additional testing for arithmetics.<commit_after>// Copyright 2016-2017 <NAME> (<EMAIL>)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <mp++/config.hpp>

#include <mp++/detail/mpfr.hpp>
#include <mp++/real.hpp>
#include <utility>

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

using namespace mppp;

#if defined(_MSC_VER)

template <typename... Args>
auto fma_wrap(Args &&... args) -> decltype(mppp::fma(std::forward<Args>(args)...))
{
    return mppp::fma(std::forward<Args>(args)...);
}

template <typename... Args>
auto fms_wrap(Args &&... args) -> decltype(mppp::fms(std::forward<Args>(args)...))
{
    return mppp::fms(std::forward<Args>(args)...);
}

#else

#define fma_wrap fma
#define fms_wrap fms

#endif

TEST_CASE("real arith nary steal")
{
    real r1, r2, r3;
    auto p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, r3);
    REQUIRE(!p.first);
    REQUIRE(p.second == r1.get_prec());
    r1.set_prec(r1.get_prec() + 1);
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, r3);
    REQUIRE(!p.first);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, std::move(r2), r3);
    REQUIRE(p.first == &r2);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, std::move(r3));
    REQUIRE(p.first == &r3);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, std::move(r2), std::move(r3));
    REQUIRE(p.first == &r2);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, std::move(r2), std::move(r3));
    REQUIRE(p.first == &r1);
    REQUIRE(p.second == r1.get_prec());
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, static_cast<const real &>(r2), r3);
    REQUIRE(p.first == &r1);
    REQUIRE(p.second == r1.get_prec());
    r3.set_prec(r1.get_prec() + 1);
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, r3);
    REQUIRE(p.first == &r1);
    REQUIRE(p.second == r3.get_prec());
    p = std::make_pair(&r1, r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, std::move(r3));
    REQUIRE(p.first == &r3);
    REQUIRE(p.second == r3.get_prec());
    p = std::make_pair(static_cast<real *>(nullptr), r1.get_prec());
    mpfr_nary_op_check_steal(p, r2, std::move(r3));
    REQUIRE(p.first == &r3);
    REQUIRE(p.second == r3.get_prec());
}

TEST_CASE("real add")
{
    real r1, r2, r3;
    add(r1, r2, r3);
    REQUIRE(r1.zero_p());
    REQUIRE(r1.get_prec() == r3.get_prec());
    r1 = 56;
    add(r1, r2, r3);
    REQUIRE(r1.zero_p());
    REQUIRE(r1.get_prec() == r3.get_prec());
    r2 = 56;
    r3 = -45;
    r1 = -4;
    add(r1, r2, r3);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{11}.get_mpfr_t()));
    REQUIRE(r1.get_prec() == r3.get_prec());
    r1.prec_round(real_prec_min());
    add(r1, r2, r3);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{11}.get_mpfr_t()));
    REQUIRE(r1.get_prec() == r3.get_prec());
    add(r1, real{12, 123}, real{34, 128});
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{46}.get_mpfr_t()));
    REQUIRE(r1.get_prec() == 128);
    // Some tests with rvalue refs/overlapping arguments.
    add(r1,std::move(r1),std::move(r1));
    REQUIRE(r1.get_prec() == 128);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{92}.get_mpfr_t()));
    add(r1,std::move(r1),real{100,150});
    REQUIRE(r1.get_prec() == 150);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{192}.get_mpfr_t()));
    add(r1,std::move(r1),real{100,50});
    REQUIRE(r1.get_prec() == 150);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{292}.get_mpfr_t()));
    add(r1,real{100,160},std::move(r1));
    REQUIRE(r1.get_prec() == 160);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{392}.get_mpfr_t()));
    add(r1,real{100,50},std::move(r1));
    REQUIRE(r1.get_prec() == 160);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{492}.get_mpfr_t()));
    r1 = real{92,128};
    add(r1,r1,std::move(r1));
    REQUIRE(r1.get_prec() == 128);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{184}.get_mpfr_t()));
    add(r1,std::move(r1),r1);
    REQUIRE(r1.get_prec() == 128);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{368}.get_mpfr_t()));
    r1 = real{};
    add(r1,real{10,50},real{12,51});
    REQUIRE(r1.get_prec() == 51);
    REQUIRE(::mpfr_equal_p(r1.get_mpfr_t(), real{22}.get_mpfr_t()));
    r1 = real{};
    add(r1,real{10,52},real{12,51});
{'fraction_non_alphanumeric': 0.21277061010277717, 'fraction_numerical': 0.049420511699103435, 'mean_word_length': 4.188315371525809, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5353882', 'n_tokens_mistral': 4354, 'n_tokens_neox': 4117, 'n_words': 605}