// $Id$ // // Copyright (C) 2003-2008 Greg Landrum and Rational Discovery LLC // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include "Dict.h" #include #include #include #include #include #include #include #include namespace RDKit{ namespace { template std::string vectToString(const boost::any &val){ const std::vector &tv=boost::any_cast >(val); std::ostringstream sstr; sstr<<"["; std::copy(tv.begin(),tv.end(),std::ostream_iterator(sstr,",")); sstr<<"]"; return sstr.str(); } } void Dict::getVal(const std::string &what, std::string &res) const { // // We're going to try and be somewhat crafty about this getVal stuff to make these // containers a little bit more generic. The normal behavior here is that the // value being queried must be directly castable to type T. We'll robustify a // little bit by trying that and, if the cast fails, attempting a couple of // other casts, which will then be lexically cast to type T. // if(!hasVal(what) ) throw KeyErrorException(what); const boost::any &val = _data.find(what)->second; try{ res = boost::any_cast(val); } catch (const boost::bad_any_cast &) { if(val.type()==typeid(int)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(unsigned int)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(long)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(unsigned long)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(float)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(double)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(const char *)){ res = std::string(boost::any_cast(val)); } else if(val.type()==typeid(std::vector)){ res = vectToString(val); } else if(val.type()==typeid(std::vector)){ res = vectToString(val); } else { throw; } } }; bool Dict::getValIfPresent(const std::string &what, std::string &res) const { // // We're going to try and be somewhat crafty about this getVal stuff to make these // containers a little bit more generic. The normal behavior here is that the // value being queried must be directly castable to type T. We'll robustify a // little bit by trying that and, if the cast fails, attempting a couple of // other casts, which will then be lexically cast to type T. // DataType::const_iterator pos=_data.find(what); if (pos==_data.end()) return false; const boost::any &val = pos->second; try{ res = boost::any_cast(val); } catch (const boost::bad_any_cast &) { if(val.type()==typeid(int)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(unsigned int)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(long)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(unsigned long)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(float)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(double)){ res = boost::lexical_cast(boost::any_cast(val)); } else if(val.type()==typeid(const char *)){ res = std::string(boost::any_cast(val)); } else if(val.type()==typeid(std::vector)){ res = vectToString(val); } else if(val.type()==typeid(std::vector)){ res = vectToString(val); } else { return false; } } return true; }; namespace { template typename boost::enable_if, T>::type _fromany(const boost::any &arg) { T res; if(arg.type()==typeid(std::string) || arg.type()==typeid(const char *)){ try { res = boost::any_cast(arg); } catch (const boost::bad_any_cast &exc) { try{ res = boost::lexical_cast(boost::any_cast(arg)); } catch (...){ throw exc; } } } else { res = boost::any_cast(arg); } return res; } template typename boost::disable_if, T>::type _fromany(const boost::any &arg) { return boost::any_cast(arg); } } template T Dict::fromany(const boost::any &arg) const { return _fromany(arg); }; template boost::any Dict::toany(T arg) const { return boost::any(arg); }; #define ANY_FORCE(T) template T Dict::fromany(const boost::any& arg) const; \ template boost::any Dict::toany(T arg) const; ANY_FORCE(bool); ANY_FORCE(boost::shared_array); ANY_FORCE(boost::shared_array); ANY_FORCE(double); ANY_FORCE(int); ANY_FORCE(std::list); ANY_FORCE(std::string); ANY_FORCE(std::vector >); ANY_FORCE(std::vector >); ANY_FORCE(std::vector); ANY_FORCE(std::vector); ANY_FORCE(std::vector >); ANY_FORCE(std::vector); ANY_FORCE(std::vector >); ANY_FORCE(std::vector >); ANY_FORCE(std::vector); ANY_FORCE(std::vector); ANY_FORCE(unsigned int); template const std::string & Dict::fromany(const boost::any &arg) const; typedef boost::tuples::tuple uint32_t_tuple ; typedef boost::tuples::tuple double_tuple; template uint32_t_tuple Dict::fromany(const boost::any& arg) const; template boost::any Dict::toany(uint32_t_tuple arg) const; template double_tuple Dict::fromany(const boost::any& arg) const; template boost::any Dict::toany(double_tuple arg) const; }