lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [5893] Clone 'mec*' source files for GPT


From: Greg Chicares
Subject: [lmi-commits] [5893] Clone 'mec*' source files for GPT
Date: Sun, 15 Jun 2014 17:17:50 +0000

Revision: 5893
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5893
Author:   chicares
Date:     2014-06-15 17:17:49 +0000 (Sun, 15 Jun 2014)
Log Message:
-----------
Clone 'mec*' source files for GPT

Modified Paths:
--------------
    lmi/trunk/ChangeLog

Added Paths:
-----------
    lmi/trunk/gpt.xrc
    lmi/trunk/gpt_document.cpp
    lmi/trunk/gpt_document.hpp
    lmi/trunk/gpt_input.cpp
    lmi/trunk/gpt_input.hpp
    lmi/trunk/gpt_server.cpp
    lmi/trunk/gpt_server.hpp
    lmi/trunk/gpt_state.cpp
    lmi/trunk/gpt_state.hpp
    lmi/trunk/gpt_view.cpp
    lmi/trunk/gpt_view.hpp
    lmi/trunk/gpt_view.png
    lmi/trunk/gpt_xml_document.cpp
    lmi/trunk/gpt_xml_document.hpp

Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2014-05-04 16:57:25 UTC (rev 5892)
+++ lmi/trunk/ChangeLog 2014-06-15 17:17:49 UTC (rev 5893)
@@ -33797,3 +33797,21 @@
   dbnames.xpp
 Remove or deprecate inutile database suboptions.
 
+20140615T1717Z <address@hidden> [542]
+
+  gpt.xrc              [new file]
+  gpt_document.cpp     [new file]
+  gpt_document.hpp     [new file]
+  gpt_input.cpp        [new file]
+  gpt_input.hpp        [new file]
+  gpt_server.cpp       [new file]
+  gpt_server.hpp       [new file]
+  gpt_state.cpp        [new file]
+  gpt_state.hpp        [new file]
+  gpt_view.cpp         [new file]
+  gpt_view.hpp         [new file]
+  gpt_view.png         [new file]
+  gpt_xml_document.cpp [new file]
+  gpt_xml_document.hpp [new file]
+Clone 'mec*' source files for GPT.
+

Added: lmi/trunk/gpt.xrc
===================================================================
(Binary files differ)


Property changes on: lmi/trunk/gpt.xrc
___________________________________________________________________
Added: svn:mime-type
   + application/xml
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_document.cpp
===================================================================
--- lmi/trunk/gpt_document.cpp                          (rev 0)
+++ lmi/trunk/gpt_document.cpp  2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,135 @@
+// Document class for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif
+
+#include "gpt_document.hpp"
+#include "view_ex.tpp"
+
+#include "alert.hpp"
+#include "gpt_view.hpp"
+#include "miscellany.hpp"
+#include "wx_utility.hpp"
+
+#include <fstream>
+
+IMPLEMENT_DYNAMIC_CLASS(gpt_document, wxDocument)
+
+gpt_document::gpt_document()
+    :wxDocument()
+{
+}
+
+gpt_document::~gpt_document()
+{
+}
+
+gpt_view& gpt_document::PredominantView() const
+{
+    return ::PredominantView<gpt_view>(*this);
+}
+
+wxHtmlWindow& gpt_document::PredominantViewWindow() const
+{
+    return ::PredominantViewWindow<gpt_view,wxHtmlWindow>
+        (*this
+        ,&gpt_view::html_window_
+        );
+}
+
+/// See the documentation for similar class IllustrationDocument.
+
+bool gpt_document::OnCreate(wxString const& filename, long int flags)
+{
+    if(wxDOC_NEW & flags)
+        {
+        ; // Do nothing.
+        }
+    else
+        {
+        std::string f = ValidateAndConvertFilename(filename);
+        std::ifstream ifs(f.c_str());
+        if(!ifs)
+            {
+            warning()
+                << "Unable to read file '"
+                << filename
+                << "'."
+                << LMI_FLUSH
+                ;
+            return false;
+            }
+        doc_.read(ifs);
+        }
+
+    return wxDocument::OnCreate(filename, flags);
+}
+
+#if !wxCHECK_VERSION(2,9,0)
+/// See the documentation for similar class IllustrationDocument.
+
+bool gpt_document::OnNewDocument()
+{
+    Modify(true);
+    SetDocumentSaved(false);
+
+#if wxCHECK_VERSION(2,8,8)
+    wxString const name = GetDocumentManager()->MakeNewDocumentName();
+#else  // !wxCHECK_VERSION(2,8,8)
+    wxString name;
+    GetDocumentManager()->MakeDefaultName(name);
+#endif // !wxCHECK_VERSION(2,8,8)
+    SetTitle(name);
+    SetFilename(name, true);
+
+    return true;
+}
+#endif // !wxCHECK_VERSION(2,9,0)
+
+/// See the documentation for similar class IllustrationDocument.
+
+bool gpt_document::DoOpenDocument(wxString const& filename)
+{
+    return true;
+}
+
+/// See the documentation for similar class IllustrationDocument.
+
+bool gpt_document::DoSaveDocument(wxString const& filename)
+{
+    std::string f = ValidateAndConvertFilename(filename);
+    std::ofstream ofs(f.c_str(), ios_out_trunc_binary());
+    doc_.write(ofs);
+    if(!ofs)
+        {
+        warning() << "Unable to save '" << filename << "'." << LMI_FLUSH;
+        return false;
+        }
+
+    status() << "Saved '" << filename << "'." << std::flush;
+    return true;
+}
+


Property changes on: lmi/trunk/gpt_document.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_document.hpp
===================================================================
--- lmi/trunk/gpt_document.hpp                          (rev 0)
+++ lmi/trunk/gpt_document.hpp  2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,67 @@
+// Document class for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_document_hpp
+#define gpt_document_hpp
+
+#include "config.hpp"
+
+#include "gpt_input.hpp"
+#include "gpt_xml_document.hpp"
+#include "uncopyable_lmi.hpp"
+
+#include <wx/docview.h>
+
+class gpt_view;
+class WXDLLIMPEXP_FWD_CORE wxHtmlWindow;
+
+class gpt_document
+    :public  wxDocument
+    ,private lmi::uncopyable<gpt_document>
+{
+    friend class gpt_view;
+
+  public:
+    gpt_document();
+    virtual ~gpt_document();
+
+    gpt_view& PredominantView() const;
+
+  private:
+    wxHtmlWindow& PredominantViewWindow() const;
+
+    // wxDocument overrides.
+    virtual bool OnCreate(wxString const& filename, long int flags);
+#if !wxCHECK_VERSION(2,9,0)
+    virtual bool OnNewDocument();
+#endif // !wxCHECK_VERSION(2,9,0)
+    virtual bool DoOpenDocument(wxString const& filename);
+    virtual bool DoSaveDocument(wxString const& filename);
+
+    gpt_xml_document doc_;
+
+    DECLARE_DYNAMIC_CLASS(gpt_document)
+};
+
+#endif // gpt_document_hpp
+


Property changes on: lmi/trunk/gpt_document.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_input.cpp
===================================================================
--- lmi/trunk/gpt_input.cpp                             (rev 0)
+++ lmi/trunk/gpt_input.cpp     2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,677 @@
+// MVC Model for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "gpt_input.hpp"
+#include "xml_serializable.tpp"
+
+#include "alert.hpp"
+#include "assert_lmi.hpp"
+#include "calendar_date.hpp"            // attained_age()
+#include "contains.hpp"
+#include "database.hpp"
+#include "dbnames.hpp"
+#include "global_settings.hpp"
+#include "input_seq_helpers.hpp"        // convert_vector(), 
convert_vector_type()
+#include "map_lookup.hpp"
+#include "miscellany.hpp"               // lmi_array_size()
+
+#include <algorithm>                    // std::max()
+#include <limits>
+#include <sstream>
+#include <utility>                      // std::pair
+
+template class xml_serializable<gpt_input>;
+
+namespace
+{
+template<typename T>
+std::string realize_sequence_string
+    (gpt_input           & input
+    ,std::vector<T>      & v
+    ,datum_sequence const& sequence_string
+    ,int                   index_origin = 0
+    )
+{
+    InputSequence s
+        (sequence_string.value()
+        ,input.years_to_maturity()
+        ,input.issue_age        ()
+        ,input.maturity_age     () // This class has no "retirement age".
+        ,input.inforce_year     ()
+        ,input.effective_year   ()
+        ,index_origin
+        );
+    detail::convert_vector(v, s.linear_number_representation());
+    return s.formatted_diagnostics(true);
+}
+} // Unnamed namespace.
+
+/// Values are initialized by UDT defaults where appropriate, and here
+/// in the initializer-list otherwise. All "ascribed" data members are
+/// listed here for clarity and maintainability, and commented out if
+/// UDT defaults are presently appropriate.
+
+gpt_input::gpt_input()
+    :Use7702ATables                   ("No")
+    ,IssueAge                         ("45")
+    ,Gender                           ("Male")
+    ,Smoking                          ("Nonsmoker")
+    ,UnderwritingClass                ("Standard")
+//    ,DateOfBirth                      ("")
+//    ,SubstandardTable                 ("")
+//    ,ProductName                      ("")
+//    ,External1035ExchangeAmount       ("")
+//    ,External1035ExchangeFromMec      ("")
+//    ,Internal1035ExchangeAmount       ("")
+//    ,Internal1035ExchangeFromMec      ("")
+//    ,EffectiveDate                    ("")
+//    ,DefinitionOfLifeInsurance        ("")
+    ,DefinitionOfMaterialChange       ("Unnecessary premium")
+//    ,GroupUnderwritingType            ("")
+//    ,Comments                         ("")
+//    ,InforceAsOfDate                  ("")
+//    ,InforceYear                      ("")
+//    ,InforceMonth                     ("")
+    ,InforceTargetSpecifiedAmount     ("1000000")
+//    ,InforceAccountValue              ("")
+//    ,InforceIsMec                     ("")
+//    ,LastMaterialChangeDate           ("")
+//    ,InforceContractYear              ("")
+//    ,InforceContractMonth             ("")
+//    ,InforceAvBeforeLastMc            ("")
+//    ,InforceDcv                       ("")
+    ,InforceLeastDeathBenefit         ("1000000")
+    ,PaymentHistory                   ("0")
+    ,BenefitHistory                   ("1000000")
+    ,StateOfJurisdiction              ("CT")
+    ,PremiumTaxState                  ("CT")
+    ,FlatExtra                        ("0")
+//    ,UseDOB                           ("")
+    ,Payment                          ("0")
+    ,BenefitAmount                    ("1000000")
+{
+    AscribeMembers();
+    DoAdaptExternalities(); // Initialize database, e.g.
+    DoTransmogrify();       // Make DOB and age consistent, e.g.
+}
+
+gpt_input::gpt_input(gpt_input const& z)
+    :obstruct_slicing  <gpt_input>()
+    ,xml_serializable  <gpt_input>()
+    ,MvcModel                     ()
+    ,MemberSymbolTable <gpt_input>()
+{
+    AscribeMembers();
+    MemberSymbolTable<gpt_input>::assign(z);
+    DoAdaptExternalities();
+}
+
+gpt_input::~gpt_input()
+{
+}
+
+gpt_input& gpt_input::operator=(gpt_input const& z)
+{
+    MemberSymbolTable<gpt_input>::assign(z);
+    DoAdaptExternalities();
+    return *this;
+}
+
+bool gpt_input::operator==(gpt_input const& z) const
+{
+    return MemberSymbolTable<gpt_input>::equals(z);
+}
+
+int gpt_input::maturity_age() const {return GleanedMaturityAge_;}
+
+int gpt_input::years_to_maturity  () const {return maturity_age() - 
issue_age();}
+int gpt_input::issue_age          () const {return IssueAge     .value();}
+int gpt_input::inforce_year       () const {return InforceYear  .value();}
+int gpt_input::effective_year     () const {return 
EffectiveDate.value().year();}
+
+void gpt_input::AscribeMembers()
+{
+    ascribe("Use7702ATables"                        , 
&gpt_input::Use7702ATables                        );
+    ascribe("IssueAge"                              , &gpt_input::IssueAge     
                         );
+    ascribe("Gender"                                , &gpt_input::Gender       
                         );
+    ascribe("Smoking"                               , &gpt_input::Smoking      
                         );
+    ascribe("UnderwritingClass"                     , 
&gpt_input::UnderwritingClass                     );
+    ascribe("DateOfBirth"                           , &gpt_input::DateOfBirth  
                         );
+    ascribe("SubstandardTable"                      , 
&gpt_input::SubstandardTable                      );
+    ascribe("ProductName"                           , &gpt_input::ProductName  
                         );
+    ascribe("External1035ExchangeAmount"            , 
&gpt_input::External1035ExchangeAmount            );
+    ascribe("External1035ExchangeFromMec"           , 
&gpt_input::External1035ExchangeFromMec           );
+    ascribe("Internal1035ExchangeAmount"            , 
&gpt_input::Internal1035ExchangeAmount            );
+    ascribe("Internal1035ExchangeFromMec"           , 
&gpt_input::Internal1035ExchangeFromMec           );
+    ascribe("EffectiveDate"                         , 
&gpt_input::EffectiveDate                         );
+    ascribe("DefinitionOfLifeInsurance"             , 
&gpt_input::DefinitionOfLifeInsurance             );
+    ascribe("DefinitionOfMaterialChange"            , 
&gpt_input::DefinitionOfMaterialChange            );
+    ascribe("GroupUnderwritingType"                 , 
&gpt_input::GroupUnderwritingType                 );
+    ascribe("Comments"                              , &gpt_input::Comments     
                         );
+    ascribe("InforceAsOfDate"                       , 
&gpt_input::InforceAsOfDate                       );
+    ascribe("InforceYear"                           , &gpt_input::InforceYear  
                         );
+    ascribe("InforceMonth"                          , &gpt_input::InforceMonth 
                         );
+    ascribe("InforceTargetSpecifiedAmount"          , 
&gpt_input::InforceTargetSpecifiedAmount          );
+    ascribe("InforceAccountValue"                   , 
&gpt_input::InforceAccountValue                   );
+    ascribe("InforceIsMec"                          , &gpt_input::InforceIsMec 
                         );
+    ascribe("LastMaterialChangeDate"                , 
&gpt_input::LastMaterialChangeDate                );
+    ascribe("InforceContractYear"                   , 
&gpt_input::InforceContractYear                   );
+    ascribe("InforceContractMonth"                  , 
&gpt_input::InforceContractMonth                  );
+    ascribe("InforceAvBeforeLastMc"                 , 
&gpt_input::InforceAvBeforeLastMc                 );
+    ascribe("InforceDcv"                            , &gpt_input::InforceDcv   
                         );
+    ascribe("InforceLeastDeathBenefit"              , 
&gpt_input::InforceLeastDeathBenefit              );
+    ascribe("PaymentHistory"                        , 
&gpt_input::PaymentHistory                        );
+    ascribe("BenefitHistory"                        , 
&gpt_input::BenefitHistory                        );
+    ascribe("StateOfJurisdiction"                   , 
&gpt_input::StateOfJurisdiction                   );
+    ascribe("PremiumTaxState"                       , 
&gpt_input::PremiumTaxState                       );
+    ascribe("FlatExtra"                             , &gpt_input::FlatExtra    
                         );
+    ascribe("UseDOB"                                , &gpt_input::UseDOB       
                         );
+    ascribe("Payment"                               , &gpt_input::Payment      
                         );
+    ascribe("BenefitAmount"                         , 
&gpt_input::BenefitAmount                         );
+}
+
+/// Reset database_ if necessary, i.e., if the product or any database
+/// axis changed.
+
+void gpt_input::DoAdaptExternalities()
+{
+    // This early-exit condition has to fail the first time this
+    // function is called, because database_ is initialized only here.
+    if
+        (
+            database_.get()
+        &&  CachedProductName_           == ProductName
+        &&  CachedGender_                == Gender
+        &&  CachedUnderwritingClass_     == UnderwritingClass
+        &&  CachedSmoking_               == Smoking
+        &&  CachedIssueAge_              == IssueAge
+        &&  CachedGroupUnderwritingType_ == GroupUnderwritingType
+        &&  CachedStateOfJurisdiction_   == StateOfJurisdiction
+        )
+        {
+        return;
+        }
+
+    CachedProductName_           = ProductName          .value();
+    CachedGender_                = Gender               .value();
+    CachedUnderwritingClass_     = UnderwritingClass    .value();
+    CachedSmoking_               = Smoking              .value();
+    CachedIssueAge_              = IssueAge             .value();
+    CachedGroupUnderwritingType_ = GroupUnderwritingType.value();
+    CachedStateOfJurisdiction_   = StateOfJurisdiction  .value();
+
+    database_.reset
+        (new product_database
+            (CachedProductName_
+            ,CachedGender_
+            ,CachedUnderwritingClass_
+            ,CachedSmoking_
+            ,CachedIssueAge_
+            ,CachedGroupUnderwritingType_
+            ,CachedStateOfJurisdiction_
+            )
+        );
+
+    GleanedMaturityAge_ = static_cast<int>(database_->Query(DB_MaturityAge));
+}
+
+datum_base const* gpt_input::DoBaseDatumPointer
+    (std::string const& name
+    ) const
+{
+    return member_cast<datum_base>(operator[](name));
+}
+
+any_entity& gpt_input::DoEntity(std::string const& name)
+{
+    return MemberSymbolTable<gpt_input>::operator[](name);
+}
+
+any_entity const& gpt_input::DoEntity(std::string const& name) const
+{
+    return MemberSymbolTable<gpt_input>::operator[](name);
+}
+
+MvcModel::NamesType const& gpt_input::DoNames() const
+{
+    return member_names();
+}
+
+MvcModel::StateType gpt_input::DoState() const
+{
+    return member_state(*this);
+}
+
+void gpt_input::DoCustomizeInitialValues()
+{
+}
+
+void gpt_input::DoEnforceCircumscription(std::string const& name)
+{
+    datum_base* base_datum = member_cast<datum_base>(operator[](name));
+    tn_range_base* datum = dynamic_cast<tn_range_base*>(base_datum);
+    if(datum)
+        {
+        datum->enforce_circumscription();
+        }
+}
+
+void gpt_input::DoEnforceProscription(std::string const& name)
+{
+    // Here one could handle special cases for which the generic
+    // behavior is not wanted.
+
+    datum_base* base_datum = member_cast<datum_base>(operator[](name));
+    mc_enum_base* datum = dynamic_cast<mc_enum_base*>(base_datum);
+    if(datum)
+        {
+        datum->enforce_proscription();
+        }
+}
+
+/// Cf. Input::DoHarmonize().
+
+void gpt_input::DoHarmonize()
+{
+    bool anything_goes    = global_settings::instance().ash_nazg();
+
+    DefinitionOfLifeInsurance.allow(mce_gpt , database_->Query(DB_AllowGpt ));
+    DefinitionOfLifeInsurance.allow(mce_cvat, database_->Query(DB_AllowCvat));
+    DefinitionOfLifeInsurance.allow(mce_noncompliant, false);
+
+    DefinitionOfMaterialChange.enable(mce_noncompliant != 
DefinitionOfLifeInsurance);
+    if(mce_noncompliant == DefinitionOfLifeInsurance)
+        {
+        // Nothing to do: all choices ignored because control is disabled.
+        }
+    else if(mce_cvat == DefinitionOfLifeInsurance)
+        {
+        DefinitionOfMaterialChange.allow(mce_unnecessary_premium               
         ,true         );
+        DefinitionOfMaterialChange.allow(mce_benefit_increase                  
         ,true         );
+        
DefinitionOfMaterialChange.allow(mce_later_of_increase_or_unnecessary_premium   
,anything_goes); // Not yet implemented.
+        
DefinitionOfMaterialChange.allow(mce_earlier_of_increase_or_unnecessary_premium 
,true         );
+        DefinitionOfMaterialChange.allow(mce_adjustment_event                  
         ,false        );
+        }
+    else if(mce_gpt == DefinitionOfLifeInsurance)
+        {
+        DefinitionOfMaterialChange.allow(mce_unnecessary_premium               
         ,false        );
+        DefinitionOfMaterialChange.allow(mce_benefit_increase                  
         ,false        );
+        
DefinitionOfMaterialChange.allow(mce_later_of_increase_or_unnecessary_premium   
,false        );
+        
DefinitionOfMaterialChange.allow(mce_earlier_of_increase_or_unnecessary_premium 
,false        );
+        DefinitionOfMaterialChange.allow(mce_adjustment_event                  
         ,true         );
+        }
+    else
+        {
+        fatal_error()
+            << "No option selected for definition of life insurance."
+            << LMI_FLUSH
+            ;
+        }
+
+    GroupUnderwritingType.allow(mce_medical         , 
database_->Query(DB_AllowFullUw   ));
+    GroupUnderwritingType.allow(mce_paramedical     , 
database_->Query(DB_AllowParamedUw));
+    GroupUnderwritingType.allow(mce_nonmedical      , 
database_->Query(DB_AllowNonmedUw ));
+    GroupUnderwritingType.allow(mce_simplified_issue, 
database_->Query(DB_AllowSimpUw   ));
+    GroupUnderwritingType.allow(mce_guaranteed_issue, 
database_->Query(DB_AllowGuarUw   ));
+
+    IssueAge        .enable(mce_no  == UseDOB);
+    DateOfBirth     .enable(mce_yes == UseDOB);
+
+    // The ranges of both EffectiveDate and IssueAge are treated as
+    // independent, to prevent one's value from affecting the other's
+    // range and therefore possibly forcing its value to change. Thus,
+    // if the maximum conceivable IssueAge is 100, then the earliest
+    // permitted EffectiveDate is approximately the centennial of the
+    // gregorian epoch.
+
+#if 0
+// Temporarily suppress this while exploring automatic-
+// enforcement options in the skeleton trunk.
+    IssueAge.minimum_and_maximum
+        (static_cast<int>(database_->Query(DB_MinIssAge))
+        ,static_cast<int>(database_->Query(DB_MaxIssAge))
+        );
+#endif // 0
+
+    EffectiveDate.minimum
+        (minimum_as_of_date
+            (     IssueAge.trammel().maximum_maximorum()
+            ,EffectiveDate.trammel().minimum_minimorum()
+            )
+        );
+
+    oenum_alb_or_anb const alb_anb =
+        static_cast<oenum_alb_or_anb>
+            (static_cast<int>
+                (database_->Query(DB_AgeLastOrNearest)
+                )
+            );
+    DateOfBirth.minimum_and_maximum
+        (minimum_birthdate(IssueAge.maximum(), EffectiveDate.value(), alb_anb)
+        ,maximum_birthdate(IssueAge.minimum(), EffectiveDate.value(), alb_anb)
+        );
+
+    int max_age = static_cast<int>(database_->Query(DB_MaturityAge));
+    InforceAsOfDate.minimum_and_maximum
+        (EffectiveDate.value()
+        ,add_years_and_months
+            (EffectiveDate.value()
+            ,-1 + max_age - IssueAge.value()
+            ,11
+            ,true
+            )
+        );
+    // SOMEDAY !! Here, it's important to use std::max(): otherwise,
+    // when values change, the maximum could be less than the minimum,
+    // because 'InforceAsOfDate' has not yet been constrained to the
+    // limit just set. Should the MVC framework handle this somehow?
+    LastMaterialChangeDate.minimum_and_maximum
+        (EffectiveDate.value()
+        ,std::max(InforceAsOfDate.value(), InforceAsOfDate.minimum())
+        );
+
+    double maximum_1035 =
+          InforceAsOfDate == EffectiveDate
+        ? std::numeric_limits<double>::max()
+        : 0.0
+        ;
+    External1035ExchangeAmount.maximum(maximum_1035);
+    Internal1035ExchangeAmount.maximum(maximum_1035);
+
+    External1035ExchangeFromMec.allow (mce_yes, 0.0 != 
External1035ExchangeAmount);
+    External1035ExchangeFromMec.enable(         0.0 != 
External1035ExchangeAmount);
+    Internal1035ExchangeFromMec.allow (mce_yes, 0.0 != 
Internal1035ExchangeAmount);
+    Internal1035ExchangeFromMec.enable(         0.0 != 
Internal1035ExchangeAmount);
+
+    // SOMEDAY !! Do this in class Input as well.
+    bool mec_due_to_1035 =
+            mce_yes == External1035ExchangeFromMec
+        ||  mce_yes == Internal1035ExchangeFromMec
+        ;
+    InforceIsMec.allow (mce_no, !mec_due_to_1035);
+    InforceIsMec.enable(        !mec_due_to_1035);
+    bool non_mec = mce_no == InforceIsMec;
+
+    double maximum_7702A_csv_at_issue =
+          InforceAsOfDate == EffectiveDate
+        ? 0.0
+        : std::numeric_limits<double>::max()
+        ;
+    InforceAccountValue.maximum(maximum_7702A_csv_at_issue);
+    InforceDcv         .maximum(maximum_7702A_csv_at_issue);
+
+    InforceTargetSpecifiedAmount.enable(non_mec);
+    InforceAccountValue         .enable(non_mec);
+    LastMaterialChangeDate      .enable(non_mec);
+    InforceDcv                  .enable(non_mec && mce_cvat == 
DefinitionOfLifeInsurance);
+    InforceAvBeforeLastMc       .enable(non_mec);
+    InforceLeastDeathBenefit    .enable(non_mec);
+    PaymentHistory              .enable(non_mec);
+    BenefitHistory              .enable(non_mec);
+
+    UnderwritingClass.allow(mce_ultrapreferred, 
database_->Query(DB_AllowUltraPrefClass));
+    UnderwritingClass.allow(mce_preferred     , 
database_->Query(DB_AllowPreferredClass));
+    UnderwritingClass.allow(mce_rated, database_->Query(DB_AllowSubstdTable));
+
+    SubstandardTable.enable(mce_rated == UnderwritingClass);
+
+    SubstandardTable.allow(mce_table_a, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_b, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_c, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_d, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_e, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_f, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_h, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_j, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_l, mce_rated == UnderwritingClass);
+    SubstandardTable.allow(mce_table_p, mce_rated == UnderwritingClass);
+
+    FlatExtra.enable(database_->Query(DB_AllowFlatExtras));
+
+    bool blend_mortality_by_gender  = false;
+    bool blend_mortality_by_smoking = false;
+
+    bool allow_gender_distinct = database_->Query(DB_AllowSexDistinct);
+    bool allow_unisex          = database_->Query(DB_AllowUnisex);
+
+    Gender.allow(mce_female, !blend_mortality_by_gender && 
allow_gender_distinct);
+    Gender.allow(mce_male  , !blend_mortality_by_gender && 
allow_gender_distinct);
+    Gender.allow(mce_unisex,  blend_mortality_by_gender || allow_unisex);
+
+    bool allow_smoker_distinct = database_->Query(DB_AllowSmokeDistinct);
+    bool allow_unismoke        = database_->Query(DB_AllowUnismoke);
+
+    Smoking.allow(mce_smoker,    !blend_mortality_by_smoking && 
allow_smoker_distinct);
+    Smoking.allow(mce_nonsmoker, !blend_mortality_by_smoking && 
allow_smoker_distinct);
+    Smoking.allow(mce_unismoke,   blend_mortality_by_smoking || 
allow_unismoke);
+}
+
+/// Change values as required for consistency.
+
+void gpt_input::DoTransmogrify()
+{
+    std::pair<int,int> ym0 = years_and_months_since
+        (EffectiveDate  .value()
+        ,InforceAsOfDate.value()
+        );
+    InforceYear  = ym0.first;
+    InforceMonth = ym0.second;
+
+    std::pair<int,int> ym1 = years_and_months_since
+        (LastMaterialChangeDate.value()
+        ,InforceAsOfDate       .value()
+        );
+    InforceContractYear  = ym1.first;
+    InforceContractMonth = ym1.second;
+
+    oenum_alb_or_anb const alb_anb =
+        static_cast<oenum_alb_or_anb>
+            (static_cast<int>
+                (database_->Query(DB_AgeLastOrNearest)
+                )
+            );
+
+    int apparent_age = attained_age
+        (DateOfBirth.value()
+        ,EffectiveDate.value()
+        ,alb_anb
+        );
+    if(mce_no == UseDOB)
+        {
+        // If no DOB is supplied, assume a birthday occurs on the
+        // issue date--as good an assumption as any, and the simplest.
+        // It may need to be a day earlier for a contract issued on a
+        // leap-year day.
+        DateOfBirth = add_years
+            (DateOfBirth.value()
+            ,apparent_age - IssueAge.value()
+            ,true
+            );
+        }
+    else
+        {
+        IssueAge = apparent_age;
+        }
+}
+
+std::vector<std::string> gpt_input::RealizeAllSequenceInput(bool report_errors)
+{
+    LMI_ASSERT(years_to_maturity() == database_->length());
+
+    std::vector<std::string> s;
+    s.push_back(RealizeFlatExtra                  ());
+    s.push_back(RealizePaymentHistory             ());
+    s.push_back(RealizeBenefitHistory             ());
+
+    if(report_errors)
+        {
+        for
+            (std::vector<std::string>::iterator i = s.begin()
+            ;i != s.end()
+            ;++i
+            )
+            {
+            std::ostringstream oss;
+            bool diagnostics_present = false;
+            if(!i->empty())
+                {
+                diagnostics_present = true;
+                oss << (*i) << "\n";
+                }
+            if(diagnostics_present)
+                {
+                fatal_error()
+                    << "Input validation problems:\n"
+                    << oss.str()
+                    << LMI_FLUSH
+                    ;
+                }
+            }
+        }
+
+    return s;
+}
+
+std::string gpt_input::RealizeFlatExtra()
+{
+// We could enforce a maximum of the monthly equivalent of unity,
+// and a minimum of zero; is that worth the bother though?
+    std::string s = realize_sequence_string
+        (*this
+        ,FlatExtraRealized_
+        ,FlatExtra
+        );
+    if(s.size())
+        {
+        return s;
+        }
+
+    if(database_->Query(DB_AllowFlatExtras))
+        {
+        return "";
+        }
+
+    if(!each_equal(FlatExtraRealized_.begin(), FlatExtraRealized_.end(), 0.0))
+        {
+        return "Flat extras may not be illustrated on this policy form.";
+        }
+
+    return "";
+}
+
+std::string gpt_input::RealizePaymentHistory()
+{
+    return realize_sequence_string
+        (*this
+        ,PaymentHistoryRealized_
+        ,PaymentHistory
+        );
+}
+
+std::string gpt_input::RealizeBenefitHistory()
+{
+    return realize_sequence_string
+        (*this
+        ,BenefitHistoryRealized_
+        ,BenefitHistory
+        );
+}
+
+/// Backward-compatibility serial number of this class's xml version.
+///
+/// version 0: 20140615T1717Z
+
+int gpt_input::class_version() const
+{
+    return 0;
+}
+
+std::string const& gpt_input::xml_root_name() const
+{
+    static std::string const s("gpt");
+    return s;
+}
+
+bool gpt_input::is_detritus(std::string const& s) const
+{
+    static std::string const a[] =
+        {"Remove this string when adding the first removed entity."
+        };
+    static std::vector<std::string> const v(a, a + lmi_array_size(a));
+    return contains(v, s);
+}
+
+void gpt_input::redintegrate_ex_ante
+    (int                file_version
+    ,std::string const& // name
+    ,std::string      & // value
+    ) const
+{
+    if(class_version() == file_version)
+        {
+        return;
+        }
+
+    // Nothing to do for now.
+}
+
+void gpt_input::redintegrate_ex_post
+    (int                                       file_version
+    ,std::map<std::string, std::string> const& // detritus_map
+    ,std::list<std::string>             const& // residuary_names
+    )
+{
+    if(class_version() == file_version)
+        {
+        return;
+        }
+
+    // Nothing to do for now.
+}
+
+void gpt_input::redintegrate_ad_terminum()
+{
+    Reconcile();
+    RealizeAllSequenceInput(false);
+}
+
+std::vector<double> gpt_input::FlatExtraRealized() const
+{
+    return convert_vector_type<double>(FlatExtraRealized_);
+}
+
+std::vector<double> gpt_input::PaymentHistoryRealized() const
+{
+    return convert_vector_type<double>(PaymentHistoryRealized_);
+}
+
+std::vector<double> gpt_input::BenefitHistoryRealized() const
+{
+    return convert_vector_type<double>(BenefitHistoryRealized_);
+}
+


Property changes on: lmi/trunk/gpt_input.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_input.hpp
===================================================================
--- lmi/trunk/gpt_input.hpp                             (rev 0)
+++ lmi/trunk/gpt_input.hpp     2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,227 @@
+// MVC Model for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_input_hpp
+#define gpt_input_hpp
+
+#include "config.hpp"
+
+#include "mvc_model.hpp"
+
+#include "any_member.hpp"
+#include "ce_product_name.hpp"
+#include "datum_boolean.hpp"
+#include "datum_sequence.hpp"
+#include "datum_string.hpp"
+#include "mc_enum.hpp"
+#include "mc_enum_types.hpp"
+#include "obstruct_slicing.hpp"
+#include "so_attributes.hpp"
+#include "tn_range.hpp"
+#include "tn_range_types.hpp"
+#include "xml_serializable.hpp"
+
+class product_database;
+
+#include <boost/operators.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <string>
+#include <vector>
+
+/// This class is the Model of the MVC framework for GPT.
+///
+/// See general notes on class Input.
+///
+/// These variables:
+///   InforceContractYear
+///   InforceYear
+/// are dependent, but useful. These:
+///   UseDOB
+///   IssueAge
+/// are superfluous, but convenient. These:
+///   InforceContractMonth
+///   InforceMonth
+/// are just excess baggage that can be eliminated once the 7702A
+/// calculations are rewritten.
+
+class LMI_SO gpt_input
+    :virtual private obstruct_slicing           <gpt_input>
+    ,        public  xml_serializable           <gpt_input>
+    ,        public  MvcModel
+    ,        public  MemberSymbolTable          <gpt_input>
+    ,        private boost::equality_comparable <gpt_input>
+{
+  public:
+    gpt_input();
+    gpt_input(gpt_input const&);
+    virtual ~gpt_input();
+
+    gpt_input& operator=(gpt_input const&);
+    bool operator==(gpt_input const&) const;
+
+    int                maturity_age() const;
+
+    int years_to_maturity  () const;
+    int issue_age          () const;
+    int inforce_year       () const;
+    int effective_year     () const;
+
+    std::vector<std::string> RealizeAllSequenceInput(bool report_errors = 
true);
+
+    std::vector<double> FlatExtraRealized     () const;
+    std::vector<double> PaymentHistoryRealized() const;
+    std::vector<double> BenefitHistoryRealized() const;
+
+  private:
+    void AscribeMembers();
+
+    // xml_serializable required implementation.
+    virtual int                class_version() const;
+    virtual std::string const& xml_root_name() const;
+
+    // xml_serializable overrides.
+    virtual bool is_detritus(std::string const&) const;
+    virtual void redintegrate_ex_ante
+        (int                file_version
+        ,std::string const& name
+        ,std::string      & value
+        ) const;
+    virtual void redintegrate_ex_post
+        (int                                       file_version
+        ,std::map<std::string, std::string> const& detritus_map
+        ,std::list<std::string>             const& residuary_names
+        );
+    virtual void redintegrate_ad_terminum();
+
+    // MvcModel required implementation.
+    virtual void DoAdaptExternalities();
+    virtual datum_base const* DoBaseDatumPointer(std::string const&) const;
+    virtual any_entity      & DoEntity(std::string const&)      ;
+    virtual any_entity const& DoEntity(std::string const&) const;
+    virtual NamesType const& DoNames() const;
+    virtual StateType        DoState() const;
+    virtual void DoCustomizeInitialValues();
+    virtual void DoEnforceCircumscription(std::string const&);
+    virtual void DoEnforceProscription   (std::string const&);
+    virtual void DoHarmonize();
+    virtual void DoTransmogrify();
+
+    std::string RealizeFlatExtra     ();
+    std::string RealizePaymentHistory();
+    std::string RealizeBenefitHistory();
+
+    boost::scoped_ptr<product_database> database_;
+
+    // Database axes are independent variables; they're "cached" along
+    // with the database, which is reset when any of them changes.
+    // Dependent variables, stored only as an optimization, are
+    // "gleaned" whenever the database is reset.
+    std::string              CachedProductName_          ;
+    mcenum_gender            CachedGender_               ;
+    mcenum_class             CachedUnderwritingClass_    ;
+    mcenum_smoking           CachedSmoking_              ;
+    int                      CachedIssueAge_             ;
+    mcenum_uw_basis          CachedGroupUnderwritingType_;
+    mcenum_state             CachedStateOfJurisdiction_  ;
+    int                      GleanedMaturityAge_         ;
+
+    mce_yes_or_no            Use7702ATables                  ;
+    tnr_age                  IssueAge                        ;
+    mce_gender               Gender                          ;
+    mce_smoking              Smoking                         ;
+    mce_class                UnderwritingClass               ;
+    tnr_date                 DateOfBirth                     ;
+    mce_table_rating         SubstandardTable                ;
+    ce_product_name          ProductName                     ;
+    tnr_nonnegative_double   External1035ExchangeAmount      ;
+    mce_yes_or_no            External1035ExchangeFromMec     ;
+    tnr_nonnegative_double   Internal1035ExchangeAmount      ;
+    mce_yes_or_no            Internal1035ExchangeFromMec     ;
+    tnr_date                 EffectiveDate                   ;
+    mce_defn_life_ins        DefinitionOfLifeInsurance       ;
+    mce_defn_material_change DefinitionOfMaterialChange      ;
+    mce_uw_basis             GroupUnderwritingType           ;
+    datum_string             Comments                        ;
+    tnr_date                 InforceAsOfDate                 ;
+    tnr_duration             InforceYear                     ;
+    tnr_month                InforceMonth                    ;
+    tnr_nonnegative_double   InforceTargetSpecifiedAmount    ;
+    tnr_nonnegative_double   InforceAccountValue             ;
+    mce_yes_or_no            InforceIsMec                    ;
+    tnr_date                 LastMaterialChangeDate          ;
+    tnr_duration             InforceContractYear             ;
+    tnr_month                InforceContractMonth            ;
+    tnr_nonnegative_double   InforceAvBeforeLastMc           ;
+    tnr_nonnegative_double   InforceDcv                      ;
+    tnr_nonnegative_double   InforceLeastDeathBenefit        ;
+    numeric_sequence         PaymentHistory                  ;
+    numeric_sequence         BenefitHistory                  ;
+    mce_state                StateOfJurisdiction             ;
+    mce_state                PremiumTaxState                 ;
+    numeric_sequence         FlatExtra                       ;
+    mce_yes_or_no            UseDOB                          ;
+    tnr_nonnegative_double   Payment                         ;
+    tnr_nonnegative_double   BenefitAmount                   ;
+
+    std::vector<tnr_unrestricted_double> FlatExtraRealized_     ;
+    std::vector<tnr_unrestricted_double> PaymentHistoryRealized_;
+    std::vector<tnr_unrestricted_double> BenefitHistoryRealized_;
+};
+
+/// Specialization of struct template reconstitutor for this Model
+/// and the base class that all its UDTs share.
+
+template<> struct reconstitutor<datum_base, gpt_input>
+{
+    typedef datum_base DesiredType;
+    static DesiredType* reconstitute(any_member<gpt_input>& m)
+        {
+        DesiredType* z = 0;
+        z = exact_cast<ce_product_name         >(m); if(z) return z;
+        z = exact_cast<datum_string            >(m); if(z) return z;
+        // Sequences.
+        z = exact_cast<numeric_sequence        >(m); if(z) return z;
+        // mc- types.
+        z = exact_cast<mce_class               >(m); if(z) return z;
+        z = exact_cast<mce_defn_life_ins       >(m); if(z) return z;
+        z = exact_cast<mce_defn_material_change>(m); if(z) return z;
+        z = exact_cast<mce_gender              >(m); if(z) return z;
+        z = exact_cast<mce_smoking             >(m); if(z) return z;
+        z = exact_cast<mce_state               >(m); if(z) return z;
+        z = exact_cast<mce_table_rating        >(m); if(z) return z;
+        z = exact_cast<mce_uw_basis            >(m); if(z) return z;
+        z = exact_cast<mce_yes_or_no           >(m); if(z) return z;
+        // tnr- types.
+        z = exact_cast<tnr_age                 >(m); if(z) return z;
+        z = exact_cast<tnr_date                >(m); if(z) return z;
+        z = exact_cast<tnr_duration            >(m); if(z) return z;
+        z = exact_cast<tnr_month               >(m); if(z) return z;
+        z = exact_cast<tnr_nonnegative_double  >(m); if(z) return z;
+        z = exact_cast<tnr_unrestricted_double >(m); if(z) return z;
+        return z;
+        }
+};
+
+#endif // gpt_input_hpp
+


Property changes on: lmi/trunk/gpt_input.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_server.cpp
===================================================================
--- lmi/trunk/gpt_server.cpp                            (rev 0)
+++ lmi/trunk/gpt_server.cpp    2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,586 @@
+// Server for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "gpt_server.hpp"
+
+#include "actuarial_table.hpp"
+#include "alert.hpp"
+#include "assert_lmi.hpp"
+#include "commutation_functions.hpp"
+#include "configurable_settings.hpp"
+#include "contains.hpp"
+#include "data_directory.hpp"
+#include "database.hpp"
+#include "dbnames.hpp"
+#include "et_vector.hpp"
+#include "gpt_input.hpp"
+#include "gpt_xml_document.hpp"
+#include "ihs_irc7702a.hpp"
+#include "materially_equal.hpp"
+#include "math_functors.hpp"
+#include "mc_enum_types_aux.hpp"        // mc_state_from_string()
+#include "miscellany.hpp"               // ios_out_trunc_binary()
+#include "oecumenic_enumerations.hpp"
+#include "path_utility.hpp"             // fs::path inserter
+#include "premium_tax.hpp"
+#include "product_data.hpp"
+#include "round_to.hpp"
+#include "stratified_algorithms.hpp"    // TieredGrossToNet()
+#include "stratified_charges.hpp"
+#include "timer.hpp"
+#include "value_cast.hpp"
+
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+#include <algorithm>                    // std::min()
+#include <iostream>
+#include <limits>
+#include <string>
+#include <vector>
+
+namespace
+{
+gpt_state test_one_days_7702A_transactions
+    (fs::path  const& file_path
+    ,gpt_input const& input
+    )
+{
+    bool                        Use7702ATables               = 
exact_cast<mce_yes_or_no           >(input["Use7702ATables"              
])->value();
+//  int                         IssueAge                     = 
exact_cast<tnr_age                 >(input["IssueAge"                    
])->value();
+    mcenum_gender               Gender                       = 
exact_cast<mce_gender              >(input["Gender"                      
])->value();
+    mcenum_smoking              Smoking                      = 
exact_cast<mce_smoking             >(input["Smoking"                     
])->value();
+    mcenum_class                UnderwritingClass            = 
exact_cast<mce_class               >(input["UnderwritingClass"           
])->value();
+//  calendar_date               DateOfBirth                  = 
exact_cast<tnr_date                >(input["DateOfBirth"                 
])->value();
+//  mcenum_table_rating         SubstandardTable             = 
exact_cast<mce_table_rating        >(input["SubstandardTable"            
])->value();
+    std::string                 ProductName                  = 
exact_cast<ce_product_name         >(input["ProductName"                 
])->value();
+    double                      External1035ExchangeAmount   = 
exact_cast<tnr_nonnegative_double  >(input["External1035ExchangeAmount"  
])->value();
+//  bool                        External1035ExchangeFromMec  = 
exact_cast<mce_yes_or_no           >(input["External1035ExchangeFromMec" 
])->value();
+    double                      Internal1035ExchangeAmount   = 
exact_cast<tnr_nonnegative_double  >(input["Internal1035ExchangeAmount"  
])->value();
+//  bool                        Internal1035ExchangeFromMec  = 
exact_cast<mce_yes_or_no           >(input["Internal1035ExchangeFromMec" 
])->value();
+//  calendar_date               EffectiveDate                = 
exact_cast<tnr_date                >(input["EffectiveDate"               
])->value();
+    mcenum_defn_life_ins        DefinitionOfLifeInsurance    = 
exact_cast<mce_defn_life_ins       >(input["DefinitionOfLifeInsurance"   
])->value();
+    mcenum_defn_material_change DefinitionOfMaterialChange   = 
exact_cast<mce_defn_material_change>(input["DefinitionOfMaterialChange"  
])->value();
+    mcenum_uw_basis             GroupUnderwritingType        = 
exact_cast<mce_uw_basis            >(input["GroupUnderwritingType"       
])->value();
+//  std::string                 Comments                     = 
exact_cast<datum_string            >(input["Comments"                    
])->value();
+    int                         InforceYear                  = 
exact_cast<tnr_duration            >(input["InforceYear"                 
])->value();
+    int                         InforceMonth                 = 
exact_cast<tnr_month               >(input["InforceMonth"                
])->value();
+    double                      InforceTargetSpecifiedAmount = 
exact_cast<tnr_nonnegative_double  
>(input["InforceTargetSpecifiedAmount"])->value();
+    double                      InforceAccountValue          = 
exact_cast<tnr_nonnegative_double  >(input["InforceAccountValue"         
])->value();
+//  calendar_date               InforceAsOfDate              = 
exact_cast<tnr_date                >(input["InforceAsOfDate"             
])->value();
+    bool                        InforceIsMec                 = 
exact_cast<mce_yes_or_no           >(input["InforceIsMec"                
])->value();
+//  calendar_date               LastMaterialChangeDate       = 
exact_cast<tnr_date                >(input["LastMaterialChangeDate"      
])->value();
+    double                      InforceDcv                   = 
exact_cast<tnr_nonnegative_double  >(input["InforceDcv"                  
])->value();
+    double                      InforceAvBeforeLastMc        = 
exact_cast<tnr_nonnegative_double  >(input["InforceAvBeforeLastMc"       
])->value();
+    int                         InforceContractYear          = 
exact_cast<tnr_duration            >(input["InforceContractYear"         
])->value();
+    int                         InforceContractMonth         = 
exact_cast<tnr_month               >(input["InforceContractMonth"        
])->value();
+    double                      InforceLeastDeathBenefit     = 
exact_cast<tnr_nonnegative_double  >(input["InforceLeastDeathBenefit"    
])->value();
+    mcenum_state                StateOfJurisdiction          = 
exact_cast<mce_state               >(input["StateOfJurisdiction"         
])->value();
+    mcenum_state                PremiumTaxState              = 
exact_cast<mce_state               >(input["PremiumTaxState"             
])->value();
+//  std::string                 FlatExtra                    = 
exact_cast<numeric_sequence        >(input["FlatExtra"                   
])->value();
+//  std::string                 PaymentHistory               = 
exact_cast<numeric_sequence        >(input["PaymentHistory"              
])->value();
+//  std::string                 BenefitHistory               = 
exact_cast<numeric_sequence        >(input["BenefitHistory"              
])->value();
+//  bool                        UseDOB                       = 
exact_cast<mce_yes_or_no           >(input["UseDOB"                      
])->value();
+    double                      Payment                      = 
exact_cast<tnr_nonnegative_double  >(input["Payment"                     
])->value();
+    double                      BenefitAmount                = 
exact_cast<tnr_nonnegative_double  >(input["BenefitAmount"               
])->value();
+
+    product_data product_filenames(ProductName);
+
+    product_database database
+        (ProductName
+        ,Gender
+        ,UnderwritingClass
+        ,Smoking
+        ,input.issue_age()
+        ,GroupUnderwritingType
+        ,StateOfJurisdiction
+        );
+
+    stratified_charges 
stratified(AddDataDir(product_filenames.datum("TierFilename")));
+
+    // SOMEDAY !! Ideally these would be in the GUI (or read from product 
files).
+    round_to<double> const RoundNonMecPrem(2, r_downward);
+    round_to<double> const round_max_premium(2, r_downward);
+
+    oenum_modal_prem_type const target_premium_type =
+        
static_cast<oenum_modal_prem_type>(static_cast<int>(database.Query(DB_TgtPremType)));
+    std::vector<double> TargetPremiumRates(input.years_to_maturity());
+    if(oe_modal_table == target_premium_type)
+        {
+        TargetPremiumRates = actuarial_table_rates
+            (AddDataDir(product_filenames.datum("TgtPremFilename"))
+            ,static_cast<long int>(database.Query(DB_TgtPremTable))
+            ,input.issue_age()
+            ,input.years_to_maturity()
+            );
+        }
+    else
+        {
+        ; // Do nothing: 'TargetPremiumRates' won't be used.
+        }
+
+    std::vector<double> const CvatCorridorFactors = actuarial_table_rates
+        (AddDataDir(product_filenames.datum("CvatCorridorFilename"))
+        ,static_cast<long int>(database.Query(DB_CorridorTable))
+        ,input.issue_age()
+        ,input.years_to_maturity()
+        );
+
+    std::vector<double> tabular_Ax;
+    for(int j = 0; j < input.years_to_maturity(); ++j)
+        {
+        LMI_ASSERT(0.0 < CvatCorridorFactors[j]);
+        tabular_Ax.push_back(1.0 / CvatCorridorFactors[j]);
+        }
+    tabular_Ax.push_back(1.0);
+
+    std::vector<double> const tabular_7Px = actuarial_table_rates
+        (AddDataDir(product_filenames.datum("SevenPayFilename"))
+        ,static_cast<long int>(database.Query(DB_SevenPayTable))
+        ,input.issue_age()
+        ,input.years_to_maturity()
+        );
+
+    std::vector<double> Mly7702qc = actuarial_table_rates
+        (AddDataDir(product_filenames.datum("Irc7702QFilename"))
+        ,static_cast<long int>(database.Query(DB_Irc7702QTable))
+        ,input.issue_age()
+        ,input.years_to_maturity()
+        );
+    double max_coi_rate = database.Query(DB_MaxMonthlyCoiRate);
+    LMI_ASSERT(0.0 != max_coi_rate);
+    max_coi_rate = 1.0 / max_coi_rate;
+    assign(Mly7702qc, apply_binary(coi_rate_from_q<double>(), Mly7702qc, 
max_coi_rate));
+
+    std::vector<double> guar_int;
+    database.Query(guar_int, DB_GuarInt);
+
+    std::vector<double> const spread
+        (input.years_to_maturity()
+        ,stratified.minimum_tiered_spread_for_7702()
+        );
+
+    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(.04, guar_int) - 
spread);
+    std::vector<double> Mly7702iGlp(input.years_to_maturity());
+    assign
+        (Mly7702iGlp
+        ,apply_unary
+            (i_upper_12_over_12_from_i<double>()
+            ,apply_binary(greater_of<double>(), 0.04, guar_int) - spread
+            )
+        );
+
+    std::vector<double> Mly7702ig;
+    database.Query(Mly7702ig, DB_NaarDiscount);
+    LMI_ASSERT(!contains(Mly7702ig, -1.0));
+    std::vector<double> DBDiscountRate(input.years_to_maturity());
+    assign(DBDiscountRate, 1.0 / (1.0 + Mly7702ig));
+
+    // Use zero if that's the guaranteed rate; else use the statutory rate.
+    // ET !! Use each_equal() here because PETE seems to interfere with
+    // the normal operator==(). Is that a PETE defect?
+    std::vector<double> const zero(input.years_to_maturity(), 0.0);
+    std::vector<double> const& naar_disc_rate =
+          each_equal(Mly7702ig.begin(), Mly7702ig.end(), 0.0)
+        ? zero
+        : Mly7702iGlp
+        ;
+    ULCommFns commfns
+        (Mly7702qc
+        ,Mly7702iGlp
+        ,naar_disc_rate
+        ,mce_option1_for_7702
+        ,mce_monthly
+        );
+
+    std::vector<double> analytic_Ax(input.years_to_maturity());
+    analytic_Ax += (commfns.aDomega() + commfns.kM()) / commfns.aD();
+
+    std::vector<double> E7aN(commfns.aN());
+    E7aN.insert(E7aN.end(), 7, 0.0);
+    E7aN.erase(E7aN.begin(), 7 + E7aN.begin());
+    std::vector<double> analytic_7Px(input.years_to_maturity());
+    analytic_7Px += (commfns.aDomega() + commfns.kM()) / (commfns.aN() - E7aN);
+
+    std::vector<double> const& chosen_Ax  = Use7702ATables ? tabular_Ax  : 
analytic_Ax ;
+    std::vector<double> const& chosen_7Px = Use7702ATables ? tabular_7Px : 
analytic_7Px;
+
+    Irc7702A z
+        (DefinitionOfLifeInsurance
+        ,DefinitionOfMaterialChange
+        ,false // Survivorship: hardcoded for now.
+        ,mce_allow_mec
+        ,true  // Use table for 7pp: hardcoded for now.
+        ,true  // Use table for NSP: hardcoded for now.
+        ,chosen_7Px
+        ,chosen_Ax
+        ,RoundNonMecPrem
+        );
+
+    z.Initialize7702A
+        (false       // a_Ignore
+        ,InforceIsMec // TAXATION !! also use 1035-is-mec fields?
+        ,input.issue_age()
+        ,input.maturity_age()
+        ,InforceYear
+        ,InforceMonth
+        ,InforceContractYear
+        ,InforceContractMonth
+        ,InforceAvBeforeLastMc
+        ,InforceLeastDeathBenefit
+        ,input.PaymentHistoryRealized()
+        ,input.BenefitHistoryRealized()
+        );
+    z.UpdateBOY7702A(InforceYear);
+    z.UpdateBOM7702A(InforceMonth);
+
+    // See the implementation of class BasicValues.
+    long double const epsilon_plus_one =
+        1.0L + std::numeric_limits<long double>::epsilon()
+        ;
+
+    double AnnualTargetPrem = 1000000000.0; // No higher premium is 
anticipated.
+    int const target_year =
+          database.Query(DB_TgtPremFixedAtIssue)
+        ? 0
+        : input.inforce_year()
+        ;
+    if(oe_monthly_deduction == target_premium_type)
+        {
+        warning() << "Unsupported modal premium type." << LMI_FLUSH;
+        }
+    else if(oe_modal_nonmec == target_premium_type)
+        {
+        // When 7Px is calculated from first principles, presumably
+        // the target premium should be the same as for oe_modal_table
+        // with a 7Px table and a DB_TgtPremMonthlyPolFee of zero.
+        AnnualTargetPrem = round_max_premium
+            (   InforceTargetSpecifiedAmount
+            *   epsilon_plus_one
+            *   tabular_7Px[target_year]
+            );
+        }
+    else if(oe_modal_table == target_premium_type)
+        {
+        AnnualTargetPrem = round_max_premium
+            (   database.Query(DB_TgtPremMonthlyPolFee)
+            +       InforceTargetSpecifiedAmount
+                *   epsilon_plus_one
+                *   TargetPremiumRates[target_year]
+            );
+        }
+    else
+        {
+        fatal_error()
+            << "Unknown modal premium type " << target_premium_type << '.'
+            << LMI_FLUSH
+            ;
+        }
+
+    double const premium_tax_load = premium_tax
+        (PremiumTaxState
+        ,mc_state_from_string(product_filenames.datum("InsCoDomicile"))
+        ,false // Assume load is not amortized.
+        ,database
+        ,stratified
+        ).minimum_load_rate();
+
+    std::vector<double> target_sales_load  ;
+    std::vector<double> excess_sales_load  ;
+    std::vector<double> target_premium_load;
+    std::vector<double> excess_premium_load;
+    std::vector<double> dac_tax_load       ;
+
+    database.Query(target_sales_load  , DB_CurrPremLoadTgtRfd);
+    database.Query(excess_sales_load  , DB_CurrPremLoadExcRfd);
+    database.Query(target_premium_load, DB_CurrPremLoadTgt);
+    database.Query(excess_premium_load, DB_CurrPremLoadExc);
+    database.Query(dac_tax_load       , DB_DacTaxPremLoad);
+
+    double const LoadTarget = target_sales_load[InforceYear] + 
target_premium_load[InforceYear] + dac_tax_load[InforceYear] + premium_tax_load;
+    double const LoadExcess = excess_sales_load[InforceYear] + 
excess_premium_load[InforceYear] + dac_tax_load[InforceYear] + premium_tax_load;
+
+    LMI_ASSERT(static_cast<unsigned int>(InforceContractYear) < 
input.BenefitHistoryRealized().size());
+    double const old_benefit_amount = 
input.BenefitHistoryRealized()[InforceContractYear];
+
+    double const total_1035_amount = round_max_premium
+        (TieredGrossToNet
+            (External1035ExchangeAmount + Internal1035ExchangeAmount
+            ,AnnualTargetPrem
+            ,LoadTarget
+            ,LoadExcess
+            )
+        );
+    if(0.0 != total_1035_amount)
+        {
+        z.Update1035Exch7702A
+            (InforceDcv // TAXATION !! Assert that this is zero?
+            ,total_1035_amount
+            ,old_benefit_amount
+            );
+        InforceAccountValue = InforceDcv;
+        }
+
+    if(BenefitAmount != old_benefit_amount)
+        {
+        z.UpdateBft7702A
+            (InforceDcv          // Not actually used.
+            ,BenefitAmount
+            ,old_benefit_amount
+            ,false               // Ignored.
+            ,BenefitAmount
+            ,old_benefit_amount
+            ,InforceAccountValue // Not actually used.
+            );
+        }
+
+    double const max_necessary_premium = z.MaxNecessaryPremium
+        (InforceDcv
+        ,AnnualTargetPrem
+        ,LoadTarget
+        ,LoadExcess
+        ,InforceAccountValue
+        );
+    z.MaxNonMecPremium
+        (InforceDcv
+        ,AnnualTargetPrem
+        ,LoadTarget
+        ,LoadExcess
+        ,InforceAccountValue
+        );
+    double const necessary_premium = std::min(Payment, max_necessary_premium);
+    double const unnecessary_premium = material_difference(Payment, 
necessary_premium);
+
+    if(!z.IsMecAlready() && 0.0 != necessary_premium)
+        {
+        z.UpdatePmt7702A
+            (InforceDcv
+            ,necessary_premium
+            ,false
+            ,AnnualTargetPrem    // Unused.
+            ,LoadTarget          // Unused.
+            ,LoadExcess          // Unused.
+            ,InforceAccountValue // Unused.
+            );
+        double const net_necessary_premium = round_max_premium
+            (TieredGrossToNet
+                (necessary_premium
+                ,AnnualTargetPrem
+                ,LoadTarget
+                ,LoadExcess
+                )
+            );
+        InforceDcv          += net_necessary_premium;
+        InforceAccountValue += net_necessary_premium;
+        // TAXATION !! update DB also
+        }
+
+    if(0.0 < unnecessary_premium)
+        {
+        z.InduceMaterialChange();
+        }
+    if(z.IsMaterialChangeInQueue())
+        {
+        z.RedressMatChg
+            (InforceDcv
+            ,unnecessary_premium
+            ,necessary_premium
+            ,InforceAccountValue
+            );
+        }
+
+    if(!z.IsMecAlready() && 0.0 != unnecessary_premium)
+        {
+        z.UpdatePmt7702A
+            (InforceDcv
+            ,unnecessary_premium
+            ,true
+            ,AnnualTargetPrem    // Unused.
+            ,LoadTarget          // Unused.
+            ,LoadExcess          // Unused.
+            ,InforceAccountValue // Unused.
+            );
+        }
+
+    std::vector<double> ratio_Ax (input.years_to_maturity());
+    ratio_Ax  += tabular_Ax  / analytic_Ax ;
+    std::vector<double> ratio_7Px(input.years_to_maturity());
+    ratio_7Px += tabular_7Px / analytic_7Px;
+
+    configurable_settings const& c = configurable_settings::instance();
+    std::string const extension(".gpt" + c.spreadsheet_file_extension());
+    fs::path spreadsheet_filename = fs::change_extension(file_path, extension);
+    fs::ofstream ofs(spreadsheet_filename, ios_out_trunc_binary());
+    ofs << "This temporary output file will be removed in a future release.\n";
+    ofs
+        << "t\t"
+        << "ic\t"
+        << "ig\t"
+        << "qc\t"
+        << "aD\t"
+        << "kC\t"
+        << "aN\t"
+        << "kM\t"
+        << "E7aN\t"
+        << "Ax\t"
+        << "tabular\t"
+        << "ratio\t"
+        << "7Px\t"
+        << "tabular\t"
+        << "ratio\t"
+        << '\n'
+        ;
+    for(int j = 0; j < input.years_to_maturity(); ++j)
+        {
+        ofs
+            <<               j  << '\t'
+            << value_cast<std::string>(Mly7702iGlp    [j]) << '\t'
+            << value_cast<std::string>(naar_disc_rate [j]) << '\t'
+            << value_cast<std::string>(Mly7702qc      [j]) << '\t'
+            << value_cast<std::string>(commfns.aD()   [j]) << '\t'
+            << value_cast<std::string>(commfns.kC()   [j]) << '\t'
+            << value_cast<std::string>(commfns.aN()   [j]) << '\t'
+            << value_cast<std::string>(commfns.kM()   [j]) << '\t'
+            << value_cast<std::string>(E7aN           [j]) << '\t'
+            << value_cast<std::string>(analytic_Ax    [j]) << '\t'
+            << value_cast<std::string>(tabular_Ax     [j]) << '\t'
+            << value_cast<std::string>(ratio_Ax       [j]) << '\t'
+            << value_cast<std::string>(analytic_7Px   [j]) << '\t'
+            << value_cast<std::string>(tabular_7Px    [j]) << '\t'
+            << value_cast<std::string>(ratio_7Px      [j]) << '\t'
+            << '\n'
+        ;
+        }
+    ofs
+        << input.years_to_maturity()
+        << "\t\t\t\t"
+        << value_cast<std::string>(commfns.aDomega())
+        << "\t\t\t\t\t\t\t\t\t\t\t"
+        << '\n'
+        ;
+    if(!ofs)
+        {
+        warning()
+            << "Unable to write '"
+            << spreadsheet_filename
+            << "'."
+            << LMI_FLUSH
+            ;
+        }
+
+    return z.state();
+}
+} // Unnamed namespace.
+
+gpt_server::gpt_server(mcenum_emission emission)
+    :emission_                 (emission)
+    ,seconds_for_input_        (0.0)
+    ,seconds_for_calculations_ (0.0)
+    ,seconds_for_output_       (0.0)
+{
+}
+
+gpt_server::~gpt_server()
+{
+}
+
+bool gpt_server::operator()(fs::path const& file_path)
+{
+    std::string const extension = fs::extension(file_path);
+    if(".gpt" == extension)
+        {
+        Timer timer;
+        gpt_xml_document doc(file_path.string());
+        seconds_for_input_ = timer.stop().elapsed_seconds();
+        return operator()(file_path, doc.input_data());
+        }
+    else
+        {
+        fatal_error()
+            << "File '"
+            << file_path
+            << "': extension '"
+            << extension
+            << "' not supported."
+            << LMI_FLUSH
+            ;
+        return false;
+        }
+}
+
+bool gpt_server::operator()(fs::path const& file_path, gpt_input const& z)
+{
+    Timer timer;
+    state_ = test_one_days_7702A_transactions(file_path, z);
+    seconds_for_calculations_ = timer.stop().elapsed_seconds();
+    timer.restart();
+    if(mce_emit_test_data && emission_)
+        {
+        state_.save(fs::change_extension(file_path, ".gpt.xml"));
+        }
+    seconds_for_output_       = timer.stop().elapsed_seconds();
+    conditionally_show_timings_on_stdout();
+    return true;
+}
+
+void gpt_server::conditionally_show_timings_on_stdout() const
+{
+    if(mce_emit_timings & emission_)
+        {
+        std::cout
+            << "\n    Input:        "
+            << Timer::elapsed_msec_str(seconds_for_input_)
+            << "\n    Calculations: "
+            << Timer::elapsed_msec_str(seconds_for_calculations_)
+            << "\n    Output:       "
+            << Timer::elapsed_msec_str(seconds_for_output_)
+            << '\n'
+            ;
+        }
+}
+
+gpt_state gpt_server::state() const
+{
+    return state_;
+}
+
+double gpt_server::seconds_for_input() const
+{
+    return seconds_for_input_;
+}
+
+double gpt_server::seconds_for_calculations() const
+{
+    return seconds_for_calculations_;
+}
+
+double gpt_server::seconds_for_output() const
+{
+    return seconds_for_output_;
+}
+


