diff --git a/include/cantera/base/AnyMap.h b/include/cantera/base/AnyMap.h index 5e954733e..59dc7eb8f 100644 --- a/include/cantera/base/AnyMap.h +++ b/include/cantera/base/AnyMap.h @@ -7,13 +7,16 @@ #include "cantera/base/global.h" #include "cantera/base/ctexceptions.h" -#include -#include - #include #include +#include #include +namespace boost +{ +class any; +} + namespace Cantera { @@ -32,6 +35,13 @@ class AnyMap; class AnyValue { public: + AnyValue(); + ~AnyValue(); + AnyValue(AnyValue const& other); + AnyValue(AnyValue&& other); + AnyValue& operator=(AnyValue const& other); + AnyValue& operator=(AnyValue&& other); + AnyValue& operator[](const std::string& key); bool hasKey(const std::string& key) const; @@ -88,7 +98,7 @@ private: std::string demangle(const std::type_info& type) const; std::string m_key; - boost::any m_value; + std::unique_ptr m_value; static std::map s_typenames; }; diff --git a/include/cantera/base/AnyMap.inl.h b/include/cantera/base/AnyMap.inl.h index cba011009..7b59b4b12 100644 --- a/include/cantera/base/AnyMap.inl.h +++ b/include/cantera/base/AnyMap.inl.h @@ -16,15 +16,15 @@ namespace Cantera template const T &AnyValue::as() const { try { - return boost::any_cast(m_value); + return boost::any_cast(*m_value); } catch (boost::bad_any_cast&) { - if (m_value.type() == typeid(void)) { + if (m_value->type() == typeid(void)) { // Values that have not been set are of type 'void' throw CanteraError("AnyValue::as", "Key '{}' not found", m_key); } else { throw CanteraError("AnyValue::as", "Key '{}' contains a '{}',\nnot a '{}'.", - m_key, demangle(m_value.type()), demangle(typeid(T))); + m_key, demangle(m_value->type()), demangle(typeid(T))); } } } @@ -32,27 +32,27 @@ const T &AnyValue::as() const { template T &AnyValue::as() { try { - return boost::any_cast(m_value); + return boost::any_cast(*m_value); } catch (boost::bad_any_cast&) { - if (m_value.type() == typeid(void)) { + if (m_value->type() == typeid(void)) { // Values that have not been set are of type 'void' throw CanteraError("AnyValue::as", "Key '{}' not found", m_key); } else { throw CanteraError("AnyValue::as", "Key '{}' contains a '{}',\nnot a '{}'.", - m_key, demangle(m_value.type()), demangle(typeid(T))); + m_key, demangle(m_value->type()), demangle(typeid(T))); } } } template bool AnyValue::is() const { - return m_value.type() == typeid(T); + return m_value->type() == typeid(T); } template AnyValue &AnyValue::operator=(const std::vector &value) { - m_value = value; + *m_value = value; return *this; } @@ -68,7 +68,7 @@ std::vector &AnyValue::asVector() { template AnyValue& AnyValue::operator=(const std::unordered_map items) { - m_value = AnyMap(); + *m_value = AnyMap(); AnyMap& dest = as(); for (const auto& item : items) { dest[item.first] = item.second; @@ -78,7 +78,7 @@ AnyValue& AnyValue::operator=(const std::unordered_map items) { template AnyValue& AnyValue::operator=(const std::map items) { - m_value = AnyMap(); + *m_value = AnyMap(); AnyMap& dest = as(); for (const auto& item : items) { dest[item.first] = item.second; @@ -91,14 +91,14 @@ inline AnyMap& AnyValue::as() { try { // This is where nested AnyMaps are created when the syntax // m[key1][key2] is used. - if (m_value.type() == typeid(void)) { - m_value = AnyMap(); + if (m_value->type() == typeid(void)) { + *m_value = AnyMap(); } - return boost::any_cast(m_value); + return boost::any_cast(*m_value); } catch (boost::bad_any_cast&) { throw CanteraError("AnyValue::as", "value of key '{}' is a '{}',\nnot an 'AnyMap'.", - m_key, demangle(m_value.type())); + m_key, demangle(m_value->type())); } } @@ -108,7 +108,7 @@ std::map AnyValue::asMap() std::map dest; for (const auto& item : as().m_data) { try { - dest[item.first] = boost::any_cast(item.second.m_value); + dest[item.first] = boost::any_cast(*item.second.m_value); } catch (boost::bad_any_cast&) { throw CanteraError("AnyValue::asMap", "Value of key '{}' is not a '{}'", diff --git a/src/base/AnyMap.cpp b/src/base/AnyMap.cpp index 2e118c793..2917e00a9 100644 --- a/src/base/AnyMap.cpp +++ b/src/base/AnyMap.cpp @@ -17,6 +17,37 @@ std::map AnyValue::s_typenames = { // Methods of class AnyValue +AnyValue::AnyValue() + : m_key() + , m_value(new boost::any{}) +{} + +AnyValue::~AnyValue() = default; + +AnyValue::AnyValue(AnyValue const& other): m_key(other.m_key), + m_value(new boost::any{*other.m_value}) { +} + +AnyValue::AnyValue(AnyValue&& other): m_key(std::move(other.m_key)), + m_value(std::move(other.m_value)) { +} + +AnyValue& AnyValue::operator=(AnyValue const& other) { + if (this == &other) + return *this; + m_key = other.m_key; + m_value.reset(new boost::any{*other.m_value}); + return *this; +} + +AnyValue& AnyValue::operator=(AnyValue&& other) { + if (this == &other) + return *this; + m_key = std::move(other.m_key); + m_value = std::move(other.m_value); + return *this; +} + AnyValue& AnyValue::operator[](const std::string& key) { return as()[key]; @@ -29,16 +60,16 @@ bool AnyValue::hasKey(const std::string& key) const { void AnyValue::setKey(const std::string &key) { m_key = key; } const std::type_info &AnyValue::type() { - return m_value.type(); + return m_value->type(); } AnyValue &AnyValue::operator=(const std::string &value) { - m_value = value; + *m_value = value; return *this; } AnyValue &AnyValue::operator=(const char *value) { - m_value = std::string(value); + *m_value = std::string(value); return *this; } @@ -47,7 +78,7 @@ const std::string &AnyValue::asString() const { } AnyValue &AnyValue::operator=(double value) { - m_value = value; + *m_value = value; return *this; } @@ -56,7 +87,7 @@ double AnyValue::asDouble() const { } AnyValue &AnyValue::operator=(bool value) { - m_value = value; + *m_value = value; return *this; } @@ -65,12 +96,12 @@ bool AnyValue::asBool() const { } AnyValue &AnyValue::operator=(long int value) { - m_value = value; + *m_value = value; return *this; } AnyValue &AnyValue::operator=(int value) { - m_value = static_cast(value); + *m_value = static_cast(value); return *this; } @@ -78,12 +109,12 @@ long int AnyValue::asInt() const { return as(); } AnyValue& AnyValue::operator=(const AnyMap& value) { - m_value = value; + *m_value = value; return *this; } AnyValue& AnyValue::operator=(AnyMap&& value) { - m_value = std::move(value); + *m_value = std::move(value); return *this; }