Partial pimpl for AnyValue to hide boost on API.
- boost now only included in AnyMap.inl.h (within include/cantera)
This commit is contained in:
parent
f8d183220c
commit
686250e51f
3 changed files with 69 additions and 28 deletions
|
|
@ -7,13 +7,16 @@
|
|||
#include "cantera/base/global.h"
|
||||
#include "cantera/base/ctexceptions.h"
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
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<boost::any> m_value;
|
||||
static std::map<std::string, std::string> s_typenames;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,15 +16,15 @@ namespace Cantera
|
|||
template<class T>
|
||||
const T &AnyValue::as() const {
|
||||
try {
|
||||
return boost::any_cast<const T&>(m_value);
|
||||
return boost::any_cast<const T&>(*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<class T>
|
||||
T &AnyValue::as() {
|
||||
try {
|
||||
return boost::any_cast<T&>(m_value);
|
||||
return boost::any_cast<T&>(*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<class T>
|
||||
bool AnyValue::is() const {
|
||||
return m_value.type() == typeid(T);
|
||||
return m_value->type() == typeid(T);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
AnyValue &AnyValue::operator=(const std::vector<T> &value) {
|
||||
m_value = value;
|
||||
*m_value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ std::vector<T> &AnyValue::asVector() {
|
|||
|
||||
template<class T>
|
||||
AnyValue& AnyValue::operator=(const std::unordered_map<std::string, T> items) {
|
||||
m_value = AnyMap();
|
||||
*m_value = AnyMap();
|
||||
AnyMap& dest = as<AnyMap>();
|
||||
for (const auto& item : items) {
|
||||
dest[item.first] = item.second;
|
||||
|
|
@ -78,7 +78,7 @@ AnyValue& AnyValue::operator=(const std::unordered_map<std::string, T> items) {
|
|||
|
||||
template<class T>
|
||||
AnyValue& AnyValue::operator=(const std::map<std::string, T> items) {
|
||||
m_value = AnyMap();
|
||||
*m_value = AnyMap();
|
||||
AnyMap& dest = as<AnyMap>();
|
||||
for (const auto& item : items) {
|
||||
dest[item.first] = item.second;
|
||||
|
|
@ -91,14 +91,14 @@ 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();
|
||||
if (m_value->type() == typeid(void)) {
|
||||
*m_value = AnyMap();
|
||||
}
|
||||
return boost::any_cast<AnyMap&>(m_value);
|
||||
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()));
|
||||
m_key, demangle(m_value->type()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ 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);
|
||||
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 '{}'",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,37 @@ std::map<std::string, std::string> 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<AnyMap>()[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<long int>(value);
|
||||
*m_value = static_cast<long int>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -78,12 +109,12 @@ long int AnyValue::asInt() const {
|
|||
return as<long int>();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue