lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] valyuta/005 b852a68 05/17: Add features


From: Greg Chicares
Subject: [lmi-commits] [lmi] valyuta/005 b852a68 05/17: Add features
Date: Sat, 16 Jan 2021 21:06:17 -0500 (EST)

branch: valyuta/005
commit b852a687ce51496cbfb4c5271beff69cc7f63efa
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Add features
    
    Now lmi builds.
---
 currency.hpp      | 79 +++++++++++++++++++++++++++++++++++++++++++++++--------
 currency_test.cpp | 32 +++++++++++++++++++++-
 round_to.hpp      | 13 +++++++++
 3 files changed, 112 insertions(+), 12 deletions(-)

diff --git a/currency.hpp b/currency.hpp
index 3555adf..502b0c3 100644
--- a/currency.hpp
+++ b/currency.hpp
@@ -27,6 +27,7 @@
 #include "so_attributes.hpp"
 
 #include <ostream>
+#include <vector>
 
 class raw_cents {};
 
@@ -35,26 +36,33 @@ class LMI_SO currency
     friend class currency_test;
     friend class round_to_test;
     template<typename T> friend class round_to;
-    using data_type=double;
 #if 1
-    static constexpr int cents_digits     = 2;
-    static constexpr int cents_per_dollar = 100;
+    static constexpr int    cents_digits     = 2;
+    static constexpr double cents_per_dollar = 100.0;
 #endif // 1
 
   public:
-    currency() : m_ {0} {}
-    explicit currency(data_type z, raw_cents) :m_ {z} {}
+    using data_type = double;
+
+//  currency() : m_ {0} {} // prevents "constexpr currency zero {};"
+    currency() = default;
+//  currency(currency const&) = default;
+//  ~currency() = default;
+    explicit currency(data_type z, raw_cents) : m_ {z} {}
+
+//  currency& operator=(currency const&) = default;
 
     currency& operator+=(currency const& z) {m_ += z.m_; return *this;}
+    currency& operator-=(currency const& z) {m_ -= z.m_; return *this;}
 
-//  bool operator<(currency const& z) const {return m_ < z.m_;}
+    currency& operator*=(int z)             {m_ *= z; return *this;}
 
     data_type cents() const {return m_;}
     // !! possible underflow?
     double d() const {return m_ / cents_per_dollar;}
 
   private:
-    data_type m_;
+    data_type m_ = {0};
 };
 
 inline currency operator-(currency const& z)
@@ -63,9 +71,17 @@ inline currency operator-(currency const& z)
 }
 
 inline bool operator==(currency const& lhs, currency const& rhs)
-{
-    return lhs.cents() == rhs.cents();
-}
+    {return lhs.cents() == rhs.cents();}
+inline bool operator< (currency const& lhs, currency const& rhs)
+    {return lhs.cents() <  rhs.cents();}
+inline bool operator!=(currency const& lhs, currency const& rhs)
+    {return !operator==(lhs, rhs);}
+inline bool operator> (currency const& lhs, currency const& rhs)
+    {return  operator< (rhs, lhs);}
+inline bool operator<=(currency const& lhs, currency const& rhs)
+    {return !operator> (lhs, rhs);}
+inline bool operator>=(currency const& lhs, currency const& rhs)
+    {return !operator< (lhs, rhs);}
 
 inline currency operator+(currency const& lhs, currency const& rhs)
 {
@@ -77,7 +93,37 @@ inline currency operator-(currency const& lhs, currency 
const& rhs)
     return currency {lhs} += -currency {rhs};
 }
 
-//inline bool operator<(currency const& z) const {return m_ < z.m_;}
+inline currency operator*(currency const& lhs, int rhs)
+{
+    return currency {lhs} *= rhs;
+}
+
+inline currency operator*(int lhs, currency const& rhs)
+{
+    return currency {rhs} *= lhs;
+}
+
+inline double operator*(currency const& lhs, double rhs)
+{
+    return lhs.d() * rhs;
+}
+
+inline double operator*(double lhs, currency const& rhs)
+{
+    return lhs * rhs.d();
+}
+
+inline double operator/(currency const& lhs, double rhs)
+{
+    return lhs.d() / rhs;
+}
+
+#if 0 // really?
+inline double operator/(double lhs, currency const& rhs)
+{
+    return lhs / rhs.d();
+}
+#endif // 0
 
 static inline currency const C0 {{}, raw_cents {}};
 
@@ -85,4 +131,15 @@ inline std::ostream& operator<<(std::ostream& os, currency 
const& z)
 {
     os << z.d(); return os;
 }
+
+inline std::vector<double> doubleize(std::vector<currency> const& z)
+{
+    std::vector<double> r;
+    r.reserve(z.size());
+    for(auto const& i : z)
+        {
+        r.push_back(i.d());
+        }
+    return r;
+}
 #endif // currency_hpp
diff --git a/currency_test.cpp b/currency_test.cpp
index e42aad6..7410c10 100644
--- a/currency_test.cpp
+++ b/currency_test.cpp
@@ -56,6 +56,8 @@ void currency_test::test_something()
     BOOST_TEST(   0 == a0.m_);
     // operator==()
     BOOST_TEST(  C0 == a0);
+    //
+    constexpr currency zero {};
 
 // Figure out what to do about this:
 //  currency a1(3.14);
@@ -81,6 +83,11 @@ void currency_test::test_something()
     a1 += a1;
     BOOST_TEST_EQUAL(6.50, a1.d());
     BOOST_TEST_EQUAL( 650, a1.m_);
+    // operator-=()
+    a1 -= currency {12.5, raw_cents {}};
+    BOOST_TEST_EQUAL(6.375, a1.d());
+    BOOST_TEST_EQUAL(637.5, a1.m_);
+    a1 += currency {12.5, raw_cents {}}; // [having to reset this here is 
regrettable]
 
     // unary operator-()
     -a1;
@@ -108,14 +115,37 @@ void currency_test::test_something()
     BOOST_TEST_EQUAL(-6.50, a2.d());
     BOOST_TEST_EQUAL( -650, a2.m_);
 
+    // int * currency returns currency
+    currency const mult2 {3125, raw_cents {}};
+    BOOST_TEST_EQUAL(1000.0, (32 * mult2).d());
+    BOOST_TEST_EQUAL(100000, (mult2 * 32).m_);
+
+    // double * currency returns double
+    BOOST_TEST_EQUAL(1000.0, 32.0 * mult2);
+    BOOST_TEST_EQUAL(1000.0, mult2 * 32.0);
+
+    // currency / double returns double
+    currency const div2 {3300, raw_cents {}};
+    BOOST_TEST_EQUAL(1.0, div2 / 33);
+
     // operator<<()
     // 1/64 is an exact binary constant, with so few digits that it
     // must print with full precision by default
-    currency a3 {0.015625, raw_cents {}};
+    currency const a3 {0.015625, raw_cents {}};
     std::ostringstream oss;
     oss << a3;
     BOOST_TEST_EQUAL("0.00015625", oss.str());
 
+    // relops
+    BOOST_TEST(  C0 == a0);
+    BOOST_TEST(  a3 == a3);
+    BOOST_TEST(  a0 <  a3);
+    BOOST_TEST(  a0 <= a3);
+    BOOST_TEST(  a3 <= a3);
+    BOOST_TEST(  a3 >  a0);
+    BOOST_TEST(  a3 >= a0);
+    BOOST_TEST(  a3 >= a3);
+
     // round_to<>.c()
     double d0 = 123.99999999999;
     currency c0 = round_to_nearest_cent.c(d0);
diff --git a/round_to.hpp b/round_to.hpp
index bd79bef..00c7389 100644
--- a/round_to.hpp
+++ b/round_to.hpp
@@ -270,6 +270,8 @@ class round_to
     currency c(RealType r) const;
     std::vector<currency> c(std::vector<RealType> r) const;
 
+    currency c(currency z) const;
+
     int decimals() const;
     rounding_style style() const;
 
@@ -398,6 +400,17 @@ std::vector<currency> 
round_to<RealType>::c(std::vector<RealType> r) const
     return z;
 }
 
+// !! need unit tests
+template<typename RealType>
+currency round_to<RealType>::c(currency z) const
+{
+    return
+        (decimals() < currency::cents_digits)
+        ? c(z.d())
+        : z
+        ;
+}
+
 template<typename RealType>
 int round_to<RealType>::decimals() const
 {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]