mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Wrap GncOptionValue/GncOptionValidatedValue in Boost::Variant.
To provide a single type for containers.
This commit is contained in:
parent
c0ba3e2706
commit
b6fd844774
@ -51,16 +51,18 @@ scm_from_value<QofInstance*>(QofInstance* value)
|
|||||||
return scm_guid;
|
return scm_guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<std::string>>
|
GncOption
|
||||||
gnc_make_string_option(const char* section, const char* name,
|
gnc_make_string_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
std::string value)
|
std::string value)
|
||||||
{
|
{
|
||||||
return std::make_shared<GncOptionValue<std::string>>(
|
GncOptionValue<std::string> retval {
|
||||||
section, name, key, doc_string, value);
|
section, name, key, doc_string, value
|
||||||
|
};
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<std::string>>
|
GncOption
|
||||||
gnc_make_text_option(const char* section, const char* name,
|
gnc_make_text_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
std::string value)
|
std::string value)
|
||||||
@ -68,36 +70,41 @@ gnc_make_text_option(const char* section, const char* name,
|
|||||||
return gnc_make_string_option(section, name, key, doc_string, value);
|
return gnc_make_string_option(section, name, key, doc_string, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<QofInstance*>>
|
GncOption
|
||||||
gnc_make_budget_option(const char* section, const char* name,
|
gnc_make_budget_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
GncBudget *value)
|
GncBudget *value)
|
||||||
{
|
{
|
||||||
return std::make_shared<GncOptionValue<QofInstance*>>(
|
GncOptionValue<QofInstance*> retval {
|
||||||
section, name, key, doc_string, QOF_INSTANCE(value));
|
section, name, key, doc_string, QOF_INSTANCE(value)
|
||||||
|
};
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<QofInstance*>>
|
GncOption
|
||||||
gnc_make_commodity_option(const char* section, const char* name,
|
gnc_make_commodity_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
gnc_commodity *value)
|
gnc_commodity *value)
|
||||||
{
|
{
|
||||||
return std::make_shared<GncOptionValue<QofInstance*>>(
|
GncOptionValue<QofInstance*> retval {
|
||||||
section, name, key, doc_string, QOF_INSTANCE(value));
|
section, name, key, doc_string, QOF_INSTANCE(value)
|
||||||
|
};
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValidatedValue<QofInstance*>>
|
GncOption
|
||||||
gnc_make_currency_option(const char* section, const char* name,
|
gnc_make_currency_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
gnc_commodity *value)
|
gnc_commodity *value)
|
||||||
{
|
{
|
||||||
return std::make_shared<GncOptionValidatedValue<QofInstance*>>(
|
GncOptionValidatedValue<QofInstance*> retval {
|
||||||
section, name, key, doc_string, QOF_INSTANCE(value),
|
section, name, key, doc_string, QOF_INSTANCE(value),
|
||||||
[](QofInstance* new_value) -> bool
|
[](QofInstance* new_value) -> bool
|
||||||
{
|
{
|
||||||
return GNC_IS_COMMODITY (new_value) &&
|
return GNC_IS_COMMODITY (new_value) &&
|
||||||
gnc_commodity_is_currency(GNC_COMMODITY(new_value));
|
gnc_commodity_is_currency(GNC_COMMODITY(new_value));
|
||||||
}
|
}
|
||||||
);
|
};
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ extern "C"
|
|||||||
}
|
}
|
||||||
#include <libguile.h>
|
#include <libguile.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unused base class to document the structure of the current Scheme option
|
* Unused base class to document the structure of the current Scheme option
|
||||||
@ -97,7 +98,7 @@ SCM scm_from_value(ValueType);
|
|||||||
* for a detailed explanation.
|
* for a detailed explanation.
|
||||||
*/
|
*/
|
||||||
template <typename ValueType, class ValueClass>
|
template <typename ValueType, class ValueClass>
|
||||||
class GncOption
|
class GncOptionBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ValueType get_value() const
|
ValueType get_value() const
|
||||||
@ -112,12 +113,12 @@ public:
|
|||||||
{
|
{
|
||||||
return static_cast<ValueClass const&>(*this).get_default_value();
|
return static_cast<ValueClass const&>(*this).get_default_value();
|
||||||
}
|
}
|
||||||
SCM get_scm_value()
|
SCM get_scm_value() const
|
||||||
{
|
{
|
||||||
ValueType value{static_cast<ValueClass const&>(*this).get_value()};
|
ValueType value{static_cast<ValueClass const&>(*this).get_value()};
|
||||||
return scm_from_value<ValueType>(value);
|
return scm_from_value<ValueType>(value);
|
||||||
}
|
}
|
||||||
SCM get_scm_default_value()
|
SCM get_scm_default_value() const
|
||||||
{
|
{
|
||||||
ValueType value{static_cast<ValueClass const&>(*this).get_default_value()};
|
ValueType value{static_cast<ValueClass const&>(*this).get_default_value()};
|
||||||
return scm_from_value<ValueType>(value);
|
return scm_from_value<ValueType>(value);
|
||||||
@ -127,7 +128,7 @@ public:
|
|||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
class GncOptionValue :
|
class GncOptionValue :
|
||||||
public OptionClassifier,
|
public OptionClassifier,
|
||||||
public GncOption<ValueType, GncOptionValue<ValueType>>
|
public GncOptionBase<ValueType, GncOptionValue<ValueType>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GncOptionValue<ValueType>(const char* section, const char* name,
|
GncOptionValue<ValueType>(const char* section, const char* name,
|
||||||
@ -146,7 +147,7 @@ protected:
|
|||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
class GncOptionValidatedValue :
|
class GncOptionValidatedValue :
|
||||||
public OptionClassifier,
|
public OptionClassifier,
|
||||||
public GncOption<ValueType, GncOptionValidatedValue<ValueType>>
|
public GncOptionBase<ValueType, GncOptionValidatedValue<ValueType>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GncOptionValidatedValue<ValueType>(const char* section, const char* name,
|
GncOptionValidatedValue<ValueType>(const char* section, const char* name,
|
||||||
@ -187,29 +188,122 @@ private:
|
|||||||
ValueType m_validation_data;
|
ValueType m_validation_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<std::string>>
|
using GncOptionVariant = boost::variant<GncOptionValue<std::string>,
|
||||||
|
GncOptionValue<bool>,
|
||||||
|
GncOptionValue<int64_t>,
|
||||||
|
GncOptionValue<QofInstance*>,
|
||||||
|
GncOptionValidatedValue<QofInstance*>>;
|
||||||
|
class GncOption
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename OptionType>
|
||||||
|
GncOption(OptionType option) : m_option{option} {}
|
||||||
|
template <typename ValueType> ValueType get_value() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(GetValueVisitor<ValueType>(), m_option);
|
||||||
|
}
|
||||||
|
template <typename ValueType> ValueType get_default_value() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(GetDefaultValueVisitor<ValueType>(), m_option);
|
||||||
|
}
|
||||||
|
SCM get_scm_value() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(GetSCMVisitor(), m_option);
|
||||||
|
}
|
||||||
|
SCM get_scm_default_value() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(GetSCMDefaultVisitor(), m_option);
|
||||||
|
}
|
||||||
|
template <typename ValueType> void set_value(ValueType value)
|
||||||
|
{
|
||||||
|
boost::apply_visitor(SetValueVisitor<ValueType>(value), m_option);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
template <typename ValueType>
|
||||||
|
struct GetValueVisitor : public boost::static_visitor<ValueType>
|
||||||
|
{
|
||||||
|
ValueType operator()(const GncOptionValue<ValueType>& option) const {
|
||||||
|
return option.get_value();
|
||||||
|
}
|
||||||
|
ValueType operator()(const GncOptionValidatedValue<ValueType>& option) const {
|
||||||
|
return option.get_value();
|
||||||
|
}
|
||||||
|
template <class OptionType>
|
||||||
|
ValueType operator()(OptionType& option) const {
|
||||||
|
return ValueType{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename ValueType>
|
||||||
|
struct GetDefaultValueVisitor : public boost::static_visitor<ValueType>
|
||||||
|
{
|
||||||
|
ValueType operator()(const GncOptionValue<ValueType>& option) const {
|
||||||
|
return option.get_default_value();
|
||||||
|
}
|
||||||
|
ValueType operator()(const GncOptionValidatedValue<ValueType>& option) const {
|
||||||
|
return option.get_default_value();
|
||||||
|
}
|
||||||
|
template <class OptionType>
|
||||||
|
ValueType operator()(OptionType& option) const {
|
||||||
|
return ValueType();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename ValueType>
|
||||||
|
struct SetValueVisitor : public boost::static_visitor<>
|
||||||
|
{
|
||||||
|
SetValueVisitor(ValueType value) : m_value{value} {}
|
||||||
|
void operator()(GncOptionValue<ValueType>& option) const {
|
||||||
|
option.set_value(m_value);
|
||||||
|
}
|
||||||
|
void operator()(GncOptionValidatedValue<ValueType>& option) const {
|
||||||
|
option.set_value(m_value);
|
||||||
|
}
|
||||||
|
template <class OptionType>
|
||||||
|
void operator()(OptionType& option) const {
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ValueType m_value;
|
||||||
|
};
|
||||||
|
struct GetSCMVisitor : public boost::static_visitor<SCM>
|
||||||
|
{
|
||||||
|
template <class OptionType>
|
||||||
|
SCM operator()(OptionType& option) const {
|
||||||
|
return option.get_scm_value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct GetSCMDefaultVisitor : public boost::static_visitor<SCM>
|
||||||
|
{
|
||||||
|
template <class OptionType>
|
||||||
|
SCM operator()(OptionType& option) const {
|
||||||
|
return option.get_scm_default_value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GncOptionVariant m_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
GncOption
|
||||||
gnc_make_string_option(const char* section, const char* name,
|
gnc_make_string_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
std::string value);
|
std::string value);
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<std::string>>
|
GncOption
|
||||||
gnc_make_text_option(const char* section, const char* name,
|
gnc_make_text_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
std::string value);
|
std::string value);
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<QofInstance*>>
|
GncOption
|
||||||
gnc_make_budget_option(const char* section, const char* name,
|
gnc_make_budget_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
GncBudget* value);
|
GncBudget* value);
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValue<QofInstance*>>
|
GncOption
|
||||||
gnc_make_commodity_option(const char* section, const char* name,
|
gnc_make_commodity_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
gnc_commodity* value);
|
gnc_commodity* value);
|
||||||
|
|
||||||
std::shared_ptr<GncOptionValidatedValue<QofInstance*>>
|
GncOption
|
||||||
gnc_make_currency_option(const char* section, const char* name,
|
gnc_make_currency_option(const char* section, const char* name,
|
||||||
const char* key, const char* doc_string,
|
const char* key, const char* doc_string,
|
||||||
gnc_commodity* value);
|
gnc_commodity* value);
|
||||||
|
|
||||||
|
|
||||||
#endif //GNC_OPTION_HPP_
|
#endif //GNC_OPTION_HPP_
|
||||||
|
@ -46,18 +46,18 @@ TEST(GncOption, test_string_default_value)
|
|||||||
{
|
{
|
||||||
auto option = gnc_make_string_option("foo", "bar", "baz", "Phony Option",
|
auto option = gnc_make_string_option("foo", "bar", "baz", "Phony Option",
|
||||||
std::string{"waldo"});
|
std::string{"waldo"});
|
||||||
EXPECT_STREQ("waldo", option->get_default_value().c_str());
|
EXPECT_STREQ("waldo", option.get_default_value<std::string>().c_str());
|
||||||
EXPECT_STREQ("waldo", option->get_value().c_str());
|
EXPECT_STREQ("waldo", option.get_value<std::string>().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GncOption, test_string_value)
|
TEST(GncOption, test_string_value)
|
||||||
{
|
{
|
||||||
auto option = gnc_make_string_option("foo", "bar", "baz", "Phony Option",
|
auto option = gnc_make_string_option("foo", "bar", "baz", "Phony Option",
|
||||||
std::string{"waldo"});
|
std::string{"waldo"});
|
||||||
option->set_value("pepper");
|
option.set_value(std::string{"pepper"});
|
||||||
EXPECT_STREQ("waldo", option->get_default_value().c_str());
|
EXPECT_STREQ("waldo", option.get_default_value<std::string>().c_str());
|
||||||
EXPECT_NO_THROW({
|
EXPECT_NO_THROW({
|
||||||
EXPECT_STREQ("pepper", option->get_value().c_str());
|
EXPECT_STREQ("pepper", option.get_value<std::string>().c_str());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,11 +65,11 @@ TEST(GncOption, test_string_scm_functions)
|
|||||||
{
|
{
|
||||||
auto option = gnc_make_string_option("foo", "bar", "baz", "Phony Option",
|
auto option = gnc_make_string_option("foo", "bar", "baz", "Phony Option",
|
||||||
std::string{"waldo"});
|
std::string{"waldo"});
|
||||||
auto scm_value = option->get_scm_value();
|
auto scm_value = option.get_scm_value();
|
||||||
auto str_value = scm_to_utf8_string(scm_value);
|
auto str_value = scm_to_utf8_string(scm_value);
|
||||||
EXPECT_STREQ("waldo", str_value);
|
EXPECT_STREQ("waldo", str_value);
|
||||||
g_free(str_value);
|
g_free(str_value);
|
||||||
scm_value = option->get_scm_default_value();
|
scm_value = option.get_scm_default_value();
|
||||||
str_value = scm_to_utf8_string(scm_value);
|
str_value = scm_to_utf8_string(scm_value);
|
||||||
EXPECT_STREQ("waldo", str_value);
|
EXPECT_STREQ("waldo", str_value);
|
||||||
g_free(str_value);
|
g_free(str_value);
|
||||||
@ -93,7 +93,7 @@ TEST(GNCOption, test_budget_scm_functions)
|
|||||||
auto budget = gnc_budget_new(book);
|
auto budget = gnc_budget_new(book);
|
||||||
auto option = gnc_make_budget_option("foo", "bar", "baz",
|
auto option = gnc_make_budget_option("foo", "bar", "baz",
|
||||||
"Phony Option", budget);
|
"Phony Option", budget);
|
||||||
auto scm_budget = option->get_scm_value();
|
auto scm_budget = option.get_scm_value();
|
||||||
auto str_value = scm_to_utf8_string(scm_budget);
|
auto str_value = scm_to_utf8_string(scm_budget);
|
||||||
auto guid = guid_to_string(qof_instance_get_guid(budget));
|
auto guid = guid_to_string(qof_instance_get_guid(budget));
|
||||||
EXPECT_STREQ(guid, str_value);
|
EXPECT_STREQ(guid, str_value);
|
||||||
@ -158,13 +158,13 @@ TEST(GNCOption, test_currency_setter)
|
|||||||
auto usd = gnc_commodity_new(book, "United States Dollar",
|
auto usd = gnc_commodity_new(book, "United States Dollar",
|
||||||
"CURRENCY", "USD", NULL, 100);
|
"CURRENCY", "USD", NULL, 100);
|
||||||
EXPECT_NO_THROW({
|
EXPECT_NO_THROW({
|
||||||
option->set_value(QOF_INSTANCE(usd));
|
option.set_value(QOF_INSTANCE(usd));
|
||||||
});
|
});
|
||||||
EXPECT_PRED2(gnc_commodity_equal, usd, GNC_COMMODITY(option->get_value()));
|
EXPECT_PRED2(gnc_commodity_equal, usd, GNC_COMMODITY(option.get_value<QofInstance*>()));
|
||||||
EXPECT_THROW({
|
EXPECT_THROW({
|
||||||
option->set_value(QOF_INSTANCE(hpe));
|
option.set_value(QOF_INSTANCE(hpe));
|
||||||
}, std::invalid_argument);
|
}, std::invalid_argument);
|
||||||
EXPECT_PRED2(gnc_commodity_equal, usd, GNC_COMMODITY(option->get_value()));
|
EXPECT_PRED2(gnc_commodity_equal, usd, GNC_COMMODITY(option.get_value<QofInstance*>()));
|
||||||
gnc_commodity_destroy(hpe);
|
gnc_commodity_destroy(hpe);
|
||||||
gnc_commodity_destroy(usd);
|
gnc_commodity_destroy(usd);
|
||||||
gnc_commodity_destroy(eur);
|
gnc_commodity_destroy(eur);
|
||||||
|
Loading…
Reference in New Issue
Block a user