lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 5ec4c29 1/4: Clone currency


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 5ec4c29 1/4: Clone currency
Date: Sat, 8 Aug 2020 14:54:19 -0400 (EDT)

branch: master
commit 5ec4c29328216a3afcda7f7c3dcfd5f1aa55f8c1
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Clone currency
    
    Renamed the existing implementation. Cloned it, under the original name,
    with drastic simplifications. Motivation: to change variable types to
    the new name without affecting behavior yet.
---
 Makefile.am                           |   8 +
 currency.hpp                          | 270 +--------------------------------
 currency_test.cpp                     | 275 +---------------------------------
 currency.hpp => monnaie.hpp           |  68 ++++-----
 currency_test.cpp => monnaie_test.cpp | 148 +++++++++---------
 objects.make                          |   6 +
 6 files changed, 126 insertions(+), 649 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index af89211..bed9d4c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -129,6 +129,7 @@ TESTS = \
     test_mc_enum \
     test_md5sum \
     test_miscellany \
+    test_monnaie \
     test_mortality_rates \
     test_name_value_pairs \
     test_ncnnnpnn \
@@ -966,6 +967,12 @@ test_miscellany_SOURCES = \
   miscellany_test.cpp
 test_miscellany_CXXFLAGS = $(AM_CXXFLAGS)
 
+test_monnaie_SOURCES = \
+  $(common_test_objects) \
+  monnaie_test.cpp \
+  timer.cpp
+test_monnaie_CXXFLAGS = $(AM_CXXFLAGS)
+
 test_mortality_rates_SOURCES = \
   $(common_test_objects) \
   ihs_mortal.cpp \
@@ -1387,6 +1394,7 @@ noinst_HEADERS = \
     mec_view.hpp \
     mec_xml_document.hpp \
     miscellany.hpp \
+    monnaie.hpp \
     mortality_rates.hpp \
     msw_workarounds.hpp \
     multidimgrid_any.hpp \
diff --git a/currency.hpp b/currency.hpp
index 4f494e6..a3a3fc2 100644
--- a/currency.hpp
+++ b/currency.hpp
@@ -24,274 +24,6 @@
 
 #include "config.hpp"
 
