Skip to content

Commit

Permalink
Replace boost::any with std::any
Browse files Browse the repository at this point in the history
Since we no longer need to "hide" the Boost usage, we can make the
std::any member of AnyValue a regular member variable rather than
a pointer, which simplifies a few things.
  • Loading branch information
speth authored and ischoegl committed Mar 9, 2023
1 parent 19d99b2 commit 172b323
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 145 deletions.
22 changes: 6 additions & 16 deletions include/cantera/base/AnyMap.h
Expand Up @@ -12,11 +12,7 @@

#include <unordered_map>
#include <filesystem>

namespace boost
{
class any;
}
#include <any>

namespace YAML
{
Expand Down Expand Up @@ -85,10 +81,6 @@ class AnyValue : public AnyBase
public:
AnyValue();
~AnyValue();
AnyValue(AnyValue const& other);
AnyValue(AnyValue&& other);
AnyValue& operator=(AnyValue const& other);
AnyValue& operator=(AnyValue&& other);

bool operator==(const AnyValue& other) const;
bool operator!=(const AnyValue& other) const;
Expand Down Expand Up @@ -275,24 +267,24 @@ class AnyValue : public AnyBase
std::string m_key;

//! The held value
std::unique_ptr<boost::any> m_value;
std::any m_value;

typedef bool (*Comparer)(const boost::any&, const boost::any&);
typedef bool (*Comparer)(const std::any&, const std::any&);

//! Equality comparison function used when *lhs* is of type *T*
template <typename T>
static bool eq_comparer(const boost::any& lhs, const boost::any& rhs);
static bool eq_comparer(const std::any& lhs, const std::any& rhs);

//! Helper function for comparing vectors of different (but comparable)
//! types, for example `vector<double>` and `vector<long int>`
template<class T, class U>
static bool vector_eq(const boost::any& lhs, const boost::any& rhs);
static bool vector_eq(const std::any& lhs, const std::any& rhs);

//! Helper function for comparing nested vectors of different (but
//! comparable) types, for example `vector<vector<double>>` and
//! `vector<vector<long int>>`
template<class T, class U>
static bool vector2_eq(const boost::any& lhs, const boost::any& rhs);
static bool vector2_eq(const std::any& lhs, const std::any& rhs);

mutable Comparer m_equals;

Expand Down Expand Up @@ -754,8 +746,6 @@ void warn_deprecated(const std::string& source, const AnyBase& node,

}

#ifndef CANTERA_API_NO_BOOST
#include "cantera/base/AnyMap.inl.h"
#endif

#endif
53 changes: 25 additions & 28 deletions include/cantera/base/AnyMap.inl.h
Expand Up @@ -5,9 +5,6 @@

#include "cantera/base/AnyMap.h"

#include <boost/any.hpp>
#include <boost/algorithm/string.hpp>

namespace Cantera
{
// re-declared to avoid needing to include global.h here
Expand All @@ -18,31 +15,31 @@ std::string demangle(const std::type_info& type);
template<class T>
const T &AnyValue::as() const {
try {
if (typeid(T) == typeid(double) && m_value->type() == typeid(long int)) {
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>());
const_cast<AnyValue*>(this)->m_value = static_cast<double>(as<long int>());
m_equals = eq_comparer<double>;
} else if (typeid(T) == typeid(std::vector<double>)
&& m_value->type() == typeid(std::vector<AnyValue>)) {
&& m_value.type() == typeid(std::vector<AnyValue>)) {
// Implicit conversion of vector<AnyValue> to vector<double>
auto& asAny = as<std::vector<AnyValue>>();
vector_fp asDouble(asAny.size());
for (size_t i = 0; i < asAny.size(); i++) {
asDouble[i] = asAny[i].as<double>();
}
*m_value = std::move(asDouble);
const_cast<AnyValue*>(this)->m_value = std::move(asDouble);
m_equals = eq_comparer<std::vector<double>>;
}
return boost::any_cast<const T&>(*m_value);
} catch (boost::bad_any_cast&) {
if (m_value->type() == typeid(void)) {
return std::any_cast<const T&>(m_value);
} catch (std::bad_any_cast&) {
if (m_value.type() == typeid(void)) {
// Values that have not been set are of type 'void'
throw InputFileError("AnyValue::as", *this,
"Key '{}' not found or contains no value", m_key);
} else {
throw InputFileError("AnyValue::as", *this,
"Key '{}' contains a '{}',\nnot a '{}'",
m_key, demangle(m_value->type()), demangle(typeid(T)));
m_key, demangle(m_value.type()), demangle(typeid(T)));
}
}
}
Expand All @@ -56,14 +53,14 @@ T &AnyValue::as() {

template<class T>
bool AnyValue::is() const {
return m_value->type() == typeid(T);
return m_value.type() == typeid(T);
}

template<> bool AnyValue::is<std::vector<double>>() const;

template<class T>
AnyValue &AnyValue::operator=(const std::vector<T> &value) {
*m_value = value;
m_value = value;
m_equals = eq_comparer<std::vector<T>>;
return *this;
}
Expand All @@ -84,7 +81,7 @@ std::vector<T> &AnyValue::asVector(size_t nMin, size_t nMax) {

template<class T>
AnyValue& AnyValue::operator=(const std::unordered_map<std::string, T> items) {
*m_value = AnyMap();
m_value = AnyMap();
m_equals = eq_comparer<AnyMap>;
AnyMap& dest = as<AnyMap>();
for (const auto& [key, value] : items) {
Expand All @@ -95,7 +92,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();
m_equals = eq_comparer<AnyMap>;
AnyMap& dest = as<AnyMap>();
for (const auto& [key, value] : items) {
Expand All @@ -109,15 +106,15 @@ 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();
m_equals = eq_comparer<AnyMap>;
}
return boost::any_cast<AnyMap&>(*m_value);
} catch (boost::bad_any_cast&) {
return std::any_cast<AnyMap&>(m_value);
} catch (std::bad_any_cast&) {
throw InputFileError("AnyValue::as", *this,
"value of key '{}' is a '{}',\nnot an 'AnyMap'.",
m_key, demangle(m_value->type()));
m_key, demangle(m_value.type()));
}
}

Expand Down Expand Up @@ -147,10 +144,10 @@ void AnyValue::checkSize(const std::vector<T>& v, size_t nMin, size_t nMax) cons
}

template<class T, class U>
bool AnyValue::vector_eq(const boost::any& lhs, const boost::any& rhs)
bool AnyValue::vector_eq(const std::any& lhs, const std::any& rhs)
{
const auto& lvec = boost::any_cast<T>(lhs);
const auto& rvec = boost::any_cast<U>(rhs);
const auto& lvec = std::any_cast<T>(lhs);
const auto& rvec = std::any_cast<U>(rhs);
if (lvec.size() != rvec.size()) {
return false;
} else {
Expand All @@ -159,10 +156,10 @@ bool AnyValue::vector_eq(const boost::any& lhs, const boost::any& rhs)
}

template<class T, class U>
bool AnyValue::vector2_eq(const boost::any& lhs, const boost::any& rhs)
bool AnyValue::vector2_eq(const std::any& lhs, const std::any& rhs)
{
const auto& lvec = boost::any_cast<std::vector<T>>(lhs);
const auto& rvec = boost::any_cast<std::vector<U>>(rhs);
const auto& lvec = std::any_cast<std::vector<T>>(lhs);
const auto& rvec = std::any_cast<std::vector<U>>(rhs);
if (lvec.size() != rvec.size()) {
return false;
} else {
Expand All @@ -176,9 +173,9 @@ bool AnyValue::vector2_eq(const boost::any& lhs, const boost::any& rhs)
}

template<class T>
bool AnyValue::eq_comparer(const boost::any& lhs, const boost::any& rhs)
bool AnyValue::eq_comparer(const std::any& lhs, const std::any& rhs)
{
using boost::any_cast;
using std::any_cast;
typedef vector<double> vd;
typedef vector<long int> vi;
typedef vector<AnyValue> va;
Expand Down

0 comments on commit 172b323

Please sign in to comment.