From f8d183220c42e084bd2b5a26fb7c613aadaed462 Mon Sep 17 00:00:00 2001 From: Evan McCorkle Date: Sun, 22 Oct 2017 13:25:57 -0400 Subject: [PATCH] Move AnyValue template definitions to inl file --- include/cantera/base/AnyMap.h | 153 ++++-------------------------- include/cantera/base/AnyMap.inl.h | 122 ++++++++++++++++++++++++ src/base/AnyMap.cpp | 52 +++++++++- 3 files changed, 192 insertions(+), 135 deletions(-) create mode 100644 include/cantera/base/AnyMap.inl.h diff --git a/include/cantera/base/AnyMap.h b/include/cantera/base/AnyMap.h index 2357e0b98..5e954733e 100644 --- a/include/cantera/base/AnyMap.h +++ b/include/cantera/base/AnyMap.h @@ -38,102 +38,39 @@ public: // The value knows the name of its corresponding key in order to provide // comprehensible error messages. - void setKey(const std::string& key) { m_key = key; }; + void setKey(const std::string& key); template - const T& as() const { - try { - return boost::any_cast(m_value); - } catch (boost::bad_any_cast&) { - 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))); - } - } - } + const T& as() const; template - T& as() { - try { - return boost::any_cast(m_value); - } catch (boost::bad_any_cast&) { - 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))); - } - } - } + T& as(); - const std::type_info& type() { - return m_value.type(); - } + const std::type_info& type(); template - bool is() const { - return m_value.type() == typeid(T); - } + bool is() const; - AnyValue& operator=(const std::string& value) { - m_value = value; - return *this; - } - AnyValue& operator=(const char* value) { - m_value = std::string(value); - return *this; - } - const std::string& asString() const { - return as(); - } + AnyValue& operator=(const std::string& value); + AnyValue& operator=(const char* value); + const std::string& asString() const; - AnyValue& operator=(double value) { - m_value = value; - return *this; - } - double asDouble() const { - return as(); - } + AnyValue& operator=(double value); + double asDouble() const; - AnyValue& operator=(bool value) { - m_value = value; - return *this; - } - bool asBool() const { - return as(); - } + AnyValue& operator=(bool value); + bool asBool() const; - AnyValue& operator=(long int value) { - m_value = value; - return *this; - } - AnyValue& operator=(int value) { - m_value = static_cast(value); - return *this; - } - long int asInt() const { - return as(); - } + AnyValue& operator=(long int value); + AnyValue& operator=(int value); + long int asInt() const; template - AnyValue& operator=(const std::vector& value) { - m_value = value; - return *this; - } + AnyValue& operator=(const std::vector& value); template - const std::vector& asVector() const { - return as>(); - } + const std::vector& asVector() const; template - std::vector& asVector() { - return as>(); - } + std::vector& asVector(); AnyValue& operator=(const AnyMap& value); AnyValue& operator=(AnyMap&& value); @@ -239,60 +176,8 @@ private: friend class AnyValue; }; -// Definitions for templated functions which require the full declaration of -// class AnyMap. - -template -AnyValue& AnyValue::operator=(const std::unordered_map items) { - m_value = AnyMap(); - AnyMap& dest = as(); - for (const auto& item : items) { - dest[item.first] = item.second; - } - return *this; } -template -AnyValue& AnyValue::operator=(const std::map items) { - m_value = AnyMap(); - AnyMap& dest = as(); - for (const auto& item : items) { - dest[item.first] = item.second; - } - return *this; -} +#include "cantera/base/AnyMap.inl.h" -template<> -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(); - } - 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())); - } -} - -template -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); - } catch (boost::bad_any_cast&) { - throw CanteraError("AnyValue::asMap", - "Value of key '{}' is not a '{}'", - item.first, demangle(typeid(T))); - } - } - return dest; -} - -} #endif diff --git a/include/cantera/base/AnyMap.inl.h b/include/cantera/base/AnyMap.inl.h new file mode 100644 index 000000000..cba011009 --- /dev/null +++ b/include/cantera/base/AnyMap.inl.h @@ -0,0 +1,122 @@ +//! @file AnyMap.inl.h + +#ifndef CT_ANYMAP_INL_H +#define CT_ANYMAP_INL_H + +#include "cantera/base/AnyMap.h" + +#include +#include + +namespace Cantera +{ + +// Definitions for AnyValue templated functions + +template +const T &AnyValue::as() const { + try { + return boost::any_cast(m_value); + } catch (boost::bad_any_cast&) { + 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))); + } + } +} + +template +T &AnyValue::as() { + try { + return boost::any_cast(m_value); + } catch (boost::bad_any_cast&) { + 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))); + } + } +} + +template +bool AnyValue::is() const { + return m_value.type() == typeid(T); +} + +template +AnyValue &AnyValue::operator=(const std::vector &value) { + m_value = value; + return *this; +} + +template +const std::vector &AnyValue::asVector() const { + return as>(); +} + +template +std::vector &AnyValue::asVector() { + return as>(); +} + +template +AnyValue& AnyValue::operator=(const std::unordered_map items) { + m_value = AnyMap(); + AnyMap& dest = as(); + for (const auto& item : items) { + dest[item.first] = item.second; + } + return *this; +} + +template +AnyValue& AnyValue::operator=(const std::map items) { + m_value = AnyMap(); + AnyMap& dest = as(); + for (const auto& item : items) { + dest[item.first] = item.second; + } + return *this; +} + +template<> +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(); + } + 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())); + } +} + +template +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); + } catch (boost::bad_any_cast&) { + throw CanteraError("AnyValue::asMap", + "Value of key '{}' is not a '{}'", + item.first, demangle(typeid(T))); + } + } + return dest; +} + +} +#endif diff --git a/src/base/AnyMap.cpp b/src/base/AnyMap.cpp index 0f5a45af8..2e118c793 100644 --- a/src/base/AnyMap.cpp +++ b/src/base/AnyMap.cpp @@ -26,6 +26,57 @@ bool AnyValue::hasKey(const std::string& key) const { return (is() && as().hasKey(key)); } +void AnyValue::setKey(const std::string &key) { m_key = key; } + +const std::type_info &AnyValue::type() { + return m_value.type(); +} + +AnyValue &AnyValue::operator=(const std::string &value) { + m_value = value; + return *this; +} + +AnyValue &AnyValue::operator=(const char *value) { + m_value = std::string(value); + return *this; +} + +const std::string &AnyValue::asString() const { + return as(); +} + +AnyValue &AnyValue::operator=(double value) { + m_value = value; + return *this; +} + +double AnyValue::asDouble() const { + return as(); +} + +AnyValue &AnyValue::operator=(bool value) { + m_value = value; + return *this; +} + +bool AnyValue::asBool() const { + return as(); +} + +AnyValue &AnyValue::operator=(long int value) { + m_value = value; + return *this; +} + +AnyValue &AnyValue::operator=(int value) { + m_value = static_cast(value); + return *this; +} + +long int AnyValue::asInt() const { + return as(); +} AnyValue& AnyValue::operator=(const AnyMap& value) { m_value = value; return *this; @@ -45,7 +96,6 @@ std::string AnyValue::demangle(const std::type_info& type) const } } - // Methods of class AnyMap AnyValue& AnyMap::operator[](const std::string& key)