-#include "bourn_cast.hpp"
-
-#include <cmath>
-#include <cstdint>
-#include <cstdlib>
-#include <iomanip>
-#include <iostream>
-#include <limits>
-#include <stdexcept>
-
-/// Represent a currency amount exactly as integral cents.
-///
-/// This class is tailored to US currency, as lmi is tailored to US
-/// life insurance.
-///
-/// By storing the amount as an integer number of cents internally,
-/// this class avoids roundoff error for addition and subtraction.
-/// For multiplicative operations, conversions to and from double
-/// point type are provided; it is the caller's responsibility to
-/// round the final result of such calculations to a currency amount.
-///
-/// This class provides value-like semantics and has a small size,
-/// making it appropriate to pass instances by value instead of the
-/// more usual const reference.
-
-class currency
-{
-    friend class currency_test;
-
-  public:
-    /// Using int32_t for the value would limit the range to about
-    /// twenty million dollars, which is insufficient; but int64_t
-    /// accommodates values up to about ninety quadrillion dollars,
-    /// which is enough for any life insurance contract in 2016.
-
-    using amount_type = std::int_fast64_t;
-
-    static constexpr int cents_digits = 2;
-    static constexpr int cents_per_dollar = 100; // std::pow(10, cents_digits)
-
-    static constexpr amount_type max_dollars()
-        {
-        return std::numeric_limits<amount_type>::max() / cents_per_dollar;
-        }
-
-    /// No ctor-initializer-list is needed because the lone data
-    /// member has a member-initializer at its point of declaration.
-
-    currency() = default;
-
-    /// Constructor from a positive number of dollars and cents.
-    ///
-    /// The cents argument must be normalized: i.e., positive and
-    /// strictly less than cents_per_dollar.
-
-    currency(amount_type dollars, int cents)
-        {
-        if(!(0 <= dollars && dollars < max_dollars()))
-            {
-            throw std::overflow_error("Currency amount out of range.");
-            }
-
-        if(!(0 <= cents && cents < cents_per_dollar))
-            {
-            throw std::runtime_error("Invalid number of cents.");
-            }
-
-        cents_ = cents_per_dollar * dollars + cents;
-        }
-
-    /// Convert from floating-point dollars.
-    ///
-    /// The argument may be positive or negative. Its value is rounded
-    /// to the nearest cent.
-
-    static currency from_value(double d)
-        {
-        if(static_cast<double>(max_dollars()) <= std::trunc(d))
-            {
-            throw std::overflow_error("Currency amount out of range.");
-            }
-
-        // The check above ensures that the value fits in amount_type.
-        return currency
-            (static_cast<amount_type>(std::round(cents_per_dollar * d))
-            );
-        }
-
-    currency(currency const&) = default;
-    currency& operator=(currency const&) = default;
-    ~currency() = default;
-
-    // Accessors.
-
-    /// Number of whole dollars. May be negative.
-
-    amount_type dollars() const
-        {
-        return cents_ / cents_per_dollar;
-        }
-
-    /// Number of whole cents. May be negative.
-    ///
-    /// The number of cents must be negative if the number of dollars
-    /// is negative. The number of cents may be negative if the number
-    /// of dollars is zero. Otherwise the number of cents must be
-    /// nonnegative.
-
-    int cents() const
-        {
-        return bourn_cast<int>(cents_ % cents_per_dollar);
-        }
-
-    /// Total number of cents, e.g., 123 for 1 dollar and 23 cents.
-
-    amount_type total_cents() const
-        {
-        return cents_;
-        }
-
-    /// Value as floating-point dollars, for mixed-mode arithmetic.
-
-    double value() const
-        {
-        double result = bourn_cast<double>(cents_);
-        result /= cents_per_dollar;
-        return result;
-        }
-
-    // Comparisons.
-    bool operator< (currency other) const { return cents_ <  other.cents_; }
-    bool operator<=(currency other) const { return cents_ <= other.cents_; }
-    bool operator==(currency other) const { return cents_ == other.cents_; }
-    bool operator!=(currency other) const { return cents_ != other.cents_; }
-    bool operator> (currency other) const { return cents_ >  other.cents_; }
-    bool operator>=(currency other) const { return cents_ >= other.cents_; }
-
-    // Arithmetic operations.
-    currency operator-() const
-        {
-        return currency(-cents_);
-        }
-
-    currency& operator+=(currency other)
-        {
-        cents_ += other.cents_;
-        return *this;
-        }
-
-    currency& operator-=(currency other)
-        {
-        cents_ -= other.cents_;
-        return *this;
-        }
-
-    currency& operator*=(int factor)
-        {
-        cents_ *= factor;
-        return *this;
-        }
-
-  private:
-    /// This ctor is only used internally: it is too error-prone to
-    /// expose it publicly.
-
-    explicit currency(amount_type cents)
-        :cents_ {cents}
-        {
-        }
-
-    amount_type cents_ = 0;
-};
-
-inline currency operator+(currency lhs, currency rhs)
-{
-    return lhs += rhs;
-}
-
-inline currency operator-(currency lhs, currency rhs)
-{
-    return lhs -= rhs;
-}
-
-inline currency operator*(currency lhs, int rhs)
-{
-    return lhs *= rhs;
-}
-
-inline currency operator*(int lhs, currency rhs)
-{
-    return rhs *= lhs;
-}
-
-/// Insert the dollars-and-cents amount into a stream.
-///
-/// Dollars and cents, being exact integers, are formatted separately,
-/// but the negative sign cannot be supplied by either of those two
-/// separate formatting operations: $-12.34 must not be inserted as
-/// "-12.-34"; and $-0.56 must be inserted as "-0.56" even though the
-/// whole-dollar amount is not negative.
-///
-/// The decimal mark is hard-coded as '.' because that is universal
-/// US practice.
-
-inline std::ostream& operator<<(std::ostream& os, currency c)
-{
-    if(c.total_cents() < 0)
-        {
-        os << '-';
-        }
-
-    return os
-        << std::abs(c.dollars())
-        << '.'
-        << std::setfill('0')
-        << std::setw(currency::cents_digits)
-        << std::abs(c.cents());
-}
-
-/// Extract a dollars-and-cents amount from a stream.
-///
-/// The negative sign requires special attention so that $-0.56 is not
-/// extracted as -0 dollars plus 56 cents.
-///
-/// The decimal mark is hard-coded as '.' because that is universal
-/// US practice.
-
-inline std::istream& operator>>(std::istream& is, currency& c)
-{
-    bool const negative = is.peek() == '-';
-    if(negative)
-        {
-        is.get();
-        }
-
-    currency::amount_type dollars = 0;
-    is >> dollars;
-    if(!is)
-        {
-        return is;
-        }
-
-    if(is.get() != '.')
-        {
-        is.setstate(std::ios_base::failbit);
-        return is;
-        }
-
-    int cents = 0;
-    is >> cents;
-    if(!is)
-        {
-        return is;
-        }
-
-    if(!(0 <= cents && cents < currency::cents_per_dollar))
-        {
-        is.setstate(std::ios_base::failbit);
-        return is;
-        }
-
-    c = currency(dollars, cents);
-    if(negative)
-        {
-        c = -c;
-        }
-
-    return is;
-}
+using currency = double;
 
 #endif // currency_hpp
diff --git a/currency_test.cpp b/currency_test.cpp
index d18ca44..9920b13 100644
--- a/currency_test.cpp
+++ b/currency_test.cpp
@@ -23,293 +23,24 @@
 
 #include "currency.hpp"
 
-#include "bourn_cast.hpp"
-#include "materially_equal.hpp"
-#include "miscellany.hpp"               // stifle_warning_for_unused_value()
 #include "test_tools.hpp"
