Move AnyValue template definitions to inl file
This commit is contained in:
parent
713b9cc23c
commit
f8d183220c
3 changed files with 192 additions and 135 deletions
|
|
@ -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<class T>
|
||||
const T& as() const {
|
||||
try {
|
||||
return boost::any_cast<const T&>(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<class T>
|
||||
T& as() {
|
||||
try {
|
||||
return boost::any_cast<T&>(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<class T>
|
||||
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<std::string>();
|
||||
}
|
||||
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<double>();
|
||||
}
|
||||
AnyValue& operator=(double value);
|
||||
double asDouble() const;
|
||||
|
||||
AnyValue& operator=(bool value) {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
bool asBool() const {
|
||||
return as<bool>();
|
||||
}
|
||||
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<long int>(value);
|
||||
return *this;
|
||||
}
|
||||
long int asInt() const {
|
||||
return as<long int>();
|
||||
}
|
||||
AnyValue& operator=(long int value);
|
||||
AnyValue& operator=(int value);
|
||||
long int asInt() const;
|
||||
|
||||
template<class T>
|
||||
AnyValue& operator=(const std::vector<T>& value) {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
AnyValue& operator=(const std::vector<T>& value);
|
||||
template<class T>
|
||||
const std::vector<T>& asVector() const {
|
||||
return as<std::vector<T>>();
|
||||
}
|
||||
const std::vector<T>& asVector() const;
|
||||
template<class T>
|
||||
std::vector<T>& asVector() {
|
||||
return as<std::vector<T>>();
|
||||
}
|
||||
std::vector<T>& 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<class T>
|
||||
AnyValue& AnyValue::operator=(const std::unordered_map<std::string, T> items) {
|
||||
m_value = AnyMap();
|
||||
AnyMap& dest = as<AnyMap>();
|
||||
for (const auto& item : items) {
|
||||
dest[item.first] = item.second;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
AnyValue& AnyValue::operator=(const std::map<std::string, T> items) {
|
||||
m_value = AnyMap();
|
||||
AnyMap& dest = as<AnyMap>();
|
||||
for (const auto& item : items) {
|
||||
dest[item.first] = item.second;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#include "cantera/base/AnyMap.inl.h"
|
||||
|
||||
template<>
|
||||
inline AnyMap& AnyValue::as<AnyMap>() {
|
||||
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<AnyMap&>(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<class T>
|
||||
std::map<std::string, T> AnyValue::asMap()
|
||||
{
|
||||
std::map<std::string, T> dest;
|
||||
for (const auto& item : as<AnyMap>().m_data) {
|
||||
try {
|
||||
dest[item.first] = boost::any_cast<T>(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
|
||||
|
|
|
|||
122
include/cantera/base/AnyMap.inl.h
Normal file
122
include/cantera/base/AnyMap.inl.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
//! @file AnyMap.inl.h
|
||||
|
||||
#ifndef CT_ANYMAP_INL_H
|
||||
#define CT_ANYMAP_INL_H
|
||||
|
||||
#include "cantera/base/AnyMap.h"
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace Cantera
|
||||
{
|
||||
|
||||
// Definitions for AnyValue templated functions
|
||||
|
||||
template<class T>
|
||||
const T &AnyValue::as() const {
|
||||
try {
|
||||
return boost::any_cast<const T&>(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<class T>
|
||||
T &AnyValue::as() {
|
||||
try {
|
||||
return boost::any_cast<T&>(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<class T>
|
||||
bool AnyValue::is() const {
|
||||
return m_value.type() == typeid(T);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
AnyValue &AnyValue::operator=(const std::vector<T> &value) {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const std::vector<T> &AnyValue::asVector() const {
|
||||
return as<std::vector<T>>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::vector<T> &AnyValue::asVector() {
|
||||
return as<std::vector<T>>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
AnyValue& AnyValue::operator=(const std::unordered_map<std::string, T> items) {
|
||||
m_value = AnyMap();
|
||||
AnyMap& dest = as<AnyMap>();
|
||||
for (const auto& item : items) {
|
||||
dest[item.first] = item.second;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
AnyValue& AnyValue::operator=(const std::map<std::string, T> items) {
|
||||
m_value = AnyMap();
|
||||
AnyMap& dest = as<AnyMap>();
|
||||
for (const auto& item : items) {
|
||||
dest[item.first] = item.second;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline AnyMap& AnyValue::as<AnyMap>() {
|
||||
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<AnyMap&>(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<class T>
|
||||
std::map<std::string, T> AnyValue::asMap()
|
||||
{
|
||||
std::map<std::string, T> dest;
|
||||
for (const auto& item : as<AnyMap>().m_data) {
|
||||
try {
|
||||
dest[item.first] = boost::any_cast<T>(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
|
||||
|
|
@ -26,6 +26,57 @@ bool AnyValue::hasKey(const std::string& key) const {
|
|||
return (is<AnyMap>() && as<AnyMap>().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<std::string>();
|
||||
}
|
||||
|
||||
AnyValue &AnyValue::operator=(double value) {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double AnyValue::asDouble() const {
|
||||
return as<double>();
|
||||
}
|
||||
|
||||
AnyValue &AnyValue::operator=(bool value) {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool AnyValue::asBool() const {
|
||||
return as<bool>();
|
||||
}
|
||||
|
||||
AnyValue &AnyValue::operator=(long int value) {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AnyValue &AnyValue::operator=(int value) {
|
||||
m_value = static_cast<long int>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
long int AnyValue::asInt() const {
|
||||
return as<long int>();
|
||||
}
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue