From 35092042f826e830036d6aed3bc7e77f1947c930 Mon Sep 17 00:00:00 2001 From: Ivan Ermakov Date: Sun, 19 May 2019 14:32:08 +0300 Subject: [PATCH 1/5] std::varint to imporove memory use --- include/real/real.hpp | 47 ++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/include/real/real.hpp b/include/real/real.hpp index 21b6dd2..d9610d1 100644 --- a/include/real/real.hpp +++ b/include/real/real.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -59,12 +60,14 @@ namespace boost { KIND _kind; + std::variant diff_number; +/* // Explicit number real_explicit _explicit_number; // Algorithmic number real_algorithm _algorithmic_number; - +*/ // Composed number OPERATION _operation; real* _lhs_ptr = nullptr; @@ -303,12 +306,14 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - this->_explicit_it = this->_real_ptr->_explicit_number.cbegin(); + this->_explicit_it = std::get( + this->_real_ptr->diff_number).cbegin(); this->approximation_interval = this->_explicit_it.approximation_interval; break; case KIND::ALGORITHM: - this->_algorithmic_it = this->_real_ptr->_algorithmic_number.cbegin(); + this->_algorithmic_it = std::get + (this->_real_ptr->diff_number).cbegin(); this->approximation_interval = this->_algorithmic_it.approximation_interval; break; @@ -339,18 +344,23 @@ namespace boost { case KIND::EXPLICIT: if (cend) { - this->_explicit_it = this->_real_ptr->_explicit_number.cend(); + this->_explicit_it = std::get + (this->_real_ptr->diff_number).cend(); } else { - this->_explicit_it = this->_real_ptr->_explicit_number.cbegin(); + this->_explicit_it = + std::get + (this->_real_ptr->diff_number).cbegin(); } this->approximation_interval = this->_explicit_it.approximation_interval; break; case KIND::ALGORITHM: if (cend) { - this->_algorithmic_it = this->_real_ptr->_algorithmic_number.cend(); + this->_algorithmic_it = std::get( + this->_real_ptr->diff_number).cend(); } else { - this->_algorithmic_it = this->_real_ptr->_algorithmic_number.cbegin(); + this->_algorithmic_it = std::get + (this->_real_ptr->diff_number).cbegin(); } this->approximation_interval = this->_algorithmic_it.approximation_interval; break; @@ -440,8 +450,7 @@ namespace boost { */ real(const real& other) : _kind(other._kind), - _explicit_number(other._explicit_number), - _algorithmic_number(other._algorithmic_number), + diff_number(other.diff_number), _operation(other._operation) { this->copy_operands(other); }; /** @@ -454,7 +463,7 @@ namespace boost { * @throws boost::real::invalid_string_number exception */ real(const std::string& number) - : _kind(KIND::EXPLICIT), _explicit_number(number) {} + : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, number) {} /** * @brief *Initializer list constructor:* Creates a boost::real::real_explicit instance @@ -464,7 +473,7 @@ namespace boost { * @param digits - a initializer_list that represents the number digits. */ real(std::initializer_list digits) - : _kind(KIND::EXPLICIT), _explicit_number(digits, digits.size()) {} + : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, digits.size()) {} /** @@ -478,7 +487,7 @@ namespace boost { * the number is positive, otherwise is negative. */ real(std::initializer_list digits, bool positive) - : _kind(KIND::EXPLICIT), _explicit_number(digits, digits.size(), positive) {} + : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, digits.size(), positive) {} /** * @brief *Initializer list constructor with exponent:* Creates a boost::real::real @@ -490,7 +499,7 @@ namespace boost { * @param exponent - an integer representing the number exponent. */ real(std::initializer_list digits, int exponent) - : _kind(KIND::EXPLICIT), _explicit_number(digits, exponent) {}; + : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, exponent) {}; /** * @brief *Initializer list constructor with exponent and sign:* Creates a boost::real::real instance @@ -504,7 +513,7 @@ namespace boost { * the number is positive, otherwise is negative. */ real(std::initializer_list digits, int exponent, bool positive) - : _kind(KIND::EXPLICIT), _explicit_number(digits, exponent, positive) {}; + : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, exponent, positive) {}; /** * @brief *Lambda function constructor with exponent:* Creates a boost::real::real @@ -517,7 +526,7 @@ namespace boost { * @param exponent - an integer representing the number exponent. */ real(int (*get_nth_digit)(unsigned int), int exponent) - : _kind(KIND::ALGORITHM), _algorithmic_number(get_nth_digit, exponent) {} + : _kind(KIND::ALGORITHM), diff_number(std::in_place_type, get_nth_digit, exponent) {} /** * @brief *Lambda function constructor with exponent and sign:* Creates a boost::real::real instance @@ -536,7 +545,7 @@ namespace boost { int exponent, bool positive) : _kind(KIND::ALGORITHM), - _algorithmic_number(get_nth_digit, exponent, positive) {} + diff_number(std::in_place_type, get_nth_digit, exponent, positive) {} /** * @brief *Default destructor:* If the number is an operator, the destructor destroys its operands. @@ -616,11 +625,11 @@ namespace boost { switch (this->_kind) { case KIND::EXPLICIT: - result = this->_explicit_number[n]; + result = std::get(this -> diff_number)[n]; break; case KIND::ALGORITHM: - result = this->_algorithmic_number[n]; + result = std::get(this->diff_number)[n]; break; case KIND::OPERATION: @@ -729,7 +738,7 @@ namespace boost { */ real& operator=(const real& other) { this->_kind = other._kind; - this->_explicit_number = other._explicit_number; + this->diff_number = other.diff_number; this->_operation = other._operation; this->copy_operands(other); return *this; From 8199c612e913a567509d4c7318ff7077665ab692 Mon Sep 17 00:00:00 2001 From: Ivan Ermakov Date: Sun, 19 May 2019 14:40:03 +0300 Subject: [PATCH 2/5] Modified iterators to use std::variant --- include/real/real.hpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/include/real/real.hpp b/include/real/real.hpp index d9610d1..04639a4 100644 --- a/include/real/real.hpp +++ b/include/real/real.hpp @@ -106,11 +106,16 @@ namespace boost { // Internal number to iterate real const* _real_ptr = nullptr; + std::variant diff_it; + +/* // Explicit number iterator boost::real::real_explicit::const_precision_iterator _explicit_it; // Algorithmic number iterator boost::real::real_algorithm::const_precision_iterator _algorithmic_it; +*/ // If the number is a composition, the const_precision_iterator uses the operand iterators const_precision_iterator* _lhs_it_ptr = nullptr; @@ -306,15 +311,15 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - this->_explicit_it = std::get( + this->diff_it = std::get( this->_real_ptr->diff_number).cbegin(); - this->approximation_interval = this->_explicit_it.approximation_interval; + this->approximation_interval = std::get<0>(this -> diff_it).approximation_interval; break; case KIND::ALGORITHM: - this->_algorithmic_it = std::get + this->diff_it = std::get (this->_real_ptr->diff_number).cbegin(); - this->approximation_interval = this->_algorithmic_it.approximation_interval; + this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; break; case KIND::OPERATION: @@ -344,25 +349,25 @@ namespace boost { case KIND::EXPLICIT: if (cend) { - this->_explicit_it = std::get + this->diff_it = std::get (this->_real_ptr->diff_number).cend(); } else { - this->_explicit_it = + this->diff_it= std::get (this->_real_ptr->diff_number).cbegin(); } - this->approximation_interval = this->_explicit_it.approximation_interval; + this->approximation_interval = std::get<0>(this->diff_it).approximation_interval; break; case KIND::ALGORITHM: if (cend) { - this->_algorithmic_it = std::get( + this->diff_it = std::get( this->_real_ptr->diff_number).cend(); } else { - this->_algorithmic_it = std::get + this->diff_it = std::get (this->_real_ptr->diff_number).cbegin(); } - this->approximation_interval = this->_algorithmic_it.approximation_interval; + this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; break; case KIND::OPERATION: @@ -382,13 +387,13 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - ++this->_explicit_it; - this->approximation_interval = this->_explicit_it.approximation_interval; + ++(std::get<0>(this->diff_it)); + this->approximation_interval = std::get<0>(this->diff_it).approximation_interval; break; case KIND::ALGORITHM: - ++this->_algorithmic_it; - this->approximation_interval = this->_algorithmic_it.approximation_interval; + ++(std::get<1>(this->diff_it)); + this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; break; case KIND::OPERATION: From 0821e8ac5c4bd4d8187d5d27275960fe3a3f5ce2 Mon Sep 17 00:00:00 2001 From: Ivan Ermakov Date: Sun, 19 May 2019 14:40:03 +0300 Subject: [PATCH 3/5] Modified iterators to use std::variant and updated .travis.yml to use C++17 --- .travis.yml | 2 +- include/real/real.hpp | 33 +++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 512fc4c..ef6ab3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ matrix: - wget --quiet -O - ${BOOST_URL} | tar --strip-components=1 -xz -C /tmp/boost || exit 1 - cd /tmp/boost/tools/build && ./bootstrap.sh && ./b2 install --prefix=/tmp/b2 - export PATH=/tmp/b2/bin:${PATH} - - cd /tmp/boost && b2 toolset=gcc cxxflags="-std=c++14 ${CXXFLAGS}" + - cd /tmp/boost && b2 toolset=gcc cxxflags="-std=c++17 ${CXXFLAGS}" - os: osx osx_image: xcode9.4 env: diff --git a/include/real/real.hpp b/include/real/real.hpp index d9610d1..04639a4 100644 --- a/include/real/real.hpp +++ b/include/real/real.hpp @@ -106,11 +106,16 @@ namespace boost { // Internal number to iterate real const* _real_ptr = nullptr; + std::variant diff_it; + +/* // Explicit number iterator boost::real::real_explicit::const_precision_iterator _explicit_it; // Algorithmic number iterator boost::real::real_algorithm::const_precision_iterator _algorithmic_it; +*/ // If the number is a composition, the const_precision_iterator uses the operand iterators const_precision_iterator* _lhs_it_ptr = nullptr; @@ -306,15 +311,15 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - this->_explicit_it = std::get( + this->diff_it = std::get( this->_real_ptr->diff_number).cbegin(); - this->approximation_interval = this->_explicit_it.approximation_interval; + this->approximation_interval = std::get<0>(this -> diff_it).approximation_interval; break; case KIND::ALGORITHM: - this->_algorithmic_it = std::get + this->diff_it = std::get (this->_real_ptr->diff_number).cbegin(); - this->approximation_interval = this->_algorithmic_it.approximation_interval; + this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; break; case KIND::OPERATION: @@ -344,25 +349,25 @@ namespace boost { case KIND::EXPLICIT: if (cend) { - this->_explicit_it = std::get + this->diff_it = std::get (this->_real_ptr->diff_number).cend(); } else { - this->_explicit_it = + this->diff_it= std::get (this->_real_ptr->diff_number).cbegin(); } - this->approximation_interval = this->_explicit_it.approximation_interval; + this->approximation_interval = std::get<0>(this->diff_it).approximation_interval; break; case KIND::ALGORITHM: if (cend) { - this->_algorithmic_it = std::get( + this->diff_it = std::get( this->_real_ptr->diff_number).cend(); } else { - this->_algorithmic_it = std::get + this->diff_it = std::get (this->_real_ptr->diff_number).cbegin(); } - this->approximation_interval = this->_algorithmic_it.approximation_interval; + this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; break; case KIND::OPERATION: @@ -382,13 +387,13 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - ++this->_explicit_it; - this->approximation_interval = this->_explicit_it.approximation_interval; + ++(std::get<0>(this->diff_it)); + this->approximation_interval = std::get<0>(this->diff_it).approximation_interval; break; case KIND::ALGORITHM: - ++this->_algorithmic_it; - this->approximation_interval = this->_algorithmic_it.approximation_interval; + ++(std::get<1>(this->diff_it)); + this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; break; case KIND::OPERATION: From 3ddb8c04d85d118846be43a902c83ddf468c477a Mon Sep 17 00:00:00 2001 From: Ivan Ermakov Date: Tue, 21 May 2019 20:55:36 +0300 Subject: [PATCH 4/5] Fixed namespaces and std::get, changed the name of the variable and updated travis config to use gcc 8. --- .travis.yml | 4 +- include/real/real.hpp | 99 ++++++++++++++++++++++--------------------- 2 files changed, 53 insertions(+), 50 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef6ab3b..612e8db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,12 @@ matrix: include: - os: linux dist: trusty - env: CC=gcc-7 CXX=g++-7 BOOST_ROOT=/usr/include/boost + env: CC=gcc-8 CXX=g++-8 BOOST_ROOT=/usr/include/boost compiler: gcc before_install: - sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test" - sudo apt-get update - - sudo apt-get install g++-7 + - sudo apt-get install g++-8 - export BOOST_URL="https://downloads.sourceforge.net/project/boost/boost/1.67.0/boost_1_67_0.tar.gz" - mkdir -p /tmp/boost - wget --quiet -O - ${BOOST_URL} | tar --strip-components=1 -xz -C /tmp/boost || exit 1 diff --git a/include/real/real.hpp b/include/real/real.hpp index 04639a4..7a3a513 100644 --- a/include/real/real.hpp +++ b/include/real/real.hpp @@ -60,14 +60,9 @@ namespace boost { KIND _kind; - std::variant diff_number; -/* - // Explicit number - real_explicit _explicit_number; - - // Algorithmic number - real_algorithm _algorithmic_number; -*/ + std::variant _explicit_algorithm_number; + //Stores both explicit and algorithmic numbers + // Composed number OPERATION _operation; real* _lhs_ptr = nullptr; @@ -107,15 +102,9 @@ namespace boost { real const* _real_ptr = nullptr; std::variant diff_it; - -/* - // Explicit number iterator - boost::real::real_explicit::const_precision_iterator _explicit_it; + boost::real::real_algorithm::const_precision_iterator> _explicit_algorithm_it; + //Stores both explicit and algorithmic iterators - // Algorithmic number iterator - boost::real::real_algorithm::const_precision_iterator _algorithmic_it; -*/ // If the number is a composition, the const_precision_iterator uses the operand iterators const_precision_iterator* _lhs_it_ptr = nullptr; @@ -311,15 +300,17 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - this->diff_it = std::get( - this->_real_ptr->diff_number).cbegin(); - this->approximation_interval = std::get<0>(this -> diff_it).approximation_interval; + this->_explicit_algorithm_it = std::get( + this->_real_ptr->_explicit_algorithm_number).cbegin(); + this->approximation_interval = std::get +(this -> _explicit_algorithm_it).approximation_interval; break; case KIND::ALGORITHM: - this->diff_it = std::get - (this->_real_ptr->diff_number).cbegin(); - this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; + this->_explicit_algorithm_it = std::get + (this->_real_ptr->_explicit_algorithm_number).cbegin(); + this->approximation_interval = std::get +(this->_explicit_algorithm_it).approximation_interval; break; case KIND::OPERATION: @@ -349,25 +340,27 @@ namespace boost { case KIND::EXPLICIT: if (cend) { - this->diff_it = std::get - (this->_real_ptr->diff_number).cend(); + this->_explicit_algorithm_it = std::get + (this->_real_ptr->_explicit_algorithm_number).cend(); } else { - this->diff_it= - std::get - (this->_real_ptr->diff_number).cbegin(); + this->_explicit_algorithm_it= + std::get + (this->_real_ptr->_explicit_algorithm_number).cbegin(); } - this->approximation_interval = std::get<0>(this->diff_it).approximation_interval; + this->approximation_interval = std::get +(this->_explicit_algorithm_it).approximation_interval; break; case KIND::ALGORITHM: if (cend) { - this->diff_it = std::get( - this->_real_ptr->diff_number).cend(); + this->_explicit_algorithm_it = std::get( + this->_real_ptr->_explicit_algorithm_number).cend(); } else { - this->diff_it = std::get - (this->_real_ptr->diff_number).cbegin(); + this->_explicit_algorithm_it = std::get + (this->_real_ptr->_explicit_algorithm_number).cbegin(); } - this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; + this->approximation_interval = std::get +(this->_explicit_algorithm_it).approximation_interval; break; case KIND::OPERATION: @@ -387,13 +380,17 @@ namespace boost { switch (this->_real_ptr->_kind) { case KIND::EXPLICIT: - ++(std::get<0>(this->diff_it)); - this->approximation_interval = std::get<0>(this->diff_it).approximation_interval; + ++(std::get + (this->_explicit_algorithm_it)); + this->approximation_interval = std::get + (this->_explicit_algorithm_it).approximation_interval; break; case KIND::ALGORITHM: - ++(std::get<1>(this->diff_it)); - this->approximation_interval = std::get<1>(this->diff_it).approximation_interval; + ++(std::get + (this->_explicit_algorithm_it)); + this->approximation_interval = std::get + (this->_explicit_algorithm_it).approximation_interval; break; case KIND::OPERATION: @@ -455,7 +452,7 @@ namespace boost { */ real(const real& other) : _kind(other._kind), - diff_number(other.diff_number), + _explicit_algorithm_number(other._explicit_algorithm_number), _operation(other._operation) { this->copy_operands(other); }; /** @@ -468,7 +465,7 @@ namespace boost { * @throws boost::real::invalid_string_number exception */ real(const std::string& number) - : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, number) {} + : _kind(KIND::EXPLICIT), _explicit_algorithm_number(std::in_place_type, number) {} /** * @brief *Initializer list constructor:* Creates a boost::real::real_explicit instance @@ -478,7 +475,8 @@ namespace boost { * @param digits - a initializer_list that represents the number digits. */ real(std::initializer_list digits) - : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, digits.size()) {} + : _kind(KIND::EXPLICIT), _explicit_algorithm_number + (std::in_place_type, digits, digits.size()) {} /** @@ -492,7 +490,8 @@ namespace boost { * the number is positive, otherwise is negative. */ real(std::initializer_list digits, bool positive) - : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, digits.size(), positive) {} + : _kind(KIND::EXPLICIT), _explicit_algorithm_number + (std::in_place_type, digits, digits.size(), positive) {} /** * @brief *Initializer list constructor with exponent:* Creates a boost::real::real @@ -504,7 +503,8 @@ namespace boost { * @param exponent - an integer representing the number exponent. */ real(std::initializer_list digits, int exponent) - : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, exponent) {}; + : _kind(KIND::EXPLICIT), _explicit_algorithm_number + (std::in_place_type, digits, exponent) {}; /** * @brief *Initializer list constructor with exponent and sign:* Creates a boost::real::real instance @@ -518,7 +518,8 @@ namespace boost { * the number is positive, otherwise is negative. */ real(std::initializer_list digits, int exponent, bool positive) - : _kind(KIND::EXPLICIT), diff_number(std::in_place_type, digits, exponent, positive) {}; + : _kind(KIND::EXPLICIT), _explicit_algorithm_number + (std::in_place_type, digits, exponent, positive) {}; /** * @brief *Lambda function constructor with exponent:* Creates a boost::real::real @@ -531,7 +532,8 @@ namespace boost { * @param exponent - an integer representing the number exponent. */ real(int (*get_nth_digit)(unsigned int), int exponent) - : _kind(KIND::ALGORITHM), diff_number(std::in_place_type, get_nth_digit, exponent) {} + : _kind(KIND::ALGORITHM), _explicit_algorithm_number + (std::in_place_type, get_nth_digit, exponent) {} /** * @brief *Lambda function constructor with exponent and sign:* Creates a boost::real::real instance @@ -550,7 +552,8 @@ namespace boost { int exponent, bool positive) : _kind(KIND::ALGORITHM), - diff_number(std::in_place_type, get_nth_digit, exponent, positive) {} + _explicit_algorithm_number + (std::in_place_type, get_nth_digit, exponent, positive) {} /** * @brief *Default destructor:* If the number is an operator, the destructor destroys its operands. @@ -630,11 +633,11 @@ namespace boost { switch (this->_kind) { case KIND::EXPLICIT: - result = std::get(this -> diff_number)[n]; + result = std::get(this -> _explicit_algorithm_number)[n]; break; case KIND::ALGORITHM: - result = std::get(this->diff_number)[n]; + result = std::get(this->_explicit_algorithm_number)[n]; break; case KIND::OPERATION: @@ -743,7 +746,7 @@ namespace boost { */ real& operator=(const real& other) { this->_kind = other._kind; - this->diff_number = other.diff_number; + this->_explicit_algorithm_number = other._explicit_algorithm_number; this->_operation = other._operation; this->copy_operands(other); return *this; From 7333f54134bbd5d7c6fa6c43e6c943da80ea52a8 Mon Sep 17 00:00:00 2001 From: Ivan Ermakov Date: Tue, 21 May 2019 21:23:55 +0300 Subject: [PATCH 5/5] Another update to Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 612e8db..d81670b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ matrix: - cd /tmp/boost/tools/build && ./bootstrap.sh && ./b2 install --prefix=/tmp/b2 - export PATH=/tmp/b2/bin:${PATH} - cd /tmp/boost && b2 toolset=gcc cxxflags="-std=c++17 ${CXXFLAGS}" + install: export CXX="g++-8" - os: osx osx_image: xcode9.4 env: