void premium_tax::test_consistency() const { if(varies_by_state_ && !load_rate_is_levy_rate_) { fatal_error() << "Premium-tax load varies by state, but differs" << " from premium-tax rates. Probably the database" << " is incorrect.\n" << LMI_FLUSH ; } if(is_tiered_in_tax_state_) { if(0.0 != tax_state_load_rate_) { fatal_error() << "Premium-tax load is tiered in premium-tax state " << mc_str(tax_state_) << ", but the product database specifies a scalar load of " << tax_state_load_rate_ << " instead of zero as expected. Probably the database" << " is incorrect." << LMI_FLUSH ; } } if(is_tiered_in_domicile_) { if(0.0 != domiciliary_load_rate_) { fatal_error() << "Premium-tax load is tiered in state of domicile " << mc_str(domicile_) << ", but the product database specifies a scalar load of " << domiciliary_load_rate_ << " instead of zero as expected. Probably the database" << " is incorrect." << LMI_FLUSH ; } fatal_error() << "Premium-tax load is tiered in state of domicile " << mc_str(domicile_) << ", but that case is not supported." << LMI_FLUSH ; } }
static int imgview_load_resource(imgview_t* iv, HINSTANCE instance, void* res_name, BOOL unicode) { gdix_Image* image; if(res_name != NULL) { TCHAR* tmp; if(unicode == MC_IS_UNICODE) { tmp = res_name; } else { tmp = mc_str(res_name, (unicode ? MC_STRW : MC_STRA), MC_STRT); if(MC_ERR(tmp == NULL)) { MC_TRACE("imgview_load_resource: mc_str() failed."); return -1; } } image = imgview_load_image_from_resource(instance, res_name); if(tmp != res_name) free(tmp); if(MC_ERR(image == NULL)) { MC_TRACE("imgview_load_resource: imgview_load_image_from_resource() failed"); return -1; } } else { image = NULL; } if(iv->image) gdix_DisposeImage(iv->image); iv->image = image; return 0; }
static int imgview_load_file(imgview_t* iv, void* path, BOOL unicode) { gdix_Image* image; if(path != NULL) { WCHAR* tmp; if(unicode) { tmp = path; } else { tmp = mc_str(path, MC_STRA, MC_STRW); if(MC_ERR(tmp == NULL)) { MC_TRACE("imgview_load_file: mc_str() failed."); return -1; } } image = imgview_load_image_from_file(tmp); if(tmp != path) free(tmp); if(MC_ERR(image == NULL)) { MC_TRACE("imgview_load_file: imgview_load_image_from_file() failed"); return -1; } } else { image = NULL; } if(iv->image) gdix_DisposeImage(iv->image); iv->image = image; return 0; }
static LRESULT html_notify_text(html_t* html, UINT code, const WCHAR* text) { /* Note we shamelessly misuse this also for URL notifications, as the * MC_NMHTMLURL and MC_NMHTMLTEXT are binary compatible. * They are separate mainly for historical reasons. */ MC_NMHTMLTEXTW notify; LRESULT res; BOOL need_free = FALSE; HTML_TRACE("html_notify_text: code=%d str='%S'", code, text ? text : L"[null]"); notify.hdr.hwndFrom = html->win; notify.hdr.idFrom = GetDlgCtrlID(html->win); notify.hdr.code = code; if(text == NULL) { notify.pszText = L""; } else if(html->unicode_notifications) { notify.pszText = text; } else { notify.pszText = (WCHAR*) mc_str(text, MC_STRW, MC_STRA); need_free = TRUE; } res = MC_SEND(html->notify_win, WM_NOTIFY, notify.hdr.idFrom, ¬ify); if(need_free) free((WCHAR*)notify.pszText); return res; }
static BSTR html_bstr(const void* from_str, int from_type) { WCHAR* str_w; BSTR str_b; if(from_str == NULL) { /* According to MSDN, BSTR should never be NULL. */ from_str = L""; from_type = MC_STRW; } if(from_type == MC_STRW) { str_w = (WCHAR*) from_str; } else { char* str_a; MC_ASSERT(from_type == MC_STRA); str_a = (char*) from_str; str_w = (WCHAR*) mc_str(str_a, from_type, MC_STRW); if(MC_ERR(str_w == NULL)) { MC_TRACE("html_bstr: mc_str() failed."); return NULL; } } str_b = html_SysAllocString(str_w); if(MC_ERR(str_b == NULL)) MC_TRACE("html_bstr: SysAllocString() failed."); if(str_w != from_str) free(str_w); return str_b; }
static BSTR html_bstr(const void* from_str, int from_type) { WCHAR* str_w; BSTR str_b; if(from_str == NULL) return NULL; if(from_type == MC_STRW) { str_w = (WCHAR*) from_str; if(str_w[0] == L'\0') return NULL; } else { char* str_a; MC_ASSERT(from_type == MC_STRA); str_a = (char*) from_str; if(str_a[0] == '\0') return NULL; str_w = (WCHAR*) mc_str(str_a, from_type, MC_STRW); if(MC_ERR(str_w == NULL)) { MC_TRACE("html_bstr: mc_str() failed."); return NULL; } } str_b = html_SysAllocString(str_w); if(MC_ERR(str_b == NULL)) MC_TRACE("html_bstr: SysAllocString() failed."); if(from_type == MC_STRA) free(str_w); return str_b; }
int table_set_cell_data(table_t* table, WORD col, WORD row, MC_TABLECELL* cell_data, BOOL unicode) { table_cell_t* cell; table_refresh_detail_t refresh_detail; TABLE_TRACE("table_set_cell_data(%p, %hd, %hd, %p, %s)", table, col, row, cell_data, (unicode ? "unicode" : "ansi")); cell = table_get_cell(table, col, row); if(MC_ERR(cell == NULL)) { MC_TRACE("table_set_cell_data: table_get_cell() failed."); return -1; } if(MC_ERR(cell_data->fMask & ~MC_TCMF_ALL)) { MC_TRACE("table_set_cell_data: Unsupported pCell->fMask 0x%x", cell_data->fMask); SetLastError(ERROR_INVALID_PARAMETER); return -1; } /* Set the cell */ if(cell_data->fMask & MC_TCMF_TEXT) { TCHAR* str; if(cell_data->pszText == MC_LPSTR_TEXTCALLBACK) { str = MC_LPSTR_TEXTCALLBACK; } else if(cell_data->pszText != NULL) { str = mc_str(cell_data->pszText, (unicode ? MC_STRW : MC_STRA), MC_STRT); if(MC_ERR(str == NULL)) { MC_TRACE("table_set_cell_data: mc_str() failed."); return -1; } } else { str = NULL; } table_cell_clear(cell); cell->text = str; } if(cell_data->fMask & MC_TCMF_PARAM) cell->lp = cell_data->lParam; if(cell_data->fMask & MC_TCMF_FLAGS) cell->flags = cell_data->dwFlags; /* Refresh */ refresh_detail.event = TABLE_CELL_CHANGED; refresh_detail.param[0] = col; refresh_detail.param[1] = row; table_refresh(table, &refresh_detail); return 0; }
static value_t* __stdcall strw_ctor_str(const TCHAR* str) { value_t* v; v = (value_t*) malloc(sizeof(value_t) + sizeof(WCHAR*)); if(MC_ERR(v == NULL)) return NULL; VALUE_DATA(v, WCHAR*) = mc_str(str, MC_STRT, MC_STRW); if(MC_ERR(VALUE_DATA(v, WCHAR*) == NULL)) { free(v); return NULL; } return (MC_HVALUE) v; }
census_run_result run_census_in_parallel::operator() (fs::path const& file ,mcenum_emission const emission ,std::vector<Input> const& cells ,Ledger & composite ) { Timer timer; census_run_result result; boost::shared_ptr<progress_meter> meter (create_progress_meter (cells.size() ,"Initializing all cells" ,progress_meter_mode(emission) ) ); ledger_emitter emitter(file, emission); std::vector<Input>::const_iterator ip; std::vector<boost::shared_ptr<AccountValue> > cell_values; std::vector<boost::shared_ptr<AccountValue> >::iterator i; std::vector<mcenum_run_basis> const& RunBases = composite.GetRunBases(); int j = 0; int const first_cell_inforce_year = value_cast<int>((*cells.begin())["InforceYear"].str()); int const first_cell_inforce_month = value_cast<int>((*cells.begin())["InforceMonth"].str()); cell_values.reserve(cells.size()); for(ip = cells.begin(); ip != cells.end(); ++ip, ++j) { // This condition need be written only once, here, because // subsequently 'cell_values' (which reflects the condition) // is iterated across instead of 'cells'. if(!cell_should_be_ignored(cells[j])) { { // Begin fenv_guard scope. fenv_guard fg; boost::shared_ptr<AccountValue> av(new AccountValue(*ip)); std::string const name(cells[j]["InsuredName"].str()); av->SetDebugFilename (serial_file_path(file, name, j, "hastur").string() ); cell_values.push_back(av); if(contains(av->yare_input_.Comments, "idiosyncrasyZ")) { av->Debugging = true; av->DebugPrintInit(); } if ( first_cell_inforce_year != av->yare_input_.InforceYear || first_cell_inforce_month != av->yare_input_.InforceMonth ) { fatal_error() << "Running census by month untested for inforce" << " with inforce duration varying across cells." << LMI_FLUSH ; } if(mce_solve_none != av->yare_input_.SolveType) { fatal_error() << "Running census by month: solves not permitted." << LMI_FLUSH ; } } // End fenv_guard scope. } if(!meter->reflect_progress()) { result.completed_normally_ = false; goto done; } } // End for. meter->culminate(); if(cell_values.empty()) { // Make sure it's safe to dereference cell_values[0] later. fatal_error() << "No cell with any lives was included in the composite." << LMI_FLUSH ; } for (std::vector<mcenum_run_basis>::const_iterator run_basis = RunBases.begin() ;run_basis != RunBases.end() ;++run_basis ) { // It seems somewhat anomalous to create and update a GUI // progress meter inside this critical calculation section, // because it is not entirely inconceivable that doing so // might affect the floating-point control word. However, // rogue msw dlls that improperly alter the control word // seem to do so when they are initially loaded, and any // such dll would already have been loaded to support the // progress meter used earlier in this function. { // Begin fenv_guard scope. fenv_guard fg; mcenum_gen_basis expense_and_general_account_basis; mcenum_sep_basis separate_account_basis; set_cloven_bases_from_run_basis (*run_basis ,expense_and_general_account_basis ,separate_account_basis ); // Calculate duration when the youngest life matures. int MaxYr = 0; for(i = cell_values.begin(); i != cell_values.end(); ++i) { (*i)->InitializeLife(*run_basis); MaxYr = std::max(MaxYr, (*i)->GetLength()); } meter = create_progress_meter (MaxYr - first_cell_inforce_year ,mc_str(*run_basis) ,progress_meter_mode(emission) ); // Variables to support tiering and experience rating. double const case_ibnr_months = cell_values[0]->ibnr_as_months_of_mortality_charges() ; double const case_experience_rating_amortization_years = cell_values[0]->experience_rating_amortization_years() ; double case_accum_net_mortchgs = 0.0; double case_accum_net_claims = 0.0; double case_k_factor = cell_values[0]->yare_input_.ExperienceRatingInitialKFactor; // Experience rating as implemented here uses either a special // scalar input rate, or the separate-account rate. Those // rates as entered might vary across cells, but there must be // only one rate: therefore, use the first cell's rate, and // extend its last element if it doesn't have enough values. std::vector<double> experience_reserve_rate; std::copy (cell_values[0]->yare_input_.SeparateAccountRate.begin() ,cell_values[0]->yare_input_.SeparateAccountRate.end() ,std::back_inserter(experience_reserve_rate) ); experience_reserve_rate.resize(MaxYr, experience_reserve_rate.back()); if(cell_values[0]->yare_input_.OverrideExperienceReserveRate) { experience_reserve_rate.assign (experience_reserve_rate.size() ,cell_values[0]->yare_input_.ExperienceReserveRate ); } for(int year = first_cell_inforce_year; year < MaxYr; ++year) { double experience_reserve_annual_u = 1.0 + experience_reserve_rate[year] ; for(i = cell_values.begin(); i != cell_values.end(); ++i) { // A cell must be initialized at the beginning of any // partial inforce year in which it's illustrated. if((*i)->PrecedesInforceDuration(year, 11)) { continue; } (*i)->Year = year; (*i)->CoordinateCounters(); (*i)->InitializeYear(); } // Process one month at a time for all cells. int const inforce_month = first_cell_inforce_year == year ? first_cell_inforce_month : 0 ; for(int month = inforce_month; month < 12; ++month) { double assets = 0.0; // Get total case assets prior to interest crediting because // those assets may determine the M&E charge. // Process transactions through monthly deduction. for(i = cell_values.begin(); i != cell_values.end(); ++i) { if((*i)->PrecedesInforceDuration(year, month)) { continue; } (*i)->Month = month; (*i)->CoordinateCounters(); (*i)->IncrementBOM(year, month, case_k_factor); assets += (*i)->GetSepAcctAssetsInforce(); } // Process transactions from int credit through end of month. for(i = cell_values.begin(); i != cell_values.end(); ++i) { if((*i)->PrecedesInforceDuration(year, month)) { continue; } (*i)->IncrementEOM(year, month, assets, (*i)->CumPmts); } } // Perform end of year calculations. // Project claims using the partial-mortality rate: // it's curtate, so the whole year's claims occur at // the end of the last month and no interest // adjustment is required. // // An off-anniversary inforce case generates a full // year's claims, which is consistent with curtate // mortality. double eoy_inforce_lives = 0.0; double years_net_claims = 0.0; double years_net_mortchgs = 0.0; double projected_net_mortchgs = 0.0; for(i = cell_values.begin(); i != cell_values.end(); ++i) { if((*i)->PrecedesInforceDuration(year, 11)) { continue; } (*i)->SetClaims(); (*i)->SetProjectedCoiCharge(); eoy_inforce_lives += (*i)->InforceLivesEoy(); (*i)->IncrementEOY(year); years_net_claims += (*i)->GetCurtateNetClaimsInforce(); years_net_mortchgs += (*i)->GetCurtateNetCoiChargeInforce(); projected_net_mortchgs += (*i)->GetProjectedCoiChargeInforce(); } // Calculate next year's k factor. Do this only for // current-expense bases, not as a speed optimization, // but rather because experience rating on other bases // is undefined. case_accum_net_claims *= experience_reserve_annual_u; case_accum_net_claims += years_net_claims; case_accum_net_mortchgs *= experience_reserve_annual_u; case_accum_net_mortchgs += years_net_mortchgs; // Presumably an admin system would maintain a scalar // reserve instead of tracking claims and mortality // charges separately, and accumulate it at interest more // frequently than once a year. // // Therefore, add inforce reserve here, to avoid crediting // a year's interest to it. Because only a scalar reserve // is captured, it must all be added to one side of the // reserve equation: the distinction between claims and // mortality charges is lost, but their difference is // preserved, so the resulting reserve is correct. // // The inforce reserve would reflect net claims already // paid as well as mortality charges already deducted for // any partial year. Therefore, although inforce YTD COI // charge is captured separately for adjusting IBNR, it // would be incorrect to add it here. if(first_cell_inforce_year == year) { case_accum_net_mortchgs += cell_values[0]->yare_input_.InforceNetExperienceReserve; } // Apportion experience-rating reserve uniformly across // inforce lives. Previously, it had been apportioned by // projected mortality charges; that proved unworkable // when a cell lapsed, matured, or failed to have a // nonzero NAAR due to a corridor factor of unity. To // guard against such problems, the apportioned reserve // is summed across cells and asserted materially to // equal the original total reserve. if ( cell_values[0]->yare_input_.UseExperienceRating && mce_gen_curr == expense_and_general_account_basis && 0.0 != eoy_inforce_lives ) { if(first_cell_inforce_year == year) { years_net_mortchgs += cell_values[0]->yare_input_.InforceYtdNetCoiCharge; } double case_ibnr = years_net_mortchgs * case_ibnr_months / 12.0 ; double case_net_mortality_reserve = case_accum_net_mortchgs - case_accum_net_claims - case_ibnr ; // Current net mortality charge can actually be zero, // e.g., when the corridor factor is unity. double denominator = case_experience_rating_amortization_years * projected_net_mortchgs ; if(0.0 == denominator) { case_k_factor = 1.0; } else { case_k_factor = std::max (0.0 ,1.0 - case_net_mortality_reserve / denominator ); } double case_net_mortality_reserve_checksum = 0.0; for(i = cell_values.begin(); i != cell_values.end(); ++i) { if((*i)->PrecedesInforceDuration(year, 11)) { continue; } case_net_mortality_reserve_checksum += (*i)->ApportionNetMortalityReserve ( case_net_mortality_reserve / eoy_inforce_lives ); } if (!materially_equal (case_net_mortality_reserve ,case_net_mortality_reserve_checksum ) ) { fatal_error() << "\nExperience-rating reserve discrepancy in year " << year << ": " << case_net_mortality_reserve << " != " << case_net_mortality_reserve_checksum << LMI_FLUSH ; } } if(!meter->reflect_progress()) { result.completed_normally_ = false; goto done; } } // End for year. meter->culminate(); for(i = cell_values.begin(); i != cell_values.end(); ++i) { (*i)->FinalizeLife(*run_basis); } } // End fenv_guard scope. } // End for. meter = create_progress_meter (cell_values.size() ,"Finalizing all cells" ,progress_meter_mode(emission) ); for(i = cell_values.begin(); i != cell_values.end(); ++i) { fenv_guard fg; (*i)->FinalizeLifeAllBases(); composite.PlusEq(*(*i)->ledger_from_av()); if(!meter->reflect_progress()) { result.completed_normally_ = false; goto done; } } meter->culminate(); result.seconds_for_output_ += emitter.initiate(); meter = create_progress_meter (cell_values.size() ,"Writing output for all cells" ,progress_meter_mode(emission) ); for(j = 0, i = cell_values.begin(); i != cell_values.end(); ++i, ++j) { std::string const name(cells[j]["InsuredName"].str()); result.seconds_for_output_ += emitter.emit_cell (serial_file_path(file, name, j, "hastur") ,*(*i)->ledger_from_av() ); meter->dawdle(intermission_between_printouts(emission)); if(!meter->reflect_progress()) { result.completed_normally_ = false; goto done; } } meter->culminate(); result.seconds_for_output_ += emitter.emit_cell (serial_file_path(file, "composite", -1, "hastur") ,composite ); result.seconds_for_output_ += emitter.finish(); done: double total_seconds = timer.stop().elapsed_seconds(); status() << Timer::elapsed_msec_str(total_seconds) << std::flush; result.seconds_for_calculations_ = total_seconds - result.seconds_for_output_; return result; }
//============================================================================ // To add a new column, see ihs_dbughdr.hpp . void AccountValue::DebugPrint() { if(!Debugging || Solving || SolvingForGuarPremium) { return; // Show detail on final run, not every solve iteration. } DebugRecord.assign(eLast, "EMPTY"); SetMonthlyDetail(eYear ,Year); SetMonthlyDetail(eMonth ,Month); SetMonthlyDetail(eBasis ,mc_str(RunBasis_)); SetMonthlyDetail(eAge ,InvariantValues().Age + Year); // Initial values at beginning of run, reflecting inforce if applicable. if(InforceYear == Year && InforceMonth == Month) { PriorAVGenAcct = InforceAVGenAcct; PriorAVSepAcct = InforceAVSepAcct; PriorAVRegLn = InforceAVRegLn; PriorAVPrfLn = InforceAVPrfLn; PriorRegLnBal = InforceRegLnBal; PriorPrfLnBal = InforcePrfLnBal; } // Beginning of month values. SetMonthlyDetail(eGenAcctBOMAV ,PriorAVGenAcct); SetMonthlyDetail(eSepAcctBOMAV ,PriorAVSepAcct); SetMonthlyDetail(eUnloanedBOMAV ,PriorAVGenAcct + PriorAVSepAcct); SetMonthlyDetail(eRegularLoanBOMAV ,PriorAVRegLn); SetMonthlyDetail(ePrefLoanBOMAV ,PriorAVPrfLn); SetMonthlyDetail (eTotalBOMAV ,PriorAVGenAcct + PriorAVSepAcct + PriorAVRegLn + PriorAVPrfLn ); PriorAVGenAcct = AVGenAcct; PriorAVSepAcct = AVSepAcct; PriorAVRegLn = AVRegLn; PriorAVPrfLn = AVPrfLn; // TODO ?? Should loan balance columns be similarly offset? SetMonthlyDetail(eRegLoanBal ,RegLnBal ); SetMonthlyDetail(ePrefLoanBal ,PrfLnBal ); SetMonthlyDetail(eDBOption ,mc_str(YearsDBOpt) ); SetMonthlyDetail(eSpecAmt ,ActualSpecAmt ); SetMonthlyDetail(eCorridorFactor ,YearsCorridorFactor ); SetMonthlyDetail(eDeathBft ,DBReflectingCorr ); SetMonthlyDetail(eForceout ,GptForceout ); SetMonthlyDetail(eEePrem ,EeGrossPmts[Month] ); SetMonthlyDetail(eErPrem ,ErGrossPmts[Month] ); SetMonthlyDetail(eTotalPrem ,GrossPmts[Month] ); SetMonthlyDetail(eTargetPrem ,AnnualTargetPrem ); SetMonthlyDetail(ePremiumLoad ,premium_load_ ); SetMonthlyDetail(eSalesLoad ,sales_load_ ); SetMonthlyDetail(ePremiumTaxLoad ,premium_tax_load_ ); SetMonthlyDetail(eDacTaxLoad ,dac_tax_load_ ); SetMonthlyDetail(eNetPrem ,NetPmts[Month] ); SetMonthlyDetail(ePolicyFees ,MonthsPolicyFees ); SetMonthlyDetail(eSpecAmtLoad ,SpecAmtLoad ); SetMonthlyDetail(eNAAR ,NAAR ); SetMonthlyDetail(eCoiRate ,ActualCoiRate ); SetMonthlyDetail(eCoiCharge ,CoiCharge ); SetMonthlyDetail(eAdbRate ,YearsAdbRate ); SetMonthlyDetail(eAdbCharge ,AdbCharge ); SetMonthlyDetail(eWpRate ,YearsWpRate ); SetMonthlyDetail(eWpCharge ,WpCharge ); SetMonthlyDetail(eTermAmount ,TermDB ); SetMonthlyDetail(eTermRate ,YearsTermRate ); SetMonthlyDetail(eTermCharge ,TermCharge ); SetMonthlyDetail(eTotalRiderCharges ,RiderCharges ); SetMonthlyDetail(eTotalMonthlyDeds ,MlyDed ); SetMonthlyDetail(eGenAcctIntRate ,ActualMonthlyRate(YearsGenAcctIntRate )); SetMonthlyDetail(eGenAcctIntCred ,GenAcctIntCred ); SetMonthlyDetail(eSepAcctIntRate ,ActualMonthlyRate(YearsSepAcctIntRate )); SetMonthlyDetail(eSepAcctIntCred ,SepAcctIntCred ); SetMonthlyDetail(eAssetsPostBom ,AssetsPostBom ); SetMonthlyDetail(eCumPmtsPostBom ,CumPmtsPostBom ); SetMonthlyDetail(eSepAcctLoad ,SepAcctLoad ); SetMonthlyDetail(eRegLnIntRate ,ActualMonthlyRate(YearsRegLnIntCredRate )); SetMonthlyDetail(eRegLnIntCred ,RegLnIntCred ); SetMonthlyDetail(ePrfLnIntRate ,ActualMonthlyRate(YearsPrfLnIntCredRate )); SetMonthlyDetail(ePrfLnIntCred ,PrfLnIntCred ); SetMonthlyDetail(eYearsHMValueRate ,ActualMonthlyRate(YearsHoneymoonValueRate )); SetMonthlyDetail(eYearsPostHMRate ,ActualMonthlyRate(YearsPostHoneymoonGenAcctIntRate )); // Items that are used only on anniversary. if(0 == Month) { SetMonthlyDetail(eRequestedWD ,RequestedWD ); SetMonthlyDetail(eMaxWD ,MaxWD ); SetMonthlyDetail(eGrossWD ,GrossWD ); SetMonthlyDetail(eNetWD ,NetWD ); SetMonthlyDetail(eRequestedLoan ,RequestedLoan ); SetMonthlyDetail(eMaxLoan ,MaxLoan ); SetMonthlyDetail(eNewLoan ,ActualLoan ); } else { SetMonthlyDetail(eRequestedWD ,not_applicable() ); SetMonthlyDetail(eMaxWD ,not_applicable() ); SetMonthlyDetail(eGrossWD ,not_applicable() ); SetMonthlyDetail(eNetWD ,not_applicable() ); SetMonthlyDetail(eRequestedLoan ,not_applicable() ); SetMonthlyDetail(eMaxLoan ,not_applicable() ); SetMonthlyDetail(eNewLoan ,not_applicable() ); } SetMonthlyDetail(eTaxBasis ,TaxBasis ); SetMonthlyDetail(eCumNoLapsePrem ,CumNoLapsePrem ); SetMonthlyDetail(eNoLapseActive ,NoLapseActive ); SetMonthlyDetail(eEOMAV ,TotalAccountValue() ); SetMonthlyDetail(eHMValue ,std::max(HoneymoonValue, 0.0) ); SetMonthlyDetail(eSurrChg ,SurrChg() ); // TODO ?? Unfortunately duplicated from AccountValue::FinalizeYear(). double total_av = TotalAccountValue(); double csv_net = total_av - SurrChg() - RegLnBal + GetRefundableSalesLoad() // + std::max(0.0, ExpRatReserve) // This would be added if it existed. ; csv_net = std::max(HoneymoonValue, csv_net); SetMonthlyDetail(eEOMCSVNet ,csv_net ); SetMonthlyDetail(eEOMCV7702 ,CashValueFor7702() ); LMI_ASSERT(0 != yare_input_.NumberOfIdenticalLives); SetMonthlyDetail (eInforceFactor ,ItLapsed ? 0.0 : InvariantValues().InforceLives[Year] / yare_input_.NumberOfIdenticalLives ); // TODO ?? Claims appear as zero because SetClaims() is called not // at the end of each month (before DebugPrint() is called), but // at the end of each year (after DebugPrint() has been called). // The monthly-detail facility should be redesigned anyway to be // useful for composites. And it should show 'YearsNetClaims' and // 'YearsDeathProceeds' as well as 'YearsGrossClaims', but adding // the others is pointless as long as they would be zero. SetMonthlyDetail(eClaimsPaid ,YearsGrossClaims ); bool irc7702a_data_irrelevant = InvariantValues().MecYear < Year || InvariantValues().MecYear == Year && InvariantValues().MecMonth < Month || mce_run_gen_curr_sep_full != RunBasis_ ; if(!irc7702a_data_irrelevant) { SetMonthlyDetail(e7702ATestDur ,Irc7702A_->DebugGetTestDur ()); SetMonthlyDetail(e7702A7ppRate ,Irc7702A_->DebugGet7ppRate ()); SetMonthlyDetail(e7702ANsp ,Irc7702A_->DebugGetNsp ()); SetMonthlyDetail(e7702ALowestDb ,Irc7702A_->DebugGetLowestBft()); // This one's a little tricky. We show the DCV actually used in // material change calculations, iff there is a material change // in the current month. Otherwise, we show the DCV at the end // of the month; we could have shown zero instead, but that // wouldn't be useful. We could always have shown DCV at the end // of the month, but that wouldn't show what was actually used in // material change processing. SetMonthlyDetail (e7702ADeemedCv ,Irc7702A_->DebugGetIsMatChg() ? Irc7702A_->DebugGetSavedDCV() : Dcv ); SetMonthlyDetail(e7702ANetMaxNecPm ,NetMaxNecessaryPremium ); SetMonthlyDetail(e7702AGrossMaxNecPm ,GrossMaxNecessaryPremium ); SetMonthlyDetail(e7702AUnnecPm ,UnnecessaryPremium ); SetMonthlyDetail(e7702ADbAdj ,Irc7702A_->DebugGetDbAdj ()); SetMonthlyDetail(e7702A7pp ,Irc7702A_->DebugGet7pp ()); SetMonthlyDetail(e7702ACum7pp ,Irc7702A_->DebugGetCum7pp ()); SetMonthlyDetail(e7702AAmountsPaid ,Irc7702A_->DebugGetCumPmts ()); } else { SetMonthlyDetail(e7702ATestDur ,not_applicable() ); SetMonthlyDetail(e7702A7ppRate ,not_applicable() ); SetMonthlyDetail(e7702ANsp ,not_applicable() ); SetMonthlyDetail(e7702ALowestDb ,not_applicable() ); SetMonthlyDetail(e7702ADeemedCv ,not_applicable() ); SetMonthlyDetail(e7702ANetMaxNecPm ,not_applicable() ); SetMonthlyDetail(e7702AGrossMaxNecPm ,not_applicable() ); SetMonthlyDetail(e7702AUnnecPm ,not_applicable() ); SetMonthlyDetail(e7702ADbAdj ,not_applicable() ); SetMonthlyDetail(e7702A7pp ,not_applicable() ); SetMonthlyDetail(e7702ACum7pp ,not_applicable() ); SetMonthlyDetail(e7702AAmountsPaid ,not_applicable() ); } SetMonthlyDetail(e7702AIsMec ,InvariantValues().IsMec ); bool irc7702_data_irrelevant = mce_gpt != DefnLifeIns_ || mce_run_gen_curr_sep_full != RunBasis_ ; if(!irc7702_data_irrelevant) { SetMonthlyDetail(eGLP ,Irc7702_->glp ()); SetMonthlyDetail(eCumGLP ,Irc7702_->cum_glp ()); SetMonthlyDetail(eGSP ,Irc7702_->gsp ()); SetMonthlyDetail(e7702PremiumsPaid ,Irc7702_->premiums_paid ()); } else { SetMonthlyDetail(eGLP ,not_applicable() ); SetMonthlyDetail(eCumGLP ,not_applicable() ); SetMonthlyDetail(eGSP ,not_applicable() ); SetMonthlyDetail(e7702PremiumsPaid ,not_applicable() ); } std::copy (DebugRecord.begin() ,DebugRecord.end() ,std::ostream_iterator<std::string>(DebugStream, "\t") ); DebugStream << '\n'; DebugRecord.assign(eLast, "EMPTY"); }
static void grid_get_dispinfo(grid_t* grid, WORD col, WORD row, table_cell_t* cell, grid_dispinfo_t* di, DWORD mask) { MC_NMGDISPINFO info; MC_ASSERT((mask & ~(MC_TCMF_TEXT | MC_TCMF_VALUE | MC_TCMF_FLAGS)) == 0); /* Use what can be taken from the cell. */ if(cell != NULL) { if(cell->text != MC_LPSTR_TEXTCALLBACK) { di->text = (cell->is_value ? NULL : cell->text); mask &= ~MC_TCMF_TEXT; } di->value = (cell->is_value ? cell->value : NULL); di->flags = cell->flags; mask &= ~(MC_TCMF_VALUE | MC_TCMF_FLAGS); if(mask == 0) return; } /* For the rest data, fire MC_GN_GETDISPINFO notification. */ info.hdr.hwndFrom = grid->win; info.hdr.idFrom = GetWindowLong(grid->win, GWL_ID); info.hdr.code = (grid->unicode_notifications ? MC_GN_GETDISPINFOW : MC_GN_GETDISPINFOA); info.wColumn = col; info.wRow = row; info.cell.fMask = mask; /* Set info.cell members to meaningful values. lParam may be needed by the * app to find the requested data. Other members should be set to some * defaults to deal with broken apps which do not set the asked members. */ if(cell != NULL) { info.cell.pszText = NULL; info.cell.hValue = NULL; info.cell.lParam = cell->lp; info.cell.dwFlags = cell->flags; } else { info.cell.pszText = NULL; info.cell.hValue = NULL; info.cell.lParam = 0; info.cell.dwFlags = 0; } MC_SEND(grid->notify_win, WM_NOTIFY, 0, &info); /* If needed, convert the text from parent to the expected format. */ if(mask & MC_TCMF_TEXT) { if(grid->unicode_notifications == MC_IS_UNICODE) di->text = info.cell.pszText; else di->text = mc_str(info.cell.pszText, (grid->unicode_notifications ? MC_STRW : MC_STRA), MC_STRT); } else { /* Needed even when not asked for because of grid_free_dispinfo() */ di->text = NULL; } /* Small optimization: We do not ask about the corresponding bits in the * mask for these. If not set, the assignment does no hurt and we save few * instructions. */ di->value = info.cell.hValue; di->flags = info.cell.dwFlags; }