Property changes on: lmi/trunk/gpt_server.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_server.hpp
===================================================================
--- lmi/trunk/gpt_server.hpp                            (rev 0)
+++ lmi/trunk/gpt_server.hpp    2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,80 @@
+// Server for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_server_hpp
+#define gpt_server_hpp
+
+#include "config.hpp"
+
+#include "gpt_state.hpp"
+#include "mc_enum_type_enums.hpp" // enum mcenum_emission
+#include "obstruct_slicing.hpp"
+#include "so_attributes.hpp"
+
+#include <boost/filesystem/path.hpp>
+
+#include <functional>
+
+class gpt_input;
+
+/// Guideline premium test server.
+///
+/// operator() returns bool only to follow class illustrator, not
+/// because the return value is useful. SOMEDAY !! Reconsider that.
+///
+/// Some 'mcenum_emission' enumerators don't make sense here. However,
+/// a distinct enumeration seems unwarranted, especially because
+/// explaining another one in '--help' would be too complicated.
+/// Enumerators that don't make sense can be reported at run time.
+///
+/// Implicitly-declared special member functions do the right thing.
+
+class LMI_SO gpt_server
+    :public std::unary_function<fs::path const&, bool>
+    ,virtual private obstruct_slicing<gpt_server>
+{
+  public:
+    explicit gpt_server(mcenum_emission);
+    ~gpt_server();
+
+    bool operator()(fs::path const&);
+    bool operator()(fs::path const&, gpt_input const&);
+
+    void conditionally_show_timings_on_stdout() const;
+
+    gpt_state state() const;
+
+    double seconds_for_input       () const;
+    double seconds_for_calculations() const;
+    double seconds_for_output      () const;
+
+  private:
+    mcenum_emission emission_;
+    gpt_state state_;
+    double seconds_for_input_;
+    double seconds_for_calculations_;
+    double seconds_for_output_;
+};
+
+#endif // gpt_server_hpp
+


