diff --git a/libgnucash/app-utils/gnc-option-impl.hpp b/libgnucash/app-utils/gnc-option-impl.hpp index 5aaf2e1785..373409be4e 100644 --- a/libgnucash/app-utils/gnc-option-impl.hpp +++ b/libgnucash/app-utils/gnc-option-impl.hpp @@ -237,6 +237,18 @@ QofInstance* qof_instance_from_string(const std::string& str, QofInstance* qof_instance_from_guid(GncGUID*, GncOptionUIType type); std::string qof_instance_to_string(const QofInstance* inst); +template +struct is_QofInstanceValue +{ + static constexpr bool value = + (std::is_same_v, GncOptionValue> || + std::is_same_v, + GncOptionValidatedValue>); +}; + +template inline constexpr bool +is_QofInstanceValue_v = is_QofInstanceValue::value; + /* These will work when m_value is a built-in class; GnuCash class and container * values will need specialization unless they happen to define operators << and * >>. @@ -246,16 +258,9 @@ std::string qof_instance_to_string(const QofInstance* inst); */ #ifndef SWIG template> && - ! (std::is_same_v, - GncOptionValue> || - std::is_same_v, - GncOptionValidatedValue> || - std::is_same_v, - GncOptionRangeValue> || - std::is_same_v, - GncOptionRangeValue>), int> = 0> + typename std::enable_if_t && + ! (is_QofInstanceValue_v || + is_RangeValue_v), int> = 0> std::ostream& operator<<(std::ostream& oss, const OptType& opt) { oss << opt.get_value(); @@ -271,10 +276,7 @@ operator<< >(std::ostream& oss, } template, - GncOptionValidatedValue> || - std::is_same_v, - GncOptionValue >, int> = 0> + typename std::enable_if_t, int> = 0> inline std::ostream& operator<< (std::ostream& oss, const OptType& opt) { @@ -296,16 +298,9 @@ operator<< (std::ostream& oss, const OptType& opt) } template> && - !(std::is_same_v, - GncOptionValue> || - std::is_same_v, - GncOptionValidatedValue> || - std::is_same_v, - GncOptionRangeValue> || - std::is_same_v, - GncOptionRangeValue>), int> = 0> + typename std::enable_if_t && + !(is_QofInstanceValue_v || + is_RangeValue_v), int> = 0> std::istream& operator>>(std::istream& iss, OptType& opt) { std::decay_t value; @@ -322,11 +317,7 @@ std::istream& operator>>(std::istream& iss, OptType& opt) } template, - GncOptionValidatedValue> || - std::is_same_v, - GncOptionValue >, - int> = 0> + typename std::enable_if_t, int> = 0> std::istream& operator>> (std::istream& iss, OptType& opt) { @@ -507,11 +498,7 @@ private: }; template, - GncOptionRangeValue> || - std::is_same_v, - GncOptionRangeValue>, - int> = 0> + typename std::enable_if_t, int> = 0> inline std::ostream& operator<< (std::ostream& oss, const OptType& opt) { @@ -522,11 +509,7 @@ operator<< (std::ostream& oss, const OptType& opt) } template, - GncOptionRangeValue> || - std::is_same_v, - GncOptionRangeValue>, - int> = 0> + typename std::enable_if_t, int> = 0> inline std::istream& operator>> (std::istream& iss, OptType& opt) { diff --git a/libgnucash/app-utils/gnc-option.cpp b/libgnucash/app-utils/gnc-option.cpp index f249ff06b7..b28a925791 100644 --- a/libgnucash/app-utils/gnc-option.cpp +++ b/libgnucash/app-utils/gnc-option.cpp @@ -34,8 +34,7 @@ extern "C" } template >, + typename std::enable_if_t, int>> GncOption::GncOption(const char* section, const char* name, const char* key, const char* doc_string, @@ -49,31 +48,30 @@ GncOption::GncOption(const char* section, const char* name, template ValueType GncOption::get_value() const { - return std::visit([](const auto option)->ValueType { - if constexpr (std::is_same_v, std::decay_t>) + return std::visit( + [](const auto option)->ValueType { + if constexpr (is_same_decayed_v) return option.get_value(); - if constexpr (std::is_same_v, - GncOptionDateValue> && - std::is_same_v, + if constexpr (is_same_decayed_v) + { + if constexpr (is_same_decayed_v) return option.get_period(); - if constexpr (std::is_same_v, - GncOptionDateValue> && - std::is_same_v, - size_t>) + if constexpr (std::is_same_v) return option.get_period_index(); - if constexpr - (std::is_same_v, - GncOptionMultichoiceValue> && - std::is_same_v, - size_t>) + return ValueType{}; + } + if constexpr (is_same_decayed_v) + { + if constexpr (std::is_same_v) return option.get_index(); - if constexpr - (std::is_same_v, - GncOptionMultichoiceValue> && - std::is_same_v, + if constexpr (is_same_decayed_v) return option.get_multiple(); + } return ValueType {}; }, *m_option); } @@ -81,23 +79,25 @@ GncOption::get_value() const template ValueType GncOption::get_default_value() const { - return std::visit([](const auto option)->ValueType { - if constexpr (std::is_same_v, std::decay_t>) + return std::visit( + [](const auto option)->ValueType { + if constexpr (is_same_decayed_v) return option.get_default_value(); - if constexpr (std::is_same_v, - GncOptionDateValue> && - std::is_same_v, + if constexpr (is_same_decayed_v) + { + if constexpr (is_same_decayed_v) return option.get_default_period(); - if constexpr (std::is_same_v, - GncOptionDateValue> && - std::is_same_v, - size_t>) + if constexpr (std::is_same_v) return option.get_default_period_index(); + return ValueType{}; + } if constexpr - (std::is_same_v, + (is_same_decayed_v && - std::is_same_v, + is_same_decayed_v) return option.get_default_multiple(); return ValueType {}; @@ -108,26 +108,24 @@ GncOption::get_default_value() const template void GncOption::set_value(ValueType value) { - std::visit([value](auto& option) { + std::visit( + [value](auto& option) { if constexpr - (std::is_same_v, - std::decay_t> || - (std::is_same_v, + (is_same_decayed_v || + (is_same_decayed_v && - (std::is_same_v, - RelativeDatePeriod> || - std::is_same_v, size_t>))) + (is_same_decayed_v || + std::is_same_v))) option.set_value(value); - if constexpr - (std::is_same_v, + if constexpr (is_same_decayed_v) { - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v) option.set_multiple(value); else if constexpr (std::is_same_v || - std::is_same_v, std::string> || + is_same_decayed_v || std::is_same_v, char*>) option.set_value(value); } @@ -137,27 +135,23 @@ GncOption::set_value(ValueType value) template void GncOption::set_default_value(ValueType value) { - std::visit([value](auto& option) { + std::visit( + [value](auto& option) { if constexpr - (std::is_same_v, - std::decay_t> || - (std::is_same_v, - GncOptionDateValue> && - (std::is_same_v, - RelativeDatePeriod> || - std::is_same_v, size_t>))) + (is_same_decayed_v|| + (is_same_decayed_v && + (is_same_decayed_v || + std::is_same_v))) option.set_default_value(value); - if constexpr - (std::is_same_v, + if constexpr (is_same_decayed_v) { - if constexpr - (std::is_same_v, + if constexpr (is_same_decayed_v) - option.set_multiple(value); + option.set_default_multiple(value); else if constexpr (std::is_same_v || - std::is_same_v, std::string> || + is_same_decayed_v || std::is_same_v, char*>) option.set_default_value(value); } @@ -174,7 +168,7 @@ GncOption::get_limits(ValueType& max, ValueType& min, ValueType& step) const noe { std::visit([&max, &min, &step](const auto& option) { if constexpr - (std::is_same_v, + (is_same_decayed_v>) option.get_limits(max, min, step); }, *m_option); @@ -292,8 +286,9 @@ GncOption::is_changed() const noexcept bool GncOption::is_multiselect() const noexcept { - return std::visit([](const auto& option)->bool { - if constexpr (std::is_same_v, + return std::visit( + [](const auto& option)->bool { + if constexpr (is_same_decayed_v) return option.is_multiselect(); else @@ -304,16 +299,17 @@ GncOption::is_multiselect() const noexcept template bool GncOption::validate(ValueType value) const { - return std::visit([value] (const auto& option) -> bool { - if constexpr ((std::is_same_v, + return std::visit( + [value] (const auto& option) -> bool { + if constexpr ((is_same_decayed_v && - std::is_same_v, + is_same_decayed_v) || - (std::is_same_v, + (is_same_decayed_v && - std::is_same_v, + is_same_decayed_v) || - std::is_same_v, + is_same_decayed_v>) return option.validate(value); else @@ -324,10 +320,11 @@ GncOption::validate(ValueType value) const std::size_t GncOption::num_permissible_values() const { - return std::visit([] (const auto& option) -> size_t { - if constexpr (std::is_same_v, + return std::visit( + [] (const auto& option) -> size_t { + if constexpr (is_same_decayed_v || - std::is_same_v, + is_same_decayed_v) return option.num_permissible_values(); else @@ -338,10 +335,11 @@ GncOption::num_permissible_values() const std::size_t GncOption::permissible_value_index(const char* value) const { - return std::visit([&value] (const auto& option) -> size_t { - if constexpr (std::is_same_v, + return std::visit( + [&value] (const auto& option) -> size_t { + if constexpr (is_same_decayed_v || - std::is_same_v, + is_same_decayed_v) return option.permissible_value_index(value); else @@ -393,10 +391,7 @@ bool GncOption::is_alternate() const noexcept { return std::visit([](auto& option) -> bool { - if constexpr(std::is_same_v, - GncOptionRangeValue> || - std::is_same_v, - GncOptionRangeValue>) + if constexpr(is_RangeValue_v) return option.is_alternate(); return false; }, *m_option); @@ -406,10 +401,7 @@ void GncOption::set_alternate(bool alt) noexcept { std::visit([alt](auto& option) { - if constexpr(std::is_same_v, - GncOptionRangeValue> || - std::is_same_v, - GncOptionRangeValue>) + if constexpr(is_RangeValue_v) option.set_alternate(alt); }, *m_option); } diff --git a/libgnucash/app-utils/gnc-option.hpp b/libgnucash/app-utils/gnc-option.hpp index 414d7e39f9..e873b0d70d 100644 --- a/libgnucash/app-utils/gnc-option.hpp +++ b/libgnucash/app-utils/gnc-option.hpp @@ -53,6 +53,38 @@ template class GncOptionRangeValue; template class GncOptionValidatedValue; class GncOptionDateValue; +template +struct is_OptionClassifier +{ + static constexpr bool value = + std::is_base_of_v>; +}; + +template inline constexpr bool +is_OptionClassifier_v = is_OptionClassifier::value; + +template +struct is_same_decayed +{ + static constexpr bool value = std::is_same_v, + std::decay_t>; +}; + +template inline constexpr bool +is_same_decayed_v = is_same_decayed::value; + +template +struct is_RangeValue +{ + static constexpr bool value = + (is_same_decayed_v> || + is_same_decayed_v>); +}; + +template inline constexpr bool +is_RangeValue_v = is_RangeValue::value; + + using GncOptionVariant = std::variant, GncOptionValue, GncOptionValue, @@ -82,14 +114,13 @@ class GncOption { public: template >, + typename std::enable_if_t, int> = 0> + GncOption(OptionType option) : m_option{std::make_unique(option)} {} template >, + typename std::enable_if_t, int> = 0> GncOption(const char* section, const char* name, const char* key, const char* doc_string, diff --git a/libgnucash/app-utils/gnc-optiondb.i b/libgnucash/app-utils/gnc-optiondb.i index d53cc02421..09595b1b29 100644 --- a/libgnucash/app-utils/gnc-optiondb.i +++ b/libgnucash/app-utils/gnc-optiondb.i @@ -263,7 +263,7 @@ scm_color_list_to_string(SCM list) template inline ValueType scm_to_value(SCM new_value) { - if constexpr (std::is_same_v, SCM>) + if constexpr (is_same_decayed_v) return new_value; return ValueType{}; } @@ -816,7 +816,26 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); return scm_cons(desig, scm_from_int(val)); } - %} +template +struct is_MultichoiceOrRange +{ + static constexpr bool value = + is_same_decayed_v || + is_same_decayed_v>; +}; + +template +inline constexpr bool is_MultichoiceOrRange_v = is_MultichoiceOrRange::value; + +template +inline SCM return_scm_value(ValueType value) +{ + if constexpr (is_same_decayed_v) + return value; + return scm_from_value(static_cast(value)); +} + +%} %ignore GncOptionDBCallback; %include "gnc-option-date.hpp" @@ -840,16 +859,10 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); if (!$self) return SCM_BOOL_F; return std::visit([](const auto& option)->SCM { - if constexpr (std::is_same_v, - GncOptionMultichoiceValue> || - std::is_same_v, - GncOptionRangeValue>) + if constexpr (is_MultichoiceOrRange_v) return get_scm_value(option); auto value{option.get_value()}; - if constexpr (std::is_same_v, - SCM>) - return value; - return scm_from_value(static_cast(value)); + return return_scm_value(value); }, swig_get_option($self)); } SCM get_scm_default_value() @@ -857,25 +870,20 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); if (!$self) return SCM_BOOL_F; return std::visit([](const auto& option)->SCM { - if constexpr (std::is_same_v, - GncOptionMultichoiceValue> || - std::is_same_v, - GncOptionRangeValue>) + if constexpr (is_MultichoiceOrRange_v) return get_scm_default_value(option); auto value{option.get_default_value()}; - if constexpr (std::is_same_v, - SCM>) - return value; - return scm_from_value(static_cast(value)); + return return_scm_value(value); }, swig_get_option($self)); } + void set_value_from_scm(SCM new_value) { if (!$self) return; try { std::visit([new_value](auto& option) { - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v) { if (scm_date_absolute(new_value)) @@ -885,14 +893,14 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); return; } - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v) { option.set_multiple(scm_to_multichoices(new_value, option)); return; } - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v>) { if (scm_is_pair(new_value)) @@ -901,10 +909,7 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); option.set_value(scm_to_int(new_value)); return; } - if constexpr (std::is_same_v, - GncOptionValue> || - std::is_same_v, - GncOptionValidatedValue>) + if constexpr (is_QofInstanceValue_v) { if (scm_is_string(new_value)) { @@ -937,7 +942,7 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); return; try { std::visit([new_value](auto& option) { - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v) { if (scm_date_absolute(new_value)) @@ -946,14 +951,14 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); option.set_default_value(scm_relative_date_get_period(new_value)); return; } - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v) { option.set_default_multiple(scm_to_multichoices(new_value, option)); return; } - if constexpr (std::is_same_v, + if constexpr (is_same_decayed_v>) { if (scm_is_pair(new_value)) @@ -962,10 +967,7 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); option.set_default_value(scm_to_int(new_value)); return; } - if constexpr (std::is_same_v, - GncOptionValue> || - std::is_same_v, - GncOptionValidatedValue>) + if constexpr (is_QofInstanceValue_v) { if (scm_is_string(new_value)) { @@ -996,11 +998,11 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); if (!self) return SCM_BOOL_F; return std::visit([](const auto& option)->SCM { - if constexpr (std::is_same_v, - GncOptionMultichoiceValue>) + if constexpr (is_same_decayed_v) return scm_c_eval_string("'multichoice"); else if constexpr (std::is_same_v) + bool>) return scm_c_eval_string("'boolean"); else return SCM_BOOL_F;