-#include "timer.hpp"
-
-#include <cmath>                        // floor()
-#include <limits>
-#include <sstream>
-#include <stdexcept>
 
 class currency_test
 {
   public:
     static void test();
 
-    /// An arbitrary amount that is quasi-volatile.
-    ///
-    /// The return type is 'T', not 'T volatile'. Instantiations are
-    /// written so that the value returned cannot be computed at
-    /// compile time and calculations involving it therefore cannot
-    /// be eliminated by optimization.
-    ///
-    /// This function template is a member so that its specialization
-    /// for class currency can call a private constructor.
-
-    template<typename T>
-    static T arbitrary_amount();
-
   private:
-    static void test_ctors();
-    static void test_accessors();
-    static void test_comparison();
-    static void test_arithmetic();
-    static void test_double();
-    static void test_streams();
-    static void test_speed();
+    static void test_something();
 };
 
 void currency_test::test()
 {
-    test_ctors();
-    test_accessors();
-    test_comparison();
-    test_arithmetic();
-    test_double();
-    test_streams();
-    test_speed();
-}
-
-void currency_test::test_ctors()
-{
-    BOOST_TEST_EQUAL(currency(     ).total_cents(),   0);
-    BOOST_TEST_EQUAL(currency(0, 99).total_cents(),  99);
-    BOOST_TEST_EQUAL(currency(1, 99).total_cents(), 199);
-
-    currency const c(4, 56);
-    BOOST_TEST_EQUAL(currency(c).total_cents(), 456);
-
-    static char const* const overflow_msg = "Currency amount out of range.";
-    BOOST_TEST_THROW(currency(-1,   0), std::overflow_error, overflow_msg);
-    BOOST_TEST_THROW(currency(-1,  99), std::overflow_error, overflow_msg);
-    BOOST_TEST_THROW(currency(-1, -99), std::overflow_error, overflow_msg);
-    BOOST_TEST_THROW
-        (currency(std::numeric_limits<currency::amount_type>::max(), 0)
-        ,std::overflow_error
-        ,overflow_msg
-        );
-    BOOST_TEST_THROW
-        (currency(std::numeric_limits<currency::amount_type>::min(), 0)
-        ,std::overflow_error
-        ,overflow_msg
-        );
-
-    static char const* const cents_msg = "Invalid number of cents.";
-    BOOST_TEST_THROW(currency(1, 100), std::runtime_error, cents_msg);
-    BOOST_TEST_THROW(currency(1, 101), std::runtime_error, cents_msg);
-    BOOST_TEST_THROW(currency(1,  -1), std::runtime_error, cents_msg);
-}
-
-void currency_test::test_accessors()
-{
-    auto c = currency(1234, 56);
-    BOOST_TEST_EQUAL(c.dollars(), 1234);
-    BOOST_TEST_EQUAL(c.cents()  , 56);
-
-    c = -currency(9876543, 21);
-    BOOST_TEST_EQUAL(c.dollars(), -9876543);
-    BOOST_TEST_EQUAL(c.cents()  , -21);
-
-    c = -currency(0, 99);
-    BOOST_TEST_EQUAL(c.dollars(), 0);
-    BOOST_TEST_EQUAL(c.cents()  , -99);
-
-    c = -c;
-    BOOST_TEST_EQUAL(c.dollars(), 0);
-    BOOST_TEST_EQUAL(c.cents()  , 99);
-}
-
-void currency_test::test_comparison()
-{
-    BOOST_TEST( currency(1, 23) <  currency(1, 24));
-    BOOST_TEST(-currency(1, 23) > -currency(1, 24));
-
-    BOOST_TEST( currency(1, 23) <= currency(1, 23));
-    BOOST_TEST( currency(1, 23) == currency(1, 23));
-    BOOST_TEST( currency(1, 23) != currency(1, 24));
-    BOOST_TEST( currency(1, 23) >= currency(1, 23));
-}
-
-void currency_test::test_arithmetic()
-{
-    auto c = currency(1, 23) + currency(4, 77);
-    BOOST_TEST_EQUAL(c.total_cents(), 600);
-
-    c *= 12;
-    BOOST_TEST_EQUAL(c.total_cents(), 7200);
-
-    // $72.00 - $80.10 = $8.10
-    auto d = c - currency(80, 10);
-    BOOST_TEST_EQUAL(d.total_cents(), -810);
-}
-
-void currency_test::test_double()
-{
-    BOOST_TEST_EQUAL(currency::from_value( 1.23).total_cents(),  123);
-    BOOST_TEST_EQUAL(currency::from_value(-1.23).total_cents(), -123);
-
-    BOOST_TEST_EQUAL(currency::from_value( 0.005).total_cents(),  1);
-    BOOST_TEST_EQUAL(currency::from_value(-0.005).total_cents(), -1);
-
-    auto c = currency::from_value(         14857345.859999999404);
-    BOOST_TEST_EQUAL(c.total_cents()     , 1485734586);
-    BOOST_TEST(materially_equal(c.value(), 14857345.86));
-}
-
-void test_stream_roundtrip
-    (currency c0
-    ,std::string const& str
-    ,char const* file
-    ,int line
-    )
-{
-    std::stringstream ss;
-    currency c;
-
-    ss << c0;
-    INVOKE_BOOST_TEST_EQUAL(ss.str(), str, file, line);
-    ss >> c;
-    INVOKE_BOOST_TEST( ss.eof (), file, line);
-    INVOKE_BOOST_TEST(!ss.fail(), file, line);
-    INVOKE_BOOST_TEST(!ss.bad (), file, line);
-    INVOKE_BOOST_TEST_EQUAL(c, c0, file, line);
-}
-
-void currency_test::test_streams()
-{
-#define TEST_ROUNDTRIP(c, str) test_stream_roundtrip(c, str, __FILE__, 
__LINE__)
-    TEST_ROUNDTRIP( currency(123, 45),  "123.45");
-    TEST_ROUNDTRIP( currency(  0,  0),    "0.00");
-    TEST_ROUNDTRIP( currency(  0,  1),    "0.01");
-    TEST_ROUNDTRIP( currency(  0, 99),    "0.99");
-    TEST_ROUNDTRIP(-currency(123, 45), "-123.45");
-    TEST_ROUNDTRIP(-currency(  0,  1),   "-0.01");
-    TEST_ROUNDTRIP(-currency(  0, 99),   "-0.99");
-#undef TEST_ROUNDTRIP
-}
-
-template<>
-double currency_test::arbitrary_amount<double>()
-{
-    double volatile z(1.23);
-    return z;
-}
-
-template<>
-currency::amount_type currency_test::arbitrary_amount<currency::amount_type>()
-{
-    currency::amount_type volatile z(123);
-    return z;
-}
-
-/// An arbitrary currency amount that is quasi-volatile.
-///
-/// The local currency::amount_type variable is volatile, but the
-/// currency object returned is not volatile. It can't be, because
-/// class currency is not "volatile-correct", and there's no present
-/// need to make it so.
-///
-/// However, the currency value represented by the object returned is
-/// "volatile" in the sense that the compiler cannot presume to know
-/// it, so it can't be precomputed at compile time, and calculations
-/// involving it cannot be optimized into oblivion.
-
-template<>
-currency currency_test::arbitrary_amount<currency>()
-{
-    currency::amount_type volatile z(123);
-    return currency(z);
-}
-
-template<typename T>
-inline double convert_to_double(T t)
-{
-    return bourn_cast<double>(t);
-}
-
-template<>
-inline double convert_to_double(currency c)
-{
-    return c.value();
-}
-
-template<typename T>
-inline T convert_from_double(double d)
-{
-    return bourn_cast<T>(d);
-}
-
-template<>
-inline currency convert_from_double<currency>(double d)
-{
-    return currency::from_value(d);
-}
-
-template<typename T>
-void do_some_arithmetic(T t)
-{
-    T a(currency_test::arbitrary_amount<T>());
-    T b(currency_test::arbitrary_amount<T>());
-    T c(currency_test::arbitrary_amount<T>());
-    T d(currency_test::arbitrary_amount<T>());
-    T e(currency_test::arbitrary_amount<T>());
-    T f(currency_test::arbitrary_amount<T>());
-
-    for(int j = 0; j < 1000; ++j)
-        {
-        T u(a + b);
-        t += u;
-        u += u;
-        t += u - c + d - e;
-        u += t - f;
-        u = convert_from_double<T>(std::floor(convert_to_double(u) * 1.03));
-        T volatile v(u);
-        stifle_warning_for_unused_value(v);
-        }
-
-    T volatile w(t);
-    stifle_warning_for_unused_value(w);
-}
-
-void mete_double()
-{
-    double d(12345.67);
-    for(int j = 0; j < 1000; ++j)
-        {
-        do_some_arithmetic(d);
-        }
-}
-
-void mete_amount_type()
-{
-    currency::amount_type a(1234567);
-    for(int j = 0; j < 1000; ++j)
-        {
-        do_some_arithmetic(a);
-        }
-}
-
-void mete_currency()
-{
-    currency c(12345, 67);
-    for(int j = 0; j < 1000; ++j)
-        {
-        do_some_arithmetic(c);
-        }
+    test_something();
 }
 
