[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 \