[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master dcc33f1 3/7: Replace a free function with a b
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master dcc33f1 3/7: Replace a free function with a better general implementation |
Date: |
Thu, 4 Feb 2021 16:44:32 -0500 (EST) |
branch: master
commit dcc33f1879aa889c0a092771e31f6662a10988a2
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Replace a free function with a better general implementation
Replaced local query_into() with product_database::query_into(),
which is better because:
- using the overload makes query_into() calls uniform;
- the overload throws if value is not preserved when the double
in the database is converted to currency (rounded to nearest cent);
- the local function rounded with 'round_minutiae', silently discarding
any excess precision in the database value; now, assertions fire if
the currency amount (rounded to nearest cent) is more precise than
the datum-specific rounding (here, 'round_minutiae') allows.
Alternative not chosen: pass the rounding function object as an extra
query_into() argument, and use it there to assert appropriate rounding
precision--but that would make the calls non-uniform.
A profoundly different design would use currency<rounding_parameters>
instead of just currency, throughout lmi. Thus, specified-amount limit
might be of some hypothetical type such as:
currency<1,r_downward> MinRenlSpecAmt;
if it is to be rounded downward to one decimal. Then the "alternative"
above wouldn't require passing the rounding function object, because it
would be encoded in the (hypothetical) currency type. However, currency
types would no longer be simply additive: what would be the result of
operator+(currency<1,r_downward>,currency<0,r_to_nearest>)
? The answer would depend on the (currency) type into which the result
is to be assigned, which is why lmi specified rounding on assignment:
currency X = round_however.c(new_value);
---
loads.cpp | 53 +++++++++++++++++++++++++++++++++++------------------
1 file changed, 35 insertions(+), 18 deletions(-)
diff --git a/loads.cpp b/loads.cpp
index 021de45..236ecf6 100644
--- a/loads.cpp
+++ b/loads.cpp
@@ -34,21 +34,10 @@
#include "mc_enum_types_aux.hpp" // mc_n_ enumerators
#include "oecumenic_enumerations.hpp"
#include "premium_tax.hpp"
+#include "round_to.hpp"
namespace
{
-void query_into
- (product_database const& database
- ,e_database_key key
- ,std::vector<currency>& v
- ,round_to<double> const& round_minutiae
- )
-{
- std::vector<double> z;
- database.query_into(key, z);
- v = round_minutiae.c(z);
-}
-
void assign_midpoint
(std::vector<currency> & out
,std::vector<currency> const& in_0
@@ -151,8 +140,8 @@ void Loads::Initialize(product_database const& database,
load_details const& det
database.query_into(DB_LoadRfdProportion ,
refundable_sales_load_proportion_ );
database.query_into(DB_DacTaxPremLoad , dac_tax_load_
);
- query_into(database, DB_GuarMonthlyPolFee, monthly_policy_fee_
[mce_gen_guar], r);
- query_into(database, DB_GuarAnnualPolFee , annual_policy_fee_
[mce_gen_guar], r);
+ database.query_into(DB_GuarMonthlyPolFee , monthly_policy_fee_
[mce_gen_guar]);
+ database.query_into(DB_GuarAnnualPolFee , annual_policy_fee_
[mce_gen_guar]);
database.query_into(DB_GuarSpecAmtLoad ,
specified_amount_load_[mce_gen_guar]);
database.query_into(DB_GuarAcctValLoad ,
separate_account_load_[mce_gen_guar]);
database.query_into(DB_GuarPremLoadTgt , target_premium_load_
[mce_gen_guar]);
@@ -160,14 +149,32 @@ void Loads::Initialize(product_database const& database,
load_details const& det
database.query_into(DB_GuarPremLoadTgtRfd, target_sales_load_
[mce_gen_guar]);
database.query_into(DB_GuarPremLoadExcRfd, excess_sales_load_
[mce_gen_guar]);
- query_into(database, DB_CurrMonthlyPolFee, monthly_policy_fee_
[mce_gen_curr], r);
- query_into(database, DB_CurrAnnualPolFee , annual_policy_fee_
[mce_gen_curr], r);
+ database.query_into(DB_CurrMonthlyPolFee , monthly_policy_fee_
[mce_gen_curr]);
+ database.query_into(DB_CurrAnnualPolFee , annual_policy_fee_
[mce_gen_curr]);
database.query_into(DB_CurrSpecAmtLoad ,
specified_amount_load_[mce_gen_curr]);
database.query_into(DB_CurrAcctValLoad ,
separate_account_load_[mce_gen_curr]);
database.query_into(DB_CurrPremLoadTgt , target_premium_load_
[mce_gen_curr]);
database.query_into(DB_CurrPremLoadExc , excess_premium_load_
[mce_gen_curr]);
database.query_into(DB_CurrPremLoadTgtRfd, target_sales_load_
[mce_gen_curr]);
database.query_into(DB_CurrPremLoadExcRfd, excess_sales_load_
[mce_gen_curr]);
+
+ // Make sure database contents have no excess precision.
+ LMI_ASSERT(std::operator==
+ (r.c(monthly_policy_fee_ [mce_gen_guar])
+ , monthly_policy_fee_ [mce_gen_guar]
+ ));
+ LMI_ASSERT(std::operator==
+ (r.c(annual_policy_fee_ [mce_gen_guar])
+ , annual_policy_fee_ [mce_gen_guar]
+ ));
+ LMI_ASSERT(std::operator==
+ (r.c(monthly_policy_fee_ [mce_gen_curr])
+ , monthly_policy_fee_ [mce_gen_curr]
+ ));
+ LMI_ASSERT(std::operator==
+ (r.c(annual_policy_fee_ [mce_gen_curr])
+ , annual_policy_fee_ [mce_gen_curr]
+ ));
}
/// Transform raw input and database data into directly-useful rates.
@@ -380,16 +387,26 @@ Loads::Loads(product_database const& database, bool
NeedMidpointRates)
excess_premium_load_ .resize(mc_n_gen_bases);
specified_amount_load_.resize(mc_n_gen_bases);
- query_into(database, DB_GuarMonthlyPolFee, monthly_policy_fee_
[mce_gen_guar], r);
+ database.query_into(DB_GuarMonthlyPolFee , monthly_policy_fee_
[mce_gen_guar]);
database.query_into(DB_GuarPremLoadTgt , target_premium_load_
[mce_gen_guar]);
database.query_into(DB_GuarPremLoadExc , excess_premium_load_
[mce_gen_guar]);
database.query_into(DB_GuarSpecAmtLoad ,
specified_amount_load_[mce_gen_guar]);
- query_into(database, DB_CurrMonthlyPolFee, monthly_policy_fee_
[mce_gen_curr], r);
+ database.query_into(DB_CurrMonthlyPolFee , monthly_policy_fee_
[mce_gen_curr]);
database.query_into(DB_CurrPremLoadTgt , target_premium_load_
[mce_gen_curr]);
database.query_into(DB_CurrPremLoadExc , excess_premium_load_
[mce_gen_curr]);
database.query_into(DB_CurrSpecAmtLoad ,
specified_amount_load_[mce_gen_curr]);
+ // Make sure database contents have no excess precision.
+ LMI_ASSERT(std::operator==
+ (r.c(monthly_policy_fee_ [mce_gen_guar])
+ , monthly_policy_fee_ [mce_gen_guar]
+ ));
+ LMI_ASSERT(std::operator==
+ (r.c(monthly_policy_fee_ [mce_gen_curr])
+ , monthly_policy_fee_ [mce_gen_curr]
+ ));
+
// This ctor ignores tabular specified-amount loads.
if(NeedMidpointRates)
- [lmi-commits] [lmi] master updated (53a8634 -> 62c89fd), Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 8738f07 5/7: Improve concinnity of database descriptions, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master a8e24b0 6/7: Rectify a strange test for infinity, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 62c89fd 7/7: Use currency type for some potentially-infinite limits, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 2cf0e24 1/7: Overload query_into() for currency, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 0d94134 2/7: Note a possible improvement, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master dcc33f1 3/7: Replace a free function with a better general implementation,
Greg Chicares <=
- [lmi-commits] [lmi] master 48aa040 4/7: Use recently added query_into() overload for currency, Greg Chicares, 2021/02/04