-void currency_test::test_speed()
+void currency_test::test_something()
 {
-    std::cout
-        << "  Speed tests..."
-        << "\n  double     : " << TimeAnAliquot(mete_double)
-        << "\n  amount_type: " << TimeAnAliquot(mete_amount_type)
-        << "\n  currency   : " << TimeAnAliquot(mete_currency)
-        << std::endl
-        ;
 }
 
 int test_main(int, char*[])
diff --git a/currency.hpp b/monnaie.hpp
similarity index 80%
copy from currency.hpp
copy to monnaie.hpp
index 4f494e6..29d5ccc 100644
--- a/currency.hpp
+++ b/monnaie.hpp
@@ -19,8 +19,8 @@
 // email: <gchicares@sbcglobal.net>
 // snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
 
-#ifndef currency_hpp
-#define currency_hpp
+#ifndef monnaie_hpp
+#define monnaie_hpp
 
 #include "config.hpp"
 
@@ -49,9 +49,9 @@
 /// making it appropriate to pass instances by value instead of the
 /// more usual const reference.
 
-class currency
+class monnaie
 {
-    friend class currency_test;
+    friend class monnaie_test;
 
   public:
     /// Using int32_t for the value would limit the range to about
@@ -72,14 +72,14 @@ class currency
     /// No ctor-initializer-list is needed because the lone data
     /// member has a member-initializer at its point of declaration.
 
-    currency() = default;
+    monnaie() = default;
 
     /// Constructor from a positive number of dollars and cents.
     ///
     /// The cents argument must be normalized: i.e., positive and
     /// strictly less than cents_per_dollar.
 
-    currency(amount_type dollars, int cents)
+    monnaie(amount_type dollars, int cents)
         {
         if(!(0 <= dollars && dollars < max_dollars()))
             {
@@ -99,7 +99,7 @@ class currency
     /// The argument may be positive or negative. Its value is rounded
     /// to the nearest cent.
 
-    static currency from_value(double d)
+    static monnaie from_value(double d)
         {
         if(static_cast<double>(max_dollars()) <= std::trunc(d))
             {
@@ -107,14 +107,14 @@ class currency
             }
 
         // The check above ensures that the value fits in amount_type.
-        return currency
+        return monnaie
             (static_cast<amount_type>(std::round(cents_per_dollar * d))
             );
         }
 
-    currency(currency const&) = default;
-    currency& operator=(currency const&) = default;
-    ~currency() = default;
+    monnaie(monnaie const&) = default;
+    monnaie& operator=(monnaie const&) = default;
+    ~monnaie() = default;
 
     // Accessors.
 
@@ -154,32 +154,32 @@ class currency
         }
 
     // Comparisons.
-    bool operator< (currency other) const { return cents_ <  other.cents_; }
-    bool operator<=(currency other) const { return cents_ <= other.cents_; }
-    bool operator==(currency other) const { return cents_ == other.cents_; }
-    bool operator!=(currency other) const { return cents_ != other.cents_; }
-    bool operator> (currency other) const { return cents_ >  other.cents_; }
-    bool operator>=(currency other) const { return cents_ >= other.cents_; }
+    bool operator< (monnaie other) const { return cents_ <  other.cents_; }
+    bool operator<=(monnaie other) const { return cents_ <= other.cents_; }
+    bool operator==(monnaie other) const { return cents_ == other.cents_; }
+    bool operator!=(monnaie other) const { return cents_ != other.cents_; }
+    bool operator> (monnaie other) const { return cents_ >  other.cents_; }
+    bool operator>=(monnaie other) const { return cents_ >= other.cents_; }
 
     // Arithmetic operations.
-    currency operator-() const
+    monnaie operator-() const
         {
-        return currency(-cents_);
+        return monnaie(-cents_);
         }
 
-    currency& operator+=(currency other)
+    monnaie& operator+=(monnaie other)
         {
         cents_ += other.cents_;
         return *this;
         }
 
-    currency& operator-=(currency other)
+    monnaie& operator-=(monnaie other)
         {
         cents_ -= other.cents_;
         return *this;
         }
 
-    currency& operator*=(int factor)
+    monnaie& operator*=(int factor)
         {
         cents_ *= factor;
         return *this;
@@ -189,7 +189,7 @@ class currency
     /// This ctor is only used internally: it is too error-prone to
     /// expose it publicly.
 
-    explicit currency(amount_type cents)
+    explicit monnaie(amount_type cents)
         :cents_ {cents}
         {
         }
@@ -197,22 +197,22 @@ class currency
     amount_type cents_ = 0;
 };
 
-inline currency operator+(currency lhs, currency rhs)
+inline monnaie operator+(monnaie lhs, monnaie rhs)
 {
     return lhs += rhs;
 }
 
-inline currency operator-(currency lhs, currency rhs)
+inline monnaie operator-(monnaie lhs, monnaie rhs)
 {
     return lhs -= rhs;
 }
 
-inline currency operator*(currency lhs, int rhs)
+inline monnaie operator*(monnaie lhs, int rhs)
 {
     return lhs *= rhs;
 }
 
-inline currency operator*(int lhs, currency rhs)
+inline monnaie operator*(int lhs, monnaie rhs)
 {
     return rhs *= lhs;
 }
@@ -228,7 +228,7 @@ inline currency operator*(int lhs, currency rhs)
 /// The decimal mark is hard-coded as '.' because that is universal
 /// US practice.
 
-inline std::ostream& operator<<(std::ostream& os, currency c)
+inline std::ostream& operator<<(std::ostream& os, monnaie c)
 {
     if(c.total_cents() < 0)
         {
@@ -239,7 +239,7 @@ inline std::ostream& operator<<(std::ostream& os, currency 
c)
         << std::abs(c.dollars())
         << '.'
         << std::setfill('0')
-        << std::setw(currency::cents_digits)
+        << std::setw(monnaie::cents_digits)
         << std::abs(c.cents());
 }
 
@@ -251,7 +251,7 @@ inline std::ostream& operator<<(std::ostream& os, currency 
c)
 /// The decimal mark is hard-coded as '.' because that is universal
 /// US practice.
 
-inline std::istream& operator>>(std::istream& is, currency& c)
+inline std::istream& operator>>(std::istream& is, monnaie& c)
 {
     bool const negative = is.peek() == '-';
     if(negative)
@@ -259,7 +259,7 @@ inline std::istream& operator>>(std::istream& is, currency& 
c)
         is.get();
         }
 
-    currency::amount_type dollars = 0;
+    monnaie::amount_type dollars = 0;
     is >> dollars;
     if(!is)
         {
@@ -279,13 +279,13 @@ inline std::istream& operator>>(std::istream& is, 
currency& c)
         return is;
         }
 
-    if(!(0 <= cents && cents < currency::cents_per_dollar))
+    if(!(0 <= cents && cents < monnaie::cents_per_dollar))
         {
         is.setstate(std::ios_base::failbit);
         return is;
         }
 
-    c = currency(dollars, cents);
+    c = monnaie(dollars, cents);
     if(negative)
         {
         c = -c;
@@ -294,4 +294,4 @@ inline std::istream& operator>>(std::istream& is, currency& 
c)
     return is;
 }
 
-#endif // currency_hpp
+#endif // monnaie_hpp
diff --git a/currency_test.cpp b/monnaie_test.cpp
similarity index 58%
copy from currency_test.cpp
copy to monnaie_test.cpp
index d18ca44..9fac3b4 100644
--- a/currency_test.cpp
+++ b/monnaie_test.cpp
@@ -21,7 +21,7 @@
 
 #include "pchfile.hpp"
 
-#include "currency.hpp"
+#include "monnaie.hpp"
 
 #include "bourn_cast.hpp"
 #include "materially_equal.hpp"
@@ -34,7 +34,7 @@
 #include <sstream>
 #include <stdexcept>
 
-class currency_test
+class monnaie_test
 {
   public:
     static void test();
@@ -47,7 +47,7 @@ class currency_test
     /// be eliminated by optimization.
     ///
     /// This function template is a member so that its specialization
-    /// for class currency can call a private constructor.
+    /// for class monnaie can call a private constructor.
 
     template<typename T>
     static T arbitrary_amount();
@@ -62,7 +62,7 @@ class currency_test
     static void test_speed();
 };
 
-void currency_test::test()
+void monnaie_test::test()
 {
     test_ctors();
     test_accessors();
@@ -73,47 +73,47 @@ void currency_test::test()
     test_speed();
 }
 
-void currency_test::test_ctors()
+void monnaie_test::test_ctors()
 {
-    BOOST_TEST_EQUAL(currency(     ).total_cents(),   0);
-    BOOST_TEST_EQUAL(currency(0, 99).total_cents(),  99);
-    BOOST_TEST_EQUAL(currency(1, 99).total_cents(), 199);
+    BOOST_TEST_EQUAL(monnaie(     ).total_cents(),   0);
+    BOOST_TEST_EQUAL(monnaie(0, 99).total_cents(),  99);
+    BOOST_TEST_EQUAL(monnaie(1, 99).total_cents(), 199);
 
-    currency const c(4, 56);
-    BOOST_TEST_EQUAL(currency(c).total_cents(), 456);
+    monnaie const c(4, 56);
+    BOOST_TEST_EQUAL(monnaie(c).total_cents(), 456);
 
     static char const* const overflow_msg = "Currency amount out of range.";
-    BOOST_TEST_THROW(currency(-1,   0), std::overflow_error, overflow_msg);
-    BOOST_TEST_THROW(currency(-1,  99), std::overflow_error, overflow_msg);
-    BOOST_TEST_THROW(currency(-1, -99), std::overflow_error, overflow_msg);
+    BOOST_TEST_THROW(monnaie(-1,   0), std::overflow_error, overflow_msg);
+    BOOST_TEST_THROW(monnaie(-1,  99), std::overflow_error, overflow_msg);
+    BOOST_TEST_THROW(monnaie(-1, -99), std::overflow_error, overflow_msg);
     BOOST_TEST_THROW
-        (currency(std::numeric_limits<currency::amount_type>::max(), 0)
+        (monnaie(std::numeric_limits<monnaie::amount_type>::max(), 0)
         ,std::overflow_error
         ,overflow_msg
         );
     BOOST_TEST_THROW
-        (currency(std::numeric_limits<currency::amount_type>::min(), 0)
+        (monnaie(std::numeric_limits<monnaie::amount_type>::min(), 0)
         ,std::overflow_error
         ,overflow_msg
         );
 
     static char const* const cents_msg = "Invalid number of cents.";
-    BOOST_TEST_THROW(currency(1, 100), std::runtime_error, cents_msg);
-    BOOST_TEST_THROW(currency(1, 101), std::runtime_error, cents_msg);
-    BOOST_TEST_THROW(currency(1,  -1), std::runtime_error, cents_msg);
+    BOOST_TEST_THROW(monnaie(1, 100), std::runtime_error, cents_msg);
+    BOOST_TEST_THROW(monnaie(1, 101), std::runtime_error, cents_msg);
+    BOOST_TEST_THROW(monnaie(1,  -1), std::runtime_error, cents_msg);
 }
 
-void currency_test::test_accessors()
+void monnaie_test::test_accessors()
 {
-    auto c = currency(1234, 56);
+    auto c = monnaie(1234, 56);
     BOOST_TEST_EQUAL(c.dollars(), 1234);
     BOOST_TEST_EQUAL(c.cents()  , 56);
 
-    c = -currency(9876543, 21);
+    c = -monnaie(9876543, 21);
     BOOST_TEST_EQUAL(c.dollars(), -9876543);
     BOOST_TEST_EQUAL(c.cents()  , -21);
 
-    c = -currency(0, 99);
+    c = -monnaie(0, 99);
     BOOST_TEST_EQUAL(c.dollars(), 0);
     BOOST_TEST_EQUAL(c.cents()  , -99);
 
@@ -122,52 +122,52 @@ void currency_test::test_accessors()
     BOOST_TEST_EQUAL(c.cents()  , 99);
 }
 
-void currency_test::test_comparison()
+void monnaie_test::test_comparison()
 {
-    BOOST_TEST( currency(1, 23) <  currency(1, 24));
-    BOOST_TEST(-currency(1, 23) > -currency(1, 24));
+    BOOST_TEST( monnaie(1, 23) <  monnaie(1, 24));
+    BOOST_TEST(-monnaie(1, 23) > -monnaie(1, 24));
 
-    BOOST_TEST( currency(1, 23) <= currency(1, 23));
-    BOOST_TEST( currency(1, 23) == currency(1, 23));
-    BOOST_TEST( currency(1, 23) != currency(1, 24));
-    BOOST_TEST( currency(1, 23) >= currency(1, 23));
+    BOOST_TEST( monnaie(1, 23) <= monnaie(1, 23));
+    BOOST_TEST( monnaie(1, 23) == monnaie(1, 23));
+    BOOST_TEST( monnaie(1, 23) != monnaie(1, 24));
+    BOOST_TEST( monnaie(1, 23) >= monnaie(1, 23));
 }
 
-void currency_test::test_arithmetic()
+void monnaie_test::test_arithmetic()
 {
-    auto c = currency(1, 23) + currency(4, 77);
+    auto c = monnaie(1, 23) + monnaie(4, 77);
     BOOST_TEST_EQUAL(c.total_cents(), 600);
 
     c *= 12;
     BOOST_TEST_EQUAL(c.total_cents(), 7200);
 
     // $72.00 - $80.10 = $8.10
-    auto d = c - currency(80, 10);
+    auto d = c - monnaie(80, 10);
     BOOST_TEST_EQUAL(d.total_cents(), -810);
 }
 
-void currency_test::test_double()
+void monnaie_test::test_double()
 {
-    BOOST_TEST_EQUAL(currency::from_value( 1.23).total_cents(),  123);
-    BOOST_TEST_EQUAL(currency::from_value(-1.23).total_cents(), -123);
+    BOOST_TEST_EQUAL(monnaie::from_value( 1.23).total_cents(),  123);
+    BOOST_TEST_EQUAL(monnaie::from_value(-1.23).total_cents(), -123);
 
-    BOOST_TEST_EQUAL(currency::from_value( 0.005).total_cents(),  1);
-    BOOST_TEST_EQUAL(currency::from_value(-0.005).total_cents(), -1);
+    BOOST_TEST_EQUAL(monnaie::from_value( 0.005).total_cents(),  1);
+    BOOST_TEST_EQUAL(monnaie::from_value(-0.005).total_cents(), -1);
 
-    auto c = currency::from_value(         14857345.859999999404);
+    auto c = monnaie::from_value(          14857345.859999999404);
     BOOST_TEST_EQUAL(c.total_cents()     , 1485734586);
     BOOST_TEST(materially_equal(c.value(), 14857345.86));
 }
 
 void test_stream_roundtrip
-    (currency c0
+    (monnaie c0
     ,std::string const& str
     ,char const* file
     ,int line
     )
 {
     std::stringstream ss;
-    currency c;
+    monnaie c;
 
     ss << c0;
     INVOKE_BOOST_TEST_EQUAL(ss.str(), str, file, line);
@@ -178,50 +178,50 @@ void test_stream_roundtrip
     INVOKE_BOOST_TEST_EQUAL(c, c0, file, line);
 }
 
-void currency_test::test_streams()
+void monnaie_test::test_streams()
 {
 #define TEST_ROUNDTRIP(c, str) test_stream_roundtrip(c, str, __FILE__, 
__LINE__)
-    TEST_ROUNDTRIP( currency(123, 45),  "123.45");
-    TEST_ROUNDTRIP( currency(  0,  0),    "0.00");
-    TEST_ROUNDTRIP( currency(  0,  1),    "0.01");
-    TEST_ROUNDTRIP( currency(  0, 99),    "0.99");
-    TEST_ROUNDTRIP(-currency(123, 45), "-123.45");
-    TEST_ROUNDTRIP(-currency(  0,  1),   "-0.01");
-    TEST_ROUNDTRIP(-currency(  0, 99),   "-0.99");
+    TEST_ROUNDTRIP( monnaie(123, 45),  "123.45");
+    TEST_ROUNDTRIP( monnaie(  0,  0),    "0.00");
+    TEST_ROUNDTRIP( monnaie(  0,  1),    "0.01");
+    TEST_ROUNDTRIP( monnaie(  0, 99),    "0.99");
+    TEST_ROUNDTRIP(-monnaie(123, 45), "-123.45");
+    TEST_ROUNDTRIP(-monnaie(  0,  1),   "-0.01");
+    TEST_ROUNDTRIP(-monnaie(  0, 99),   "-0.99");
 #undef TEST_ROUNDTRIP
 }
 
 template<>
-double currency_test::arbitrary_amount<double>()
+double monnaie_test::arbitrary_amount<double>()
 {
     double volatile z(1.23);
     return z;
 }
 
 template<>
-currency::amount_type currency_test::arbitrary_amount<currency::amount_type>()
+monnaie::amount_type monnaie_test::arbitrary_amount<monnaie::amount_type>()
 {
-    currency::amount_type volatile z(123);
+    monnaie::amount_type volatile z(123);
     return z;
 }
 
-/// An arbitrary currency amount that is quasi-volatile.
+/// An arbitrary monnaie amount that is quasi-volatile.
 ///
-/// The local currency::amount_type variable is volatile, but the
-/// currency object returned is not volatile. It can't be, because
-/// class currency is not "volatile-correct", and there's no present
+/// The local monnaie::amount_type variable is volatile, but the
+/// monnaie object returned is not volatile. It can't be, because
+/// class monnaie is not "volatile-correct", and there's no present
 /// need to make it so.
 ///
-/// However, the currency value represented by the object returned is
+/// However, the monnaie value represented by the object returned is
 /// "volatile" in the sense that the compiler cannot presume to know
 /// it, so it can't be precomputed at compile time, and calculations
 /// involving it cannot be optimized into oblivion.
 
 template<>
-currency currency_test::arbitrary_amount<currency>()
+monnaie monnaie_test::arbitrary_amount<monnaie>()
 {
-    currency::amount_type volatile z(123);
-    return currency(z);
+    monnaie::amount_type volatile z(123);
+    return monnaie(z);
 }
 
 template<typename T>
@@ -231,7 +231,7 @@ inline double convert_to_double(T t)
 }
 
 template<>
-inline double convert_to_double(currency c)
+inline double convert_to_double(monnaie c)
 {
     return c.value();
 }
@@ -243,20 +243,20 @@ inline T convert_from_double(double d)
 }
 
 template<>
-inline currency convert_from_double<currency>(double d)
+inline monnaie convert_from_double<monnaie>(double d)
 {
-    return currency::from_value(d);
+    return monnaie::from_value(d);
 }
 
 template<typename T>
 void do_some_arithmetic(T t)
 {
-    T a(currency_test::arbitrary_amount<T>());
-    T b(currency_test::arbitrary_amount<T>());
-    T c(currency_test::arbitrary_amount<T>());
-    T d(currency_test::arbitrary_amount<T>());
-    T e(currency_test::arbitrary_amount<T>());
-    T f(currency_test::arbitrary_amount<T>());
+    T a(monnaie_test::arbitrary_amount<T>());
+    T b(monnaie_test::arbitrary_amount<T>());
+    T c(monnaie_test::arbitrary_amount<T>());
+    T d(monnaie_test::arbitrary_amount<T>());
+    T e(monnaie_test::arbitrary_amount<T>());
+    T f(monnaie_test::arbitrary_amount<T>());
 
     for(int j = 0; j < 1000; ++j)
         {
@@ -285,36 +285,36 @@ void mete_double()
 
 void mete_amount_type()
 {
-    currency::amount_type a(1234567);
+    monnaie::amount_type a(1234567);
     for(int j = 0; j < 1000; ++j)
         {
         do_some_arithmetic(a);
         }
 }
 
-void mete_currency()
+void mete_monnaie()
 {
-    currency c(12345, 67);
+    monnaie c(12345, 67);
     for(int j = 0; j < 1000; ++j)
         {
         do_some_arithmetic(c);
         }
 }
 
-void currency_test::test_speed()
+void monnaie_test::test_speed()
 {
     std::cout
         << "  Speed tests..."
         << "\n  double     : " << TimeAnAliquot(mete_double)
         << "\n  amount_type: " << TimeAnAliquot(mete_amount_type)
-        << "\n  currency   : " << TimeAnAliquot(mete_currency)
+        << "\n  monnaie    : " << TimeAnAliquot(mete_monnaie)
         << std::endl
         ;
 }
 
 int test_main(int, char*[])
 {
-    currency_test::test();
+    monnaie_test::test();
 
     return EXIT_SUCCESS;
 }
diff --git a/objects.make b/objects.make
index 1dd3141..f8f0839 100644
--- a/objects.make
+++ b/objects.make
@@ -446,6 +446,7 @@ unit_test_targets := \
   mc_enum_test \
   md5sum_test \
   miscellany_test \
+  monnaie_test \
   mortality_rates_test \
   name_value_pairs_test \
   ncnnnpnn_test \
@@ -840,6 +841,11 @@ miscellany_test$(EXEEXT): \
   miscellany.o \
   miscellany_test.o \
 
+monnaie_test$(EXEEXT): \
+  $(common_test_objects) \
+  monnaie_test.o \
+  timer.o \
+
 mortality_rates_test$(EXEEXT): \
   $(common_test_objects) \
   ihs_mortal.o \



reply via email to

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