cantera/include/cantera/base/AnyMap.inl.h

124 lines
3.4 KiB
C++

//! @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 {
if (typeid(T) == typeid(double) && m_value->type() == typeid(long int)) {
// Implicit conversion of long int to double
*m_value = static_cast<double>(as<long int>());
}
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 {
if (typeid(T) == typeid(double) && m_value->type() == typeid(long int)) {
// Implicit conversion of long int to double
*m_value = static_cast<double>(as<long int>());
}
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() const
{
std::map<std::string, T> dest;
for (const auto& item : as<AnyMap>().m_data) {
dest[item.first] = item.second.as<T>();
}
return dest;
}
}
#endif