Skip to content

Commit

Permalink
MP example: add swap idiom and other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
mindhells committed May 13, 2020
1 parent 2ce0f9f commit 2a7d25d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 46 deletions.
60 changes: 26 additions & 34 deletions examples/cpp/mp_double.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,37 @@

#include <mpfr.h>

class MpDouble {
private:
class MpDouble final {
mpfr_t value;
public:
public:

// copy constructor
MpDouble(const MpDouble &original) {
MpDouble(const MpDouble &original) noexcept {
mpfr_init(value);
mpfr_set(value, original.value, MPFR_RNDN);
}
// move constructor
MpDouble(MpDouble &&original) {
MpDouble(MpDouble &&original) noexcept {
mpfr_init(value); // this is needed to keep original is a safe state for destruction
mpfr_swap(value, original.value);
swap(original);
}
// implicit constructor
MpDouble(const double literal) {
MpDouble(const double literal) noexcept {
mpfr_init(value);
mpfr_set_d(value, literal, MPFR_RNDN);
}
// explicit constructors
explicit MpDouble(const char *literal) {
explicit MpDouble(const char *literal) noexcept {
mpfr_init(value);
mpfr_set_str(value, literal, 10, MPFR_RNDN);
}
explicit MpDouble(mpfr_t val) {
explicit MpDouble(mpfr_t val) noexcept {
mpfr_swap(value, val);
}
// swap
inline void swap(MpDouble &other) noexcept {
mpfr_swap(value, other.value);
}
// destructor
~MpDouble() {
mpfr_clear(value);
Expand All @@ -49,49 +53,33 @@ class MpDouble {
}

// assignment operation
MpDouble &operator=(const MpDouble &other) {
MpDouble &operator=(const MpDouble &other) noexcept {
if(this == &other) return *this;
mpfr_set(value, other.value, MPFR_RNDN);
return *this;
}
// move assignment operation
MpDouble &operator=(MpDouble &&other) {
MpDouble &operator=(MpDouble &&other) noexcept {
if(this == &other) return *this;
mpfr_swap(this->value, other.value);
swap(other);
return *this;
}

// arithmetic operations
MpDouble &operator+=(const MpDouble &other) {
mpfr_t result;
mpfr_init(result);
mpfr_add(result, value, other.value, MPFR_RNDN);
mpfr_swap(value, result);
mpfr_clear(result);
mpfr_add(value, value, other.value, MPFR_RNDN);
return *this;
}
MpDouble &operator-=(const MpDouble &other) {
mpfr_t result;
mpfr_init(result);
mpfr_sub(result, value, other.value, MPFR_RNDN);
mpfr_swap(value, result);
mpfr_clear(result);
mpfr_sub(value, value, other.value, MPFR_RNDN);
return *this;
}
MpDouble &operator/=(const MpDouble &other) {
mpfr_t result;
mpfr_init(result);
mpfr_div(result, value, other.value, MPFR_RNDN);
mpfr_swap(value, result);
mpfr_clear(result);
mpfr_div(value, value, other.value, MPFR_RNDN);
return *this;
}
MpDouble &operator*=(const MpDouble &other) {
mpfr_t result;
mpfr_init(result);
mpfr_mul(result, value, other.value, MPFR_RNDN);
mpfr_swap(value, result);
mpfr_clear(result);
mpfr_mul(value, value, other.value, MPFR_RNDN);
return *this;
}

Expand All @@ -107,8 +95,13 @@ class MpDouble {
friend bool operator!=(const MpDouble &a, const MpDouble &b);
friend bool operator==(const MpDouble &a, const MpDouble &b);

friend void swap(MpDouble &a, MpDouble &b);
};

void swap(MpDouble &a, MpDouble &b) {
a.swap(b);
}

MpDouble operator+(const MpDouble &a, const MpDouble &b) {
mpfr_t result;
mpfr_init(result);
Expand All @@ -124,7 +117,6 @@ MpDouble operator-(const MpDouble &a, const MpDouble &b) {
}

MpDouble operator/(const MpDouble &a, const MpDouble &b) {

mpfr_t result;
mpfr_init(result);
mpfr_div(result, a.value, b.value, MPFR_RNDN);
Expand Down Expand Up @@ -160,4 +152,4 @@ bool operator==(const MpDouble &a, const MpDouble &b) {

bool operator!=(const MpDouble &a, const MpDouble &b) {
return mpfr_lessgreater_p(a.value, b.value);
}
}
25 changes: 13 additions & 12 deletions examples/cpp/mp_formula.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cstdlib>
#include <cmath>
#include <new>

#include "pf.h"
#include "mp_double.h"
Expand Down Expand Up @@ -58,14 +59,14 @@ static void pf_calc(
MpDouble t__h_zwpixel_im = t__params[3];

// set some initial values (fate, color ...)
MpDouble t__h_index = 0.0;
MpDouble t__h_index {0.0};
int t__h_solid = 0;
int t__h_fate = 0;
int t__h_inside = 0;
MpDouble t__h_color_re = 0.0;
MpDouble t__h_color_i = 0.0;
MpDouble t__h_color_j = 0.0;
MpDouble t__h_color_k = 0.0;
MpDouble t__h_color_re {0.0};
MpDouble t__h_color_i {0.0};
MpDouble t__h_color_j {0.0};
MpDouble t__h_color_k {0.0};

// you could use direct color when using a #color variable in the function
*t__p_pDirectColorFlag = 0;
Expand All @@ -84,17 +85,17 @@ static void pf_calc(
void *t__a__gradient = t__pfo->p[0].gradient;
MpDouble t__a_fbailout = t__pfo->p[1].doubleval;

MpDouble z_re = 0.00000000000000000;
MpDouble z_im = 0.00000000000000000;
MpDouble z_re {0.0};
MpDouble z_im {0.0};

// those temporaries we need to keep them
MpDouble t__f5 = 0.00000000000000000;
MpDouble t__f6 = 0.00000000000000000;
MpDouble t__f5 {0.0};
MpDouble t__f6 {0.0};

MpDouble t__a_cf0_offset = t__pfo->p[2].doubleval;
MpDouble t__a_cf0_density = t__pfo->p[3].doubleval;
MpDouble t__a_cf0bailout = t__pfo->p[4].doubleval;
MpDouble cf0ed = 0.00000000000000000;
MpDouble cf0ed {0.0};

MpDouble t__a_cf1_offset = t__pfo->p[5].doubleval;
MpDouble t__a_cf1_density = t__pfo->p[6].doubleval;
Expand Down Expand Up @@ -226,7 +227,7 @@ static void pf_kill(
struct s_pf_data *p_stub)
{
MpDouble::cleanUp();
free(p_stub);
delete p_stub;
}

static struct s_pf_vtable vtbl =
Expand All @@ -240,7 +241,7 @@ static struct s_pf_vtable vtbl =
pf_obj *pf_new()
{
MpDouble::setPreccisionInBits(432);
pf_real *p = (pf_real *)malloc(sizeof(pf_real));
pf_real *p = new (std::nothrow) pf_real;
if (!p)
return NULL;
p->parent.vtbl = &vtbl;
Expand Down

0 comments on commit 2a7d25d

Please sign in to comment.