Files
rdkit/Code/RDGeneral/RDAny.h
Ricardo Rodriguez 7b7a8a4e17 Refactor iostreams includes (#8846)
* refactor iostreams includes

* restore ostream to MonomerInfo.cpp
2025-10-08 16:08:01 +02:00

217 lines
5.9 KiB
C++

// Copyright (c) 2015, Novartis Institutes for BioMedical Research Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Novartis Institutes for BioMedical Research Inc.
// nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <RDGeneral/export.h>
#ifndef RDKIT_RDANY_H
#define RDKIT_RDANY_H
#include <any>
#include <RDGeneral/BoostStartInclude.h>
#include <boost/utility.hpp>
#include <boost/lexical_cast.hpp>
#include <RDGeneral/BoostEndInclude.h>
#include "LocaleSwitcher.h"
#include "RDValue.h"
#include <string>
#include <vector>
#include <sstream>
namespace RDKit {
// RDValue does not dynamically create POD types (kind of like
// cdiggins::any) However, it doesn't use RTTI type info
// directly, it uses a companion short valued type
// to determine what to do.
// For unregistered types, it falls back to std::any.
// The Size of an RDAny is (sizeof(double) + sizeof(short) == 10 bytes)
//
// For the sake of compatibility, errors throw std::bad_any_cast
//
// Examples:
//
// RDAny v(2.);
// v = 1;
// std::vector<double> d;
// v == d;
// v.asDoubleVect().push_back(4.)
// rdany_cast<std::vector<double>(v).push_back(4.)
//
// Falls back to std::any for non registered types
// v = boost::shared_ptr<ROMol>(new ROMol(m));
//
// Safe container for RDValue -- cleans up memory and copy constructs
struct RDAny {
RDValue m_value;
RDAny() : m_value() {}
template <class T>
RDAny(const T &d) : m_value(d) {}
/*
explicit RDAny(bool v) : m_value(v) {}
template <class T>
explicit RDAny(std::vector<T> *v) : m_value(v) {}
template <class T>
explicit RDAny(const boost::shared_ptr<T> &v) : m_value(v) {}
*/
RDAny(const RDAny &rhs) { copy_rdvalue(m_value, rhs.m_value); }
~RDAny() { RDValue::cleanup_rdvalue(m_value); }
// For easy of use:
// RDAny v;
// v = 2.0;
// v = std::string("foo...");
RDAny &operator=(const RDAny &rhs) {
copy_rdvalue(m_value, rhs.m_value);
return *this;
}
RDAny &operator=(float d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(int d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(unsigned int d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(bool d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(const std::string &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(const std::vector<double> &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(const std::vector<float> &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(const std::vector<int> &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(const std::vector<unsigned int> &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = d;
return *this;
}
RDAny &operator=(const std::vector<std::string> &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d);
return *this;
}
RDAny &operator=(const std::any &d) {
RDValue::cleanup_rdvalue(m_value);
m_value = RDValue(d); // new std::any(d);
return *this;
}
template <class T>
RDAny &operator=(const T &d) {
RDValue::cleanup_rdvalue(m_value);
std::any *v = new std::any(d);
m_value = RDValue(v);
return *this;
}
};
////////////////////////////////////////////////////////////////
// rdany_cast
////////////////////////////////////////////////////////////////
// Const Access
template <class T>
const T rdany_cast(const RDAny &d) {
return rdvalue_cast<T>(d.m_value);
}
// Direct access
template <class T>
T rdany_cast(RDAny &d) {
return rdvalue_cast<T>(d.m_value);
}
template <class T>
typename boost::enable_if<boost::is_arithmetic<T>, T>::type from_rdany(
const RDAny &arg) {
T res;
if (arg.m_value.getTag() == RDTypeTag::StringTag) {
Utils::LocaleSwitcher ls;
try {
res = rdany_cast<T>(arg);
} catch (const std::bad_any_cast &exc) {
try {
res = boost::lexical_cast<T>(rdany_cast<std::string>(arg));
} catch (...) {
throw exc;
}
}
} else {
res = rdany_cast<T>(arg);
}
return res;
}
template <class T>
typename boost::disable_if<boost::is_arithmetic<T>, T>::type from_rdany(
const RDAny &arg) {
return rdany_cast<T>(arg);
}
} // namespace RDKit
#endif