lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] odd/concepts_smf c0bed46c 2/2: Experiment with stand


From: Greg Chicares
Subject: [lmi-commits] [lmi] odd/concepts_smf c0bed46c 2/2: Experiment with standard and smf concepts
Date: Sun, 2 Oct 2022 19:25:29 -0400 (EDT)

branch: odd/concepts_smf
commit c0bed46cc7a9433c0259a8e0386bc91ee1441bdc
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Experiment with standard and smf concepts
    
    Is there any value in asserting that classes satisfy such concepts as
    std::[semi]regular and well_move_constructible? Consider, for example,
    the classes in 'ce_*_name.hpp' that satisfy both. (If we want to add
    such assertions generally, then we should probably create our own
    'concepts_lmi.hpp' that would include the headers for both families.)
    
    Abstract classes cannot be regular or semiregular. We might assert that
    they derive from lmi::abstract_base<>, but adding such an assertion to
    the actual derivation seems silly. Should we assert that they are
    well_move_assignable, to ensure that move operations haven't silently
    been elided due to an accidental oversight?
    
    Some classes would be std::regular except that they are not default-
    constructible. There might be some value in identifying such classes,
    in case there's no good reason not to provide a default ctor. Where the
    lack of a default ctor is intentional (e.g., a file-dependent class that
    should be constructed only with a valid file-name argument that cannot
    reasonably be defaulted), we might create a new 'concept' to facilitate
    asserting the other std::regular requirements.
    
    What of a class such as FundData, which seems to fulfill none of the
    std::regular requirements--is it desirable to add a fully_irregular
    concept just to make the class taxonomy complete?
    
    Also consider class tn_range<>, for which it does not seem readily
    feasible to assert concepts about the class template itself as opposed
    to its template parameters. Does this difficulty suggest that the whole
    exercise is conceptually flawed, as being a misuse of the 'concepts'
    concept?
---
 any_entity.hpp         |  7 +++++++
 any_member_test.cpp    | 10 ++++++++++
 ce_product_name.hpp    |  5 +++++
 ce_skin_name.hpp       |  5 +++++
 datum_base.hpp         |  7 +++++++
 datum_boolean.hpp      |  6 ++++++
 datum_sequence.hpp     |  8 +++++++-
 datum_string.hpp       | 11 ++++++++++-
 dbvalue.hpp            |  5 +++++
 fund_data.hpp          | 11 +++++++++++
 gpt_server.hpp         |  7 +++++++
 illustrator.hpp        |  6 ++++++
 ledger.hpp             |  6 ++++++
 mec_server.hpp         |  7 +++++++
 product_data.hpp       |  5 +++++
 rounding_rules.hpp     |  6 ++++++
 rtti_lmi.hpp           |  7 +++++++
 stratified_charges.hpp |  5 +++++
 test_coding_rules.cpp  |  5 +++++
 tn_range.hpp           |  6 ++++++
 tn_range.tpp           |  7 +++++++
 yare_input.hpp         |  6 ++++++
 22 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/any_entity.hpp b/any_entity.hpp
index 8097235a..388f8eb4 100644
--- a/any_entity.hpp
+++ b/any_entity.hpp
@@ -25,9 +25,12 @@
 #include "config.hpp"
 
 #include "crtp_base.hpp"                // abstract_base
+#include "smf.hpp"                      // well_move_*<>
 
+//#include <concepts>
 #include <ostream>
 #include <string>
+#include <type_traits>
 #include <typeinfo>
 
 /// Abstract class any_entity specifies the interface required for
@@ -45,6 +48,10 @@ class any_entity : private lmi::abstract_base<any_entity>
   private:
     virtual any_entity& assign(std::string const&) = 0;
 };
+static_assert(std::is_abstract_v<any_entity>);
+//static_assert(std::regular<any_entity>);
+static_assert(well_move_assignable<any_entity>);
+//static_assert(well_move_constructible<any_entity>);
 
 /// Design notes: numeric stream output.
 ///
diff --git a/any_member_test.cpp b/any_member_test.cpp
index 9529264e..2efffb12 100644
--- a/any_member_test.cpp
+++ b/any_member_test.cpp
@@ -24,14 +24,17 @@
 #include "any_member.hpp"
 
 #include "crtp_base.hpp"                // abstract_base
+#include "smf.hpp"                      // well_move_*<>
 #include "test_tools.hpp"
 
 #include <cmath>                        // exp()
+//#include <concepts>
 #include <functional>
 #include <iostream>
 #include <istream>
 #include <ostream>
 #include <sstream>
+#include <type_traits>
 
 struct base_datum : private lmi::abstract_base<base_datum>
 {
@@ -46,6 +49,10 @@ struct base_datum : private lmi::abstract_base<base_datum>
 
     int sane;
 };
+static_assert(std::is_abstract_v<base_datum>);
+//static_assert(std::regular<base_datum>);
+static_assert(well_move_assignable<base_datum>);
+//static_assert(well_move_constructible<base_datum>);
 
 // Unused stub.
 std::istream& operator>>(std::istream& is, base_datum&      )
@@ -68,6 +75,9 @@ struct derived_datum final
   private:
     void concrete_if_not_pure() override {}
 };
+static_assert(std::regular<derived_datum>);
+static_assert(well_move_assignable<derived_datum>);
+static_assert(well_move_constructible<derived_datum>);
 
 // Unused stub.
 std::istream& operator>>(std::istream& is, derived_datum&      )
diff --git a/ce_product_name.hpp b/ce_product_name.hpp
index 3b4bef58..d7c9c6cf 100644
--- a/ce_product_name.hpp
+++ b/ce_product_name.hpp
@@ -25,8 +25,10 @@
 #include "config.hpp"
 
 #include "mc_enum.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 
+#include <concepts>
 #include <iosfwd>
 #include <string>
 #include <vector>
@@ -85,6 +87,9 @@ class LMI_SO ce_product_name final
 
     std::string value_;
 };
+static_assert(std::regular<ce_product_name>);
+static_assert(well_move_assignable<ce_product_name>);
+static_assert(well_move_constructible<ce_product_name>);
 
 bool operator==(std::string const&, ce_product_name const&);
 
diff --git a/ce_skin_name.hpp b/ce_skin_name.hpp
index 94f38f39..57b06d5c 100644
--- a/ce_skin_name.hpp
+++ b/ce_skin_name.hpp
@@ -25,7 +25,9 @@
 #include "config.hpp"
 
 #include "mc_enum.hpp"
+#include "smf.hpp"                      // well_move_*<>
 
+#include <concepts>
 #include <string>
 #include <vector>
 
@@ -75,5 +77,8 @@ class ce_skin_name final
 
     std::string value_;
 };
+static_assert(std::regular<ce_skin_name>);
+static_assert(well_move_assignable<ce_skin_name>);
+static_assert(well_move_constructible<ce_skin_name>);
 
 #endif // ce_skin_name_hpp
diff --git a/datum_base.hpp b/datum_base.hpp
index d92afc9d..e29dcc6b 100644
--- a/datum_base.hpp
+++ b/datum_base.hpp
@@ -25,9 +25,12 @@
 #include "config.hpp"
 
 #include "crtp_base.hpp"                // abstract_base
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 
+//#include <concepts>
 #include <iosfwd>
+#include <type_traits>
 
 /// Base class for GUI input fields.
 ///
@@ -46,6 +49,10 @@ class LMI_SO datum_base : private 
lmi::abstract_base<datum_base>
   private:
     bool enabled_ {true};
 };
+static_assert(std::is_abstract_v<datum_base>);
+//static_assert(std::regular<datum_base>);
+static_assert(well_move_assignable<datum_base>);
+//static_assert(well_move_constructible<datum_base>);
 
 std::istream& operator>>(std::istream&, datum_base&);
 std::ostream& operator<<(std::ostream&, datum_base const&);
diff --git a/datum_boolean.hpp b/datum_boolean.hpp
index 1759f72e..154fc3e0 100644
--- a/datum_boolean.hpp
+++ b/datum_boolean.hpp
@@ -25,6 +25,9 @@
 #include "config.hpp"
 
 #include "datum_base.hpp"
+#include "smf.hpp"                      // well_move_*<>
+
+#include <concepts>
 
 class datum_boolean final
     :public datum_base
@@ -45,6 +48,9 @@ class datum_boolean final
 
     bool value_;
 };
+static_assert(std::semiregular<datum_boolean>);
+static_assert(well_move_assignable<datum_boolean>);
+static_assert(well_move_constructible<datum_boolean>);
 
 bool operator==(datum_boolean const&, datum_boolean const&);
 
diff --git a/datum_sequence.hpp b/datum_sequence.hpp
index e32bf26b..f3d3862f 100644
--- a/datum_sequence.hpp
+++ b/datum_sequence.hpp
@@ -25,11 +25,13 @@
 #include "config.hpp"
 
 #include "datum_string.hpp"
-
+#include "smf.hpp"                      // well_move_*<>
 #include "value_cast.hpp"
 
+//#include <concepts>
 #include <map>
 #include <string>
+#include <type_traits>
 
 /// Abstract base class for MVC input sequences.
 ///
@@ -72,6 +74,10 @@ class sequence_base
 
     void assert_sanity() const;
 };
+static_assert(std::is_abstract_v<datum_base>);
+//static_assert(std::regular<sequence_base>);
+static_assert(well_move_assignable<sequence_base>);
+//static_assert(well_move_constructible<sequence_base>);
 
 bool operator==(sequence_base const&, sequence_base const&);
 
diff --git a/datum_string.hpp b/datum_string.hpp
index 7985a580..ac0df9f3 100644
--- a/datum_string.hpp
+++ b/datum_string.hpp
@@ -25,10 +25,12 @@
 #include "config.hpp"
 
 #include "datum_base.hpp"
-
+#include "smf.hpp"                      // well_move_*<>
 #include "value_cast.hpp"
 
+#include <concepts>
 #include <string>
+#include <type_traits>
 
 class datum_string_base
     :public datum_base
@@ -48,6 +50,10 @@ class datum_string_base
   private:
     std::string value_;
 };
+static_assert(std::is_abstract_v<datum_string_base>);
+//static_assert(std::regular<datum_string_base>);
+static_assert(well_move_assignable<datum_string_base>);
+//static_assert(well_move_constructible<datum_string_base>);
 
 bool operator==(datum_string_base const&, datum_string_base const&);
 
@@ -63,6 +69,9 @@ class datum_string final
   private:
     void concrete_if_not_pure() override {}
 };
+static_assert(std::regular<datum_string>);
+static_assert(well_move_assignable<datum_string>);
+static_assert(well_move_constructible<datum_string>);
 
 bool operator==(datum_string const&, datum_string const&);
 
diff --git a/dbvalue.hpp b/dbvalue.hpp
index cfc03c69..cadf872e 100644
--- a/dbvalue.hpp
+++ b/dbvalue.hpp
@@ -25,9 +25,11 @@
 #include "config.hpp"
 
 #include "dbindex.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 #include "xml_lmi_fwd.hpp"
 
+#include <concepts>
 #include <iosfwd>
 #include <string>
 #include <vector>
@@ -104,6 +106,9 @@ class LMI_SO database_entity final
     // Glosses are deprecated.
     std::string         gloss_;
 };
+static_assert(std::regular<database_entity>);
+static_assert(well_move_assignable<database_entity>);
+static_assert(well_move_constructible<database_entity>);
 
 LMI_SO std::vector<int> const& maximum_database_dimensions();
 
diff --git a/fund_data.hpp b/fund_data.hpp
index 37198395..16fe3658 100644
--- a/fund_data.hpp
+++ b/fund_data.hpp
@@ -26,8 +26,10 @@
 
 #include "cache_file_reads.hpp"
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 
+#include <concepts>
 #include <string>
 #include <vector>
 
@@ -57,6 +59,10 @@ class LMI_SO FundInfo final
     std::string LongName_  {};
     std::string gloss_     {};
 };
+// Should this class be comparable?
+//static_assert(std::regular<FundInfo>);
+static_assert(well_move_assignable<FundInfo>);
+static_assert(well_move_constructible<FundInfo>);
 
 class LMI_SO FundData final
     :public cache_file_reads<FundData>
@@ -80,6 +86,11 @@ class LMI_SO FundData final
 
     std::vector<FundInfo> FundInfo_ {};
 };
+// Should this class be default-constructible, comparable,
+// copyable, or movable?
+//static_assert(std::regular<FundData>);
+//static_assert(well_move_assignable<FundData>);
+//static_assert(well_move_constructible<FundData>);
 
 inline double FundInfo::ScalarIMF() const
 {
diff --git a/gpt_server.hpp b/gpt_server.hpp
index 72c44018..2956955a 100644
--- a/gpt_server.hpp
+++ b/gpt_server.hpp
@@ -27,8 +27,11 @@
 #include "gpt_state.hpp"
 #include "mc_enum_type_enums.hpp"       // mcenum_emission
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 
+#include <concepts>
+
 class gpt_input;
 
 /// Guideline premium test server.
@@ -64,5 +67,9 @@ class LMI_SO gpt_server final
     double seconds_for_calculations_ {0.0};
     double seconds_for_output_       {0.0};
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<gpt_server>);
+static_assert(well_move_assignable<gpt_server>);
+static_assert(well_move_constructible<gpt_server>);
 
 #endif // gpt_server_hpp
diff --git a/illustrator.hpp b/illustrator.hpp
index 758e1a99..814458c8 100644
--- a/illustrator.hpp
+++ b/illustrator.hpp
@@ -26,8 +26,10 @@
 
 #include "mc_enum_type_enums.hpp"       // mcenum_emission
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 
+#include <concepts>
 #include <memory>                       // shared_ptr
 #include <vector>
 
@@ -60,6 +62,10 @@ class LMI_SO illustrator final
     double seconds_for_calculations_;
     double seconds_for_output_;
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<illustrator>);
+static_assert(well_move_assignable<illustrator>);
+static_assert(well_move_constructible<illustrator>);
 
 LMI_SO Input const& default_cell();
 
diff --git a/ledger.hpp b/ledger.hpp
index 66856941..9922c6ca 100644
--- a/ledger.hpp
+++ b/ledger.hpp
@@ -26,9 +26,11 @@
 
 #include "ledger_evaluator.hpp"
 #include "mc_enum_type_enums.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 #include "xml_lmi.hpp"
 
+#include <concepts>
 #include <iosfwd>
 #include <memory>                       // shared_ptr
 #include <string>
@@ -133,6 +135,10 @@ class LMI_SO Ledger final
     // from which we want to shield other classes where possible.
     std::vector<mcenum_run_basis> run_bases_;
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<Ledger>);
+static_assert(well_move_assignable<Ledger>);
+static_assert(well_move_constructible<Ledger>);
 
 std::vector<double> numeric_vector
     (Ledger const&      ledger
diff --git a/mec_server.hpp b/mec_server.hpp
index f2980b16..5d7bf52c 100644
--- a/mec_server.hpp
+++ b/mec_server.hpp
@@ -27,8 +27,11 @@
 #include "mc_enum_type_enums.hpp"       // mcenum_emission
 #include "mec_state.hpp"
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 
+#include <concepts>
+
 class mec_input;
 
 /// MEC-testing server.
@@ -64,5 +67,9 @@ class LMI_SO mec_server final
     double seconds_for_calculations_ {0.0};
     double seconds_for_output_       {0.0};
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<mec_server>);
+static_assert(well_move_assignable<mec_server>);
+static_assert(well_move_constructible<mec_server>);
 
 #endif // mec_server_hpp
diff --git a/product_data.hpp b/product_data.hpp
index 8dfc6869..91218cdb 100644
--- a/product_data.hpp
+++ b/product_data.hpp
@@ -27,9 +27,11 @@
 #include "any_member.hpp"
 #include "cache_file_reads.hpp"
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 #include "xml_serializable.hpp"
 
+#include <concepts>
 #include <string>
 
 /// A single product datum: a string with an optional gloss.
@@ -60,6 +62,9 @@ class glossed_string final
     std::string datum_ {};
     std::string gloss_ {};
 };
+static_assert(std::regular<glossed_string>);
+static_assert(well_move_assignable<glossed_string>);
+static_assert(well_move_constructible<glossed_string>);
 
 class product_data;
 
diff --git a/rounding_rules.hpp b/rounding_rules.hpp
index c92b48e8..aa80ed56 100644
--- a/rounding_rules.hpp
+++ b/rounding_rules.hpp
@@ -29,9 +29,11 @@
 #include "mc_enum.hpp"
 #include "mc_enum_types.hpp"
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 #include "xml_serializable.hpp"
 
+#include <concepts>
 #include <string>
 
 /// Parameters of a rounding rule.
@@ -63,6 +65,10 @@ class LMI_SO rounding_parameters final
     mce_rounding_style style_    {r_indeterminate};
     std::string        gloss_    {};
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<rounding_parameters>);
+static_assert(well_move_assignable<rounding_parameters>);
+static_assert(well_move_constructible<rounding_parameters>);
 
 /// Product rounding rules.
 ///
diff --git a/rtti_lmi.hpp b/rtti_lmi.hpp
index 046f5b0e..aba8d0d0 100644
--- a/rtti_lmi.hpp
+++ b/rtti_lmi.hpp
@@ -24,11 +24,14 @@
 
 #include "config.hpp"
 
+#include "smf.hpp"                      // well_move_*<>
+
 #if defined __GNUC__
 #   include <cstdlib>                   // free()
 #   include <cxxabi.h>
 #endif // defined __GNUC__
 
+#include <concepts>
 #include <ostream>
 #include <string>
 #include <type_traits>
