MPFR interface

This function provides a (potentially unsafe) way to read and assign the mp_float_t<_> types through the MPFR C interface.

template<typename Fn, typename ...Args>
sfinae_callable_return_type mpfr::handle_as_mpfr_t(Fn &&fn, Args&&... args) noexcept(callable_is_noexcept)

Allows handling mp_float_t<_> objects through mpfr_ptr/mpfr_srcptr proxy objects. If after the callable is executed, one of the arguments has been modified by mpfr, the corresponding mp_float_t<_> object is set to the equivalent value.

If any of the following occurs, the behavior is undefined:

  • Any of the arguments are passed to allocating MPFR functions.

  • Any two arguments alias, and one of them is accessed after the other has been modified.

  • A mpfr_srcptr argument is const_cast to a mpfr_ptr.

  • The mp_float_t<_> object referenced by a parameter that is modified is accessed while the callable is being run (except through the mpfr_ptr proxy).

Side effects

Arguments are read before the callable is executed regardless of whether the corresponding mpfr_srcptr/mpfr_ptr is accessed by the callable

Return

The return value of the callable.

Parameters
  • [in] fn: Arguments of type mp_float_t<_>.

  • [in] fn: A callable that takes arguments of type mpfr_ptr for mutable parameters, or mpfr_srcptr for immutable parameters.

Example usage:

#include "mpfr/mpfr.hpp"
#include <cassert>

  auto main() -> int {
  using namespace mpfr;
  using scalar512_t = mp_float_t<digits2{512}>;
  using scalar1024_t = mp_float_t<digits2{1024}>;
  scalar512_t x;
  scalar1024_t y = scalar1024_t{2.0 + 1.0 / 1024};
  auto err_code = handle_as_mpfr_t(
      [](mpfr_ptr a, mpfr_srcptr b) {
        auto err = mpfr_set_str(a, "0.1111", 2, MPFR_RNDN); // set to 0b0.1111 == 0.9375
        mpfr_add(a, a, b, MPFR_RNDN);
        return err;
      },
      x,
      y);
  assert(err_code == 0);
  assert(x == scalar512_t{2 + 0.5 + 0.25 + 0.125 + 0.0625 + 1.0 / 1024});
  }