From 2a7d25d301428be4fdc2c2682e1309a301a4ba84 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 11 May 2020 17:42:54 +0100 Subject: [PATCH] MP example: add swap idiom and other improvements --- examples/cpp/mp_double.h | 60 ++++++++++++++++--------------------- examples/cpp/mp_formula.cpp | 25 ++++++++-------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/examples/cpp/mp_double.h b/examples/cpp/mp_double.h index 69eddce8a..4853b89d9 100644 --- a/examples/cpp/mp_double.h +++ b/examples/cpp/mp_double.h @@ -3,33 +3,37 @@ #include -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); @@ -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; } @@ -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); @@ -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); @@ -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); -} \ No newline at end of file +} diff --git a/examples/cpp/mp_formula.cpp b/examples/cpp/mp_formula.cpp index cb0412087..7859200fb 100644 --- a/examples/cpp/mp_formula.cpp +++ b/examples/cpp/mp_formula.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "pf.h" #include "mp_double.h" @@ -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; @@ -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; @@ -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 = @@ -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;