lmi-commits
[Top][All Lists]
Advanced

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



reply via email to

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