@@ -135,6 +138,10 @@ class TypeInfo final
   private:
     std::type_info const* ti_;
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<TypeInfo>);
+static_assert(well_move_assignable<TypeInfo>);
+static_assert(well_move_constructible<TypeInfo>);
 
 inline std::ostream& operator<<(std::ostream& os, TypeInfo const& z)
 {
diff --git a/stratified_charges.hpp b/stratified_charges.hpp
index cdf27254..1c644c16 100644
--- a/stratified_charges.hpp
+++ b/stratified_charges.hpp
@@ -28,9 +28,11 @@
 #include "cache_file_reads.hpp"
 #include "mc_enum_type_enums.hpp"
 #include "path.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "so_attributes.hpp"
 #include "xml_serializable.hpp"
 
+#include <concepts>
 #include <string>
 #include <vector>
 
@@ -92,6 +94,9 @@ class LMI_SO stratified_entity final
     std::vector<double> values_ {};
     std::string         gloss_  {};
 };
+static_assert(std::regular<stratified_entity>);
+static_assert(well_move_assignable<stratified_entity>);
+static_assert(well_move_constructible<stratified_entity>);
 
 /// Rates that depend upon the amount they're multiplied by.
 
diff --git a/test_coding_rules.cpp b/test_coding_rules.cpp
index 8409704e..9d21e325 100644
--- a/test_coding_rules.cpp
+++ b/test_coding_rules.cpp
@@ -27,10 +27,12 @@
 #include "miscellany.hpp"               // begins_with(), split_into_lines()
 #include "path.hpp"
 #include "pcre_regex.hpp"
+#include "smf.hpp"                      // well_move_*<>
 #include "ssize_lmi.hpp"
 #include "unwind.hpp"                   // scoped_unwind_toggler
 
 #include <algorithm>                    // is_sorted()
+#include <concepts>
 #include <ctime>                        // time_t
 #include <iomanip>
 #include <ios>
@@ -1178,6 +1180,9 @@ class statistics
     int lines_   {0};
     int defects_ {0};
 };
+static_assert(std::semiregular<statistics>);
+static_assert(well_move_assignable<statistics>);
+static_assert(well_move_constructible<statistics>);
 
 statistics& statistics::operator+=(statistics const& z)
 {
diff --git a/tn_range.hpp b/tn_range.hpp
index 0605f887..7dc2e4e9 100644
--- a/tn_range.hpp
+++ b/tn_range.hpp
@@ -25,7 +25,9 @@
 #include "config.hpp"
 
 #include "datum_base.hpp"
+#include "smf.hpp"                      // well_move_*<>
 
+#include <concepts>
 #include <string>
 #include <type_traits>
 #include <typeinfo>
@@ -288,6 +290,10 @@ class tn_range final
     Number maximum_;
     Number value_;
 };
+// concepts cannot be templated
+//static_assert(std::regular<tn_range>);
+//static_assert(well_move_assignable<tn_range>);
+//static_assert(well_move_constructible<tn_range>);
 
 // Define these few equality operators inline.
 //
diff --git a/tn_range.tpp b/tn_range.tpp
index a16aab1b..3825d116 100644
--- a/tn_range.tpp
+++ b/tn_range.tpp
@@ -374,6 +374,13 @@ tn_range<Number,Trammel>::tn_range()
     ,value_   {trammel_.default_initializer()}
 {
     trammel_.assert_sanity();
+// These assertions could be
+//  - copied to the other ctors
+//  - factored out into a function that all ctors would call
+//  - moved to a dtor (which is presently undeclared)
+static_assert(std::regular<tn_range<Number,Trammel>>);
+static_assert(well_move_assignable<tn_range<Number,Trammel>>);
+static_assert(well_move_constructible<tn_range<Number,Trammel>>);
 }
 
 template<typename Number, typename Trammel>
diff --git a/yare_input.hpp b/yare_input.hpp
index b202f59d..dfd398a4 100644
--- a/yare_input.hpp
+++ b/yare_input.hpp
@@ -26,7 +26,9 @@
 
 #include "calendar_date.hpp"
 #include "mc_enum_type_enums.hpp"
+#include "smf.hpp"                      // well_move_*<>
 
+#include <concepts>
 #include <string>
 #include <vector>
 
@@ -247,6 +249,10 @@ class yare_input final
     std::vector<mcenum_pmt_strategy > PaymentStrategy                 ;
     std::vector<mcenum_pmt_strategy > CorporationPaymentStrategy      ;
 };
+// Should this class be default-constructible?
+//static_assert(std::regular<yare_input>);
+static_assert(well_move_assignable<yare_input>);
+static_assert(well_move_constructible<yare_input>);
 
 bool is_policy_rated(yare_input const&);
 



reply via email to

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