Property changes on: lmi/trunk/gpt_server.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_state.cpp
===================================================================
--- lmi/trunk/gpt_state.cpp                             (rev 0)
+++ lmi/trunk/gpt_state.cpp     2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,375 @@
+// Transient state of guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "gpt_state.hpp"
+#include "xml_serializable.tpp"
+
+#include "alert.hpp"
+#include "contains.hpp"
+#include "miscellany.hpp" // htmlize(), lmi_array_size()
+#include "value_cast.hpp"
+#include "xml_lmi.hpp"
+
+#include <boost/filesystem/fstream.hpp>
+
+#include <limits>
+#include <sstream>
+#include <vector>
+
+template class xml_serializable<gpt_state>;
+
+/// Initialize all ascribed members to zero.
+
+gpt_state::gpt_state()
+{
+    AscribeMembers();
+    std::vector<std::string>::const_iterator i;
+    for(i = member_names().begin(); i != member_names().end(); ++i)
+        {
+        operator[](*i) = "0";
+        }
+}
+
+gpt_state::gpt_state(gpt_state const& z)
+    :obstruct_slicing  <gpt_state>()
+    ,xml_serializable  <gpt_state>()
+    ,MemberSymbolTable <gpt_state>()
+{
+    AscribeMembers();
+    MemberSymbolTable<gpt_state>::assign(z);
+}
+
+gpt_state::~gpt_state()
+{
+}
+
+gpt_state& gpt_state::operator=(gpt_state const& z)
+{
+    MemberSymbolTable<gpt_state>::assign(z);
+    return *this;
+}
+
+bool gpt_state::operator==(gpt_state const& z) const
+{
+    return MemberSymbolTable<gpt_state>::equals(z);
+}
+
+namespace
+{
+template<typename T>
+std::string f(T t)
+{
+    return "&nbsp;&nbsp;&nbsp;" + value_cast<std::string>(t);
+}
+
+template<>
+std::string f<>(double t)
+{
+    static double const bignum = std::numeric_limits<double>::max();
+    if(bignum == t)
+        {
+        return "&nbsp;&nbsp;&nbsp;BIGNUM";
+        }
+    else
+        {
+        return "&nbsp;&nbsp;&nbsp;" + value_cast<std::string>(t);
+        }
+}
+} // Unnamed namespace.
+
+std::string gpt_state::format_as_html(std::string const& heading) const
+{
+    std::ostringstream oss;
+
+    oss
+        << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n"
+        << "    \"http://www.w3.org/TR/html4/loose.dtd\";>\n"
+        << "<html>\n"
+        << "<head>\n"
+        << "<meta http-equiv=\"Content-Type\" content=\"text/html; 
charset=ISO-8859-1\">\n"
+        << "<title>Let me illustrate...</title>\n"
+        << "</head>\n"
+        << "<body>\n"
+        ;
+
+    oss << "<p>" << htmlize(heading) << "</p>\n";
+
+    oss
+        << "<hr>\n"
+        << "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" 
width=\"100%\">\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "policy year"                     << "</td>\n"
+        << "<td nowrap>" << f(B0_deduced_policy_year   ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "contract year"                   << "</td>\n"
+        << "<td nowrap>" << f(B1_deduced_contract_year ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "seven-pay rate"                  << "</td>\n"
+        << "<td nowrap>" << f(B2_deduced_px7_rate      ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "nsp rate"                        << "</td>\n"
+        << "<td nowrap>" << f(B3_deduced_nsp_rate      ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "target premium"                  << "</td>\n"
+        << "<td nowrap>" << f(B4_deduced_target_premium) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "target load"                     << "</td>\n"
+        << "<td nowrap>" << f(B5_deduced_target_load   ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "excess load"                     << "</td>\n"
+        << "<td nowrap>" << f(B6_deduced_excess_load   ) << "</td>\n"
+        << "</tr>\n"
+        << "</table>\n"
+        ;
+
+    oss
+        << "<hr>\n"
+        << "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" 
width=\"100%\">\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << ""           << " </td>\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << "initial"    << " </td>\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << "incr"       << " </td>\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << "decr"       << " </td>\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << "nec_prem"   << " </td>\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << "MC"         << " </td>\n"
+        << "<td valign=\"bottom\" width=\"14%\">" << "unnec_prem" << " </td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "benefit"                   << "</td>\n"
+        << "<td nowrap>" << f(C0_init_bft       ) << "</td>\n"
+        << "<td nowrap>" << f(D0_incr_bft       ) << "</td>\n"
+        << "<td nowrap>" << f(E0_decr_bft       ) << "</td>\n"
+        << "<td nowrap>" << f(F0_nec_pm_bft     ) << "</td>\n"
+        << "<td nowrap>" << f(G0_do_mc_bft      ) << "</td>\n"
+        << "<td nowrap>" << f(H0_unnec_pm_bft   ) << "</td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "LDB"                       << "</td>\n"
+        << "<td nowrap>" << f(C1_init_ldb       ) << "</td>\n"
+        << "<td nowrap>" << f(D1_incr_ldb       ) << "</td>\n"
+        << "<td nowrap>" << f(E1_decr_ldb       ) << "</td>\n"
+        << "<td nowrap>" << f(F1_nec_pm_ldb     ) << "</td>\n"
+        << "<td nowrap>" << f(G1_do_mc_ldb      ) << "</td>\n"
+        << "<td nowrap>" << f(H1_unnec_pm_ldb   ) << "</td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "amts pd"                   << "</td>\n"
+        << "<td nowrap>" << f(C2_init_amt_pd    ) << "</td>\n"
+        << "<td nowrap>" << f(D2_incr_amt_pd    ) << "</td>\n"
+        << "<td nowrap>" << f(E2_decr_amt_pd    ) << "</td>\n"
+        << "<td nowrap>" << f(F2_nec_pm_amt_pd  ) << "</td>\n"
+        << "<td nowrap>" << f(G2_do_mc_amt_pd   ) << "</td>\n"
+        << "<td nowrap>" << f(H2_unnec_pm_amt_pd) << "</td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "MC"                        << "</td>\n"
+        << "<td nowrap>" << f(C3_init_is_mc     ) << "</td>\n"
+        << "<td nowrap>" << f(D3_incr_is_mc     ) << "</td>\n"
+        << "<td nowrap>" << f(E3_decr_is_mc     ) << "</td>\n"
+        << "<td nowrap>" << f(F3_nec_pm_is_mc   ) << "</td>\n"
+        << "<td nowrap>" << f(G3_do_mc_is_mc    ) << "</td>\n"
+        << "<td nowrap>" << f(H3_unnec_pm_is_mc ) << "</td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "DCV"                       << "</td>\n"
+        << "<td nowrap>" << f(C4_init_dcv       ) << "</td>\n"
+        << "<td nowrap>" << f(D4_incr_dcv       ) << "</td>\n"
+        << "<td nowrap>" << f(E4_decr_dcv       ) << "</td>\n"
+        << "<td nowrap>" << f(F4_nec_pm_dcv     ) << "</td>\n"
+        << "<td nowrap>" << f(G4_do_mc_dcv      ) << "</td>\n"
+        << "<td nowrap>" << f(H4_unnec_pm_dcv   ) << "</td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "7PP"                       << "</td>\n"
+        << "<td nowrap>" << f(C5_init_px7       ) << "</td>\n"
+        << "<td nowrap>" << f(D5_incr_px7       ) << "</td>\n"
+        << "<td nowrap>" << f(E5_decr_px7       ) << "</td>\n"
+        << "<td nowrap>" << f(F5_nec_pm_px7     ) << "</td>\n"
+        << "<td nowrap>" << f(G5_do_mc_px7      ) << "</td>\n"
+        << "<td nowrap>" << f(H5_unnec_pm_px7   ) << "</td>\n"
+        << "</tr>\n"
+
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "MEC"                       << "</td>\n"
+        << "<td nowrap>" << f(C6_init_mec       ) << "</td>\n"
+        << "<td nowrap>" << f(D6_incr_mec       ) << "</td>\n"
+        << "<td nowrap>" << f(E6_decr_mec       ) << "</td>\n"
+        << "<td nowrap>" << f(F6_nec_pm_mec     ) << "</td>\n"
+        << "<td nowrap>" << f(G6_do_mc_mec      ) << "</td>\n"
+        << "<td nowrap>" << f(H6_unnec_pm_mec   ) << "</td>\n"
+        << "</tr>\n"
+
+        << "</table>\n"
+        ;
+
+    oss
+        << "<hr>\n"
+        << "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" 
width=\"100%\">\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "net 1035 amount"              << "</td>\n"
+        << "<td nowrap>" << f(Q0_net_1035          ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "net max necessary premium"    << "</td>\n"
+        << "<td nowrap>" << f(Q1_max_nec_prem_net  ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "gross max necessary premium"  << "</td>\n"
+        << "<td nowrap>" << f(Q2_max_nec_prem_gross) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "CV before last MC"            << "</td>\n"
+        << "<td nowrap>" << f(Q3_cv_before_last_mc ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "cumulative seven-pay premium" << "</td>\n"
+        << "<td nowrap>" << f(Q4_cum_px7           ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "cumulative amounts paid"      << "</td>\n"
+        << "<td nowrap>" << f(Q5_cum_amt_pd        ) << "</td>\n"
+        << "</tr>\n"
+        << "<tr align=\"right\">\n"
+        << "<td nowrap>" << "max non-MEC premium"          << "</td>\n"
+        << "<td nowrap>" << f(Q6_max_non_mec_prem  ) << "</td>\n"
+        << "</tr>\n"
+        << "</table>\n"
+        ;
+
+    oss
+        << "</body>\n"
+        << "</html>\n"
+        ;
+
+    return oss.str();
+}
+
+void gpt_state::AscribeMembers()
+{
+    ascribe("B0_deduced_policy_year"   , &gpt_state::B0_deduced_policy_year   
);
+    ascribe("B1_deduced_contract_year" , &gpt_state::B1_deduced_contract_year 
);
+    ascribe("B2_deduced_px7_rate"      , &gpt_state::B2_deduced_px7_rate      
);
+    ascribe("B3_deduced_nsp_rate"      , &gpt_state::B3_deduced_nsp_rate      
);
+    ascribe("B4_deduced_target_premium", 
&gpt_state::B4_deduced_target_premium);
+    ascribe("B5_deduced_target_load"   , &gpt_state::B5_deduced_target_load   
);
+    ascribe("B6_deduced_excess_load"   , &gpt_state::B6_deduced_excess_load   
);
+
+    ascribe("C0_init_bft"              , &gpt_state::C0_init_bft              
);
+    ascribe("C1_init_ldb"              , &gpt_state::C1_init_ldb              
);
+    ascribe("C2_init_amt_pd"           , &gpt_state::C2_init_amt_pd           
);
+    ascribe("C3_init_is_mc"            , &gpt_state::C3_init_is_mc            
);
+    ascribe("C4_init_dcv"              , &gpt_state::C4_init_dcv              
);
+    ascribe("C5_init_px7"              , &gpt_state::C5_init_px7              
);
+    ascribe("C6_init_mec"              , &gpt_state::C6_init_mec              
);
+
+    ascribe("D0_incr_bft"              , &gpt_state::D0_incr_bft              
);
+    ascribe("D1_incr_ldb"              , &gpt_state::D1_incr_ldb              
);
+    ascribe("D2_incr_amt_pd"           , &gpt_state::D2_incr_amt_pd           
);
+    ascribe("D3_incr_is_mc"            , &gpt_state::D3_incr_is_mc            
);
+    ascribe("D4_incr_dcv"              , &gpt_state::D4_incr_dcv              
);
+    ascribe("D5_incr_px7"              , &gpt_state::D5_incr_px7              
);
+    ascribe("D6_incr_mec"              , &gpt_state::D6_incr_mec              
);
+
+    ascribe("E0_decr_bft"              , &gpt_state::E0_decr_bft              
);
+    ascribe("E1_decr_ldb"              , &gpt_state::E1_decr_ldb              
);
+    ascribe("E2_decr_amt_pd"           , &gpt_state::E2_decr_amt_pd           
);
+    ascribe("E3_decr_is_mc"            , &gpt_state::E3_decr_is_mc            
);
+    ascribe("E4_decr_dcv"              , &gpt_state::E4_decr_dcv              
);
+    ascribe("E5_decr_px7"              , &gpt_state::E5_decr_px7              
);
+    ascribe("E6_decr_mec"              , &gpt_state::E6_decr_mec              
);
+
+    ascribe("F0_nec_pm_bft"            , &gpt_state::F0_nec_pm_bft            
);
+    ascribe("F1_nec_pm_ldb"            , &gpt_state::F1_nec_pm_ldb            
);
+    ascribe("F2_nec_pm_amt_pd"         , &gpt_state::F2_nec_pm_amt_pd         
);
+    ascribe("F3_nec_pm_is_mc"          , &gpt_state::F3_nec_pm_is_mc          
);
+    ascribe("F4_nec_pm_dcv"            , &gpt_state::F4_nec_pm_dcv            
);
+    ascribe("F5_nec_pm_px7"            , &gpt_state::F5_nec_pm_px7            
);
+    ascribe("F6_nec_pm_mec"            , &gpt_state::F6_nec_pm_mec            
);
+
+    ascribe("G0_do_mc_bft"             , &gpt_state::G0_do_mc_bft             
);
+    ascribe("G1_do_mc_ldb"             , &gpt_state::G1_do_mc_ldb             
);
+    ascribe("G2_do_mc_amt_pd"          , &gpt_state::G2_do_mc_amt_pd          
);
+    ascribe("G3_do_mc_is_mc"           , &gpt_state::G3_do_mc_is_mc           
);
+    ascribe("G4_do_mc_dcv"             , &gpt_state::G4_do_mc_dcv             
);
+    ascribe("G5_do_mc_px7"             , &gpt_state::G5_do_mc_px7             
);
+    ascribe("G6_do_mc_mec"             , &gpt_state::G6_do_mc_mec             
);
+
+    ascribe("H0_unnec_pm_bft"          , &gpt_state::H0_unnec_pm_bft          
);
+    ascribe("H1_unnec_pm_ldb"          , &gpt_state::H1_unnec_pm_ldb          
);
+    ascribe("H2_unnec_pm_amt_pd"       , &gpt_state::H2_unnec_pm_amt_pd       
);
+    ascribe("H3_unnec_pm_is_mc"        , &gpt_state::H3_unnec_pm_is_mc        
);
+    ascribe("H4_unnec_pm_dcv"          , &gpt_state::H4_unnec_pm_dcv          
);
+    ascribe("H5_unnec_pm_px7"          , &gpt_state::H5_unnec_pm_px7          
);
+    ascribe("H6_unnec_pm_mec"          , &gpt_state::H6_unnec_pm_mec          
);
+
+    ascribe("Q0_net_1035"              , &gpt_state::Q0_net_1035              
);
+    ascribe("Q1_max_nec_prem_net"      , &gpt_state::Q1_max_nec_prem_net      
);
+    ascribe("Q2_max_nec_prem_gross"    , &gpt_state::Q2_max_nec_prem_gross    
);
+    ascribe("Q3_cv_before_last_mc"     , &gpt_state::Q3_cv_before_last_mc     
);
+    ascribe("Q4_cum_px7"               , &gpt_state::Q4_cum_px7               
);
+    ascribe("Q5_cum_amt_pd"            , &gpt_state::Q5_cum_amt_pd            
);
+    ascribe("Q6_max_non_mec_prem"      , &gpt_state::Q6_max_non_mec_prem      
);
+}
+
+/// Backward-compatibility serial number of this class's xml version.
+///
+/// version 0: 20140615T1717Z
+
+int gpt_state::class_version() const
+{
+    return 0;
+}
+
+std::string const& gpt_state::xml_root_name() const
+{
+    static std::string const s("gpt_state");
+    return s;
+}
+
+bool gpt_state::is_detritus(std::string const& s) const
+{
+    static std::string const a[] =
+        {"Remove this string when adding the first removed entity."
+        };
+    static std::vector<std::string> const v(a, a + lmi_array_size(a));
+    return contains(v, s);
+}
+


Property changes on: lmi/trunk/gpt_state.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_state.hpp
===================================================================
--- lmi/trunk/gpt_state.hpp                             (rev 0)
+++ lmi/trunk/gpt_state.hpp     2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,142 @@
+// Transient state of guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_state_hpp
+#define gpt_state_hpp
+
+#include "config.hpp"
+
+#include "any_member.hpp"
+#include "obstruct_slicing.hpp"
+#include "so_attributes.hpp"
+#include "xml_serializable.hpp"
+
+#include <boost/filesystem/path.hpp>
+#include <boost/operators.hpp>
+
+#include <string>
+
+/// Transient state of guideline premium test.
+///
+/// For design discussion, see:
+///   http://lists.nongnu.org/archive/html/lmi/2009-07/msg00002.html
+///
+/// Variables are prefixed '[A-Z][0-9]_' so that they sort by groups:
+/// in particular, when their names are used to nominate xml elements.
+/// 'A*_' is reserved in case it's wanted later--e.g., for arguments.
+
+class LMI_SO gpt_state
+    :virtual private obstruct_slicing           <gpt_state>
+    ,        public  xml_serializable           <gpt_state>
+    ,        public  MemberSymbolTable          <gpt_state>
+    ,        private boost::equality_comparable <gpt_state>
+{
+    friend class Irc7702A;
+
+  public:
+    gpt_state();
+    gpt_state(gpt_state const&);
+    virtual ~gpt_state();
+
+    gpt_state& operator=(gpt_state const&);
+    bool operator==(gpt_state const&) const;
+
+    std::string format_as_html(std::string const& heading) const;
+
+  private:
+    void AscribeMembers();
+
+    // xml_serializable required implementation.
+    virtual int                class_version() const;
+    virtual std::string const& xml_root_name() const;
+
+    // xml_serializable overrides.
+    virtual bool is_detritus(std::string const&) const;
+
+    int    B0_deduced_policy_year;
+    int    B1_deduced_contract_year;
+    double B2_deduced_px7_rate;
+    double B3_deduced_nsp_rate;
+    double B4_deduced_target_premium;
+    double B5_deduced_target_load;
+    double B6_deduced_excess_load;
+
+    double C0_init_bft;
+    double C1_init_ldb;
+    double C2_init_amt_pd;
+    bool   C3_init_is_mc;
+    double C4_init_dcv;
+    double C5_init_px7;
+    bool   C6_init_mec;
+
+    double D0_incr_bft;
+    double D1_incr_ldb;
+    double D2_incr_amt_pd;
+    bool   D3_incr_is_mc;
+    double D4_incr_dcv;
+    double D5_incr_px7;
+    bool   D6_incr_mec;
+
+    double E0_decr_bft;
+    double E1_decr_ldb;
+    double E2_decr_amt_pd;
+    bool   E3_decr_is_mc;
+    double E4_decr_dcv;
+    double E5_decr_px7;
+    bool   E6_decr_mec;
+
+    double F0_nec_pm_bft;
+    double F1_nec_pm_ldb;
+    double F2_nec_pm_amt_pd;
+    bool   F3_nec_pm_is_mc;
+    double F4_nec_pm_dcv;
+    double F5_nec_pm_px7;
+    bool   F6_nec_pm_mec;
+
+    double G0_do_mc_bft;
+    double G1_do_mc_ldb;
+    double G2_do_mc_amt_pd;
+    bool   G3_do_mc_is_mc;
+    double G4_do_mc_dcv;
+    double G5_do_mc_px7;
+    bool   G6_do_mc_mec;
+
+    double H0_unnec_pm_bft;
+    double H1_unnec_pm_ldb;
+    double H2_unnec_pm_amt_pd;
+    bool   H3_unnec_pm_is_mc;
+    double H4_unnec_pm_dcv;
+    double H5_unnec_pm_px7;
+    bool   H6_unnec_pm_mec;
+
+    double Q0_net_1035;
+    double Q1_max_nec_prem_net;
+    double Q2_max_nec_prem_gross;
+    double Q3_cv_before_last_mc;
+    double Q4_cum_px7;
+    double Q5_cum_amt_pd;
+    double Q6_max_non_mec_prem;
+};
+
+#endif // gpt_state_hpp
+


Property changes on: lmi/trunk/gpt_state.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_view.cpp
===================================================================
--- lmi/trunk/gpt_view.cpp                              (rev 0)
+++ lmi/trunk/gpt_view.cpp      2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,221 @@
+// Document view for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "gpt_view.hpp"
+
+#include "edit_mvc_docview_parameters.hpp"
+#include "gpt_document.hpp"
+#include "gpt_input.hpp"
+#include "gpt_server.hpp"
+#include "handle_exceptions.hpp"
+#include "safely_dereference_as.hpp"
+#include "wx_new.hpp"
+
+#include <wx/html/htmlwin.h>
+#include <wx/html/htmprint.h>
+#include <wx/icon.h>
+#include <wx/menu.h>
+#include <wx/xrc/xmlres.h>
+
+gpt_mvc_view::gpt_mvc_view()
+{
+}
+
+gpt_mvc_view::~gpt_mvc_view()
+{
+}
+
+char const* gpt_mvc_view::DoBookControlName() const
+{
+    return "gpt_notebook";
+}
+
+char const* gpt_mvc_view::DoMainDialogName() const
+{
+    return "dialog_containing_gpt_notebook";
+}
+
+char const* gpt_mvc_view::DoResourceFileName() const
+{
+    return "gpt.xrc";
+}
+
+IMPLEMENT_DYNAMIC_CLASS(gpt_view, ViewEx)
+
+BEGIN_EVENT_TABLE(gpt_view, ViewEx)
+    EVT_MENU(XRCID("edit_cell"             ),gpt_view::UponProperties)
+    EVT_UPDATE_UI(wxID_SAVE                 ,gpt_view::UponUpdateFileSave)
+    EVT_UPDATE_UI(wxID_SAVEAS               ,gpt_view::UponUpdateFileSaveAs)
+    EVT_UPDATE_UI(XRCID("edit_cell"        ),gpt_view::UponUpdateProperties)
+
+// There has to be a better way to inhibit these inapplicable ids.
+    EVT_UPDATE_UI(XRCID("edit_class"           
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("edit_case"            
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("run_cell"             
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("run_class"            
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("run_case"             
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("print_cell"           
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("print_class"          
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("print_case"           
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("print_case_to_disk"   
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("print_spreadsheet"    
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("print_group_roster"   
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("paste_census"         
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("add_cell"             
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("delete_cells"         
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("column_width_varying" 
),gpt_view::UponUpdateInapplicable)
+    EVT_UPDATE_UI(XRCID("column_width_fixed"   
),gpt_view::UponUpdateInapplicable)
+END_EVENT_TABLE()
+
+gpt_view::gpt_view()
+    :ViewEx       ()
+    ,html_content_("Unable to display results.")
+    ,html_window_ (0)
+{
+}
+
+gpt_view::~gpt_view()
+{
+}
+
+inline gpt_input& gpt_view::input_data()
+{
+    return document().doc_.input_data_;
+}
+
+gpt_document& gpt_view::document() const
+{
+    return safely_dereference_as<gpt_document>(GetDocument());
+}
+
+wxWindow* gpt_view::CreateChildWindow()
+{
+    return html_window_ = new(wx) wxHtmlWindow(GetFrame());
+}
+
+oenum_mvc_dv_rc gpt_view::edit_parameters()
+{
+    return edit_mvc_docview_parameters<gpt_mvc_view>
+        (input_data()
+        ,document()
+        ,GetFrame()
+        );
+}
+
+wxIcon gpt_view::Icon() const
+{
+    return IconFromXmlResource("gpt_view_icon");
+}
+
+wxMenuBar* gpt_view::MenuBar() const
+{
+    return MenuBarFromXmlResource("gpt_view_menu");
+}
+
+/// This virtual function calls its base-class namesake explicitly.
+///
+/// Trap exceptions to ensure that this function returns 'false' on
+/// failure, lest wx's doc-view framework create a zombie view. See:
+///   http://lists.nongnu.org/archive/html/lmi/2008-12/msg00017.html
+
+bool gpt_view::OnCreate(wxDocument* doc, long int flags)
+{
+    bool has_view_been_created = false;
+    try
+        {
+        if(oe_mvc_dv_cancelled == edit_parameters())
+            {
+            return has_view_been_created;
+            }
+
+        has_view_been_created = ViewEx::OnCreate(doc, flags);
+        if(!has_view_been_created)
+            {
+            return has_view_been_created;
+            }
+
+        Run();
+        }
+    catch(...)
+        {
+        report_exception();
+        }
+
+    return has_view_been_created;
+}
+
+wxPrintout* gpt_view::OnCreatePrintout()
+{
+    wxHtmlPrintout* z = new(wx) wxHtmlPrintout;
+    
safely_dereference_as<wxHtmlPrintout>(z).SetHtmlText(html_content_.c_str());
+    return z;
+}
+
+void gpt_view::UponProperties(wxCommandEvent&)
+{
+    if(oe_mvc_dv_changed == edit_parameters())
+        {
+        Run();
+        }
+}
+
+/// This complete replacement for wxDocManager::OnUpdateFileSave()
+/// should not call Skip().
+
+void gpt_view::UponUpdateFileSave(wxUpdateUIEvent& e)
+{
+    e.Enable(document().IsModified());
+}
+
+/// This complete replacement for wxDocManager::OnUpdateFileSaveAs()
+/// should not call Skip().
+
+void gpt_view::UponUpdateFileSaveAs(wxUpdateUIEvent& e)
+{
+    e.Enable(true);
+}
+
+void gpt_view::UponUpdateInapplicable(wxUpdateUIEvent& e)
+{
+    e.Enable(false);
+}
+
+void gpt_view::UponUpdateProperties(wxUpdateUIEvent& e)
+{
+    e.Enable(true);
+}
+
+void gpt_view::Run()
+{
+    input_data().RealizeAllSequenceInput();
+    gpt_server server(mce_emit_test_data);
+    server(base_filename(), input_data());
+    html_content_ = 
server.state().format_as_html(input_data()["Comments"].str());
+    html_window_->SetPage(html_content_);
+}
+


Property changes on: lmi/trunk/gpt_view.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_view.hpp
===================================================================
--- lmi/trunk/gpt_view.hpp                              (rev 0)
+++ lmi/trunk/gpt_view.hpp      2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,109 @@
+// Document view for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_view_hpp
+#define gpt_view_hpp
+
+#include "config.hpp"
+
+#include "mvc_view.hpp"
+#include "view_ex.hpp"
+
+#include "obstruct_slicing.hpp"
+#include "oecumenic_enumerations.hpp"
+#include "uncopyable_lmi.hpp"
+
+#include <wx/event.h>
+
+#include <string>
+
+class gpt_document;
+class gpt_input;
+class WXDLLIMPEXP_FWD_CORE wxHtmlWindow;
+
+/// MVC View for GPT.
+///
+/// This class has external linkage so that it can be used to preload
+/// XRC resources at startup in order to diagnose their absence early.
+///
+/// Implicitly-declared special member functions do the right thing.
+
+class gpt_mvc_view
+    :public MvcView
+{
+  public:
+    gpt_mvc_view();
+    virtual ~gpt_mvc_view();
+
+  private:
+    // MvcView required implementation.
+    virtual char const* DoBookControlName () const;
+    virtual char const* DoMainDialogName  () const;
+    virtual char const* DoResourceFileName() const;
+};
+
+class gpt_view
+    :        public  ViewEx
+    ,        private lmi::uncopyable <gpt_view>
+    ,virtual private obstruct_slicing<gpt_view>
+{
+    friend class gpt_document;
+
+  public:
+    gpt_view();
+    virtual ~gpt_view();
+
+  private:
+    gpt_document& document() const;
+
+    oenum_mvc_dv_rc edit_parameters();
+    void Run();
+
+    // ViewEx required implementation.
+    virtual wxWindow* CreateChildWindow();
+    virtual wxIcon Icon() const;
+    virtual wxMenuBar* MenuBar() const;
+
+    // ViewEx overrides.
+    virtual bool OnCreate(wxDocument*, long int);
+
+    // wxView overrides.
+    virtual wxPrintout* OnCreatePrintout();
+
+    void UponProperties        (wxCommandEvent&);
+    void UponUpdateFileSave    (wxUpdateUIEvent&);
+    void UponUpdateFileSaveAs  (wxUpdateUIEvent&);
+    void UponUpdateInapplicable(wxUpdateUIEvent&);
+    void UponUpdateProperties  (wxUpdateUIEvent&);
+
+    gpt_input& input_data();
+
+    std::string html_content_;
+    wxHtmlWindow* html_window_;
+
+    DECLARE_DYNAMIC_CLASS(gpt_view)
+    DECLARE_EVENT_TABLE()
+};
+
+#endif // gpt_view_hpp
+


Property changes on: lmi/trunk/gpt_view.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_view.png
===================================================================
(Binary files differ)


Property changes on: lmi/trunk/gpt_view.png
___________________________________________________________________
Added: svn:mime-type
   + image/png
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_xml_document.cpp
===================================================================
--- lmi/trunk/gpt_xml_document.cpp                              (rev 0)
+++ lmi/trunk/gpt_xml_document.cpp      2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,100 @@
+// xml document for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "gpt_xml_document.hpp"
+
+#include "assert_lmi.hpp"
+#include "xml_lmi.hpp"
+
+#include <xmlwrapp/nodes_view.h>
+
+#include <istream>
+#include <ostream>
+
+//============================================================================
+gpt_xml_document::gpt_xml_document()
+    :input_data_()
+{
+}
+
+//============================================================================
+gpt_xml_document::gpt_xml_document(gpt_input const& z)
+    :input_data_(z)
+{
+}
+
+//============================================================================
+gpt_xml_document::gpt_xml_document(std::string const& filename)
+    :input_data_()
+{
+    xml_lmi::dom_parser parser(filename);
+    parse(parser);
+}
+
+//============================================================================
+gpt_xml_document::~gpt_xml_document()
+{
+}
+
+//============================================================================
+std::string const& gpt_xml_document::xml_root_name() const
+{
+    static std::string const s("gpt_xml_document");
+    return s;
+}
+
+//============================================================================
+void gpt_xml_document::parse(xml_lmi::dom_parser const& parser)
+{
+    xml::element const& root(parser.root_node(xml_root_name()));
+    xml::const_nodes_view const elements(root.elements());
+    LMI_ASSERT(!elements.empty());
+    xml::const_nodes_view::const_iterator i(elements.begin());
+    *i >> input_data_;
+    // XMLWRAPP !! It would be better to have operator+(int) in the
+    // iterator class, and to write this check above as
+    //   LMI_ASSERT(elements.end() == 1 + i);
+    LMI_ASSERT(elements.end() == ++i);
+}
+
+//============================================================================
+void gpt_xml_document::read(std::istream const& is)
+{
+    xml_lmi::dom_parser parser(is);
+    parse(parser);
+}
+
+//============================================================================
+void gpt_xml_document::write(std::ostream& os) const
+{
+    xml_lmi::xml_document document(xml_root_name());
+    xml::element& root = document.root_node();
+    root << input_data_;
+    os << document;
+}
+


Property changes on: lmi/trunk/gpt_xml_document.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_xml_document.hpp
===================================================================
--- lmi/trunk/gpt_xml_document.hpp                              (rev 0)
+++ lmi/trunk/gpt_xml_document.hpp      2014-06-15 17:17:49 UTC (rev 5893)
@@ -0,0 +1,69 @@
+// xml document for guideline premium test.
+//
+// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_xml_document_hpp
+#define gpt_xml_document_hpp
+
+#include "config.hpp"
+
+#include "gpt_input.hpp"
+#include "obstruct_slicing.hpp"
+#include "so_attributes.hpp"
+#include "uncopyable_lmi.hpp"
+#include "xml_lmi_fwd.hpp"
+
+#include <iosfwd>
+#include <string>
+
+class LMI_SO gpt_xml_document
+    :        private lmi::uncopyable <gpt_xml_document>
+    ,virtual private obstruct_slicing<gpt_xml_document>
+{
+    friend class gpt_document;
+    friend class gpt_view;
+
+  public:
+    gpt_xml_document();
+    gpt_xml_document(gpt_input const&);
+    gpt_xml_document(std::string const& filename);
+    ~gpt_xml_document();
+
+    gpt_input const& input_data() const;
+
+    void read(std::istream const&);
+    void write(std::ostream&) const;
+
+  private:
+    void parse(xml_lmi::dom_parser const&);
+    std::string const& xml_root_name() const;
+
+    gpt_input input_data_;
+};
+
+inline gpt_input const& gpt_xml_document::input_data() const
+{
+    return input_data_;
+}
+
+#endif // gpt_xml_document_hpp
+


Property changes on: lmi/trunk/gpt_xml_document.hpp
___________________________________________________________________
Added: svn:keywords
   + Id




reply via email to

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