Files
rdkit/Code/Demos/boost/any_container/dict.cpp
Greg Landrum 052ec66542 cleanups:
remove x bit from headers and sources;
remove a couple empty files from Code/GraphMol
2010-09-08 04:25:57 +00:00

274 lines
6.6 KiB
C++

#include <map>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/smart_ptr.hpp>
#include <string>
#include <iostream>
#include <Invariant/Invariant.h>
int idx=0;
class Contained {
public:
Contained() : _idx(idx) {
std::cout << "Contained CTOR:" << _idx << std::endl;
idx++;
}
~Contained() {
std::cout << "Contained DTOR:" << _idx << std::endl;
}
Contained( const Contained &other) : _idx(other._idx) {
std::cout << "Contained Copy CTOR:" << _idx << std::endl;
}
Contained &operator=( const Contained &other) {
_idx = other._idx;
std::cout << "Contained Assign:" << _idx << std::endl;
return *this;
}
int _idx;
};
template <typename T>
struct larger_of {
T operator()(T arg1,T arg2) { return arg1>arg2 ? arg1 : arg2; };
};
struct charptr_functor {
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
};
};
class Dict {
public:
typedef std::map<const char *,boost::any,charptr_functor> DataType;
Dict() {_data.clear();};
Dict(const Dict &other) { _data = other._data; };
Dict &operator=(const Dict &other) {
_data = other._data;
return *this;
};
bool hasVal(const char *what) const {
//DataType::const_iterator i;
//std::cerr << "\t\tpre: ";
//for(i=_data.begin();i!=_data.end();i++){
//std::cerr << (*i).first << " ";
//}
//std::cerr << std::endl;
//std::cerr << "\thasVal: " << what << ": " << _data.count(what) << std::endl;
//std::cerr << "\t\tpost: ";
//for(i=_data.begin();i!=_data.end();i++){
//std::cerr << (*i).first << " ";
//}
//std::cerr << std::endl;
return _data.count(what);
};
bool hasVal(const std::string &what) const {
return hasVal(what.c_str());
};
//
// 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.
//
template <typename T>
void getVal(const char *what,T &res) const {
PRECONDITION(hasVal(what),"getVal called on non-existent key");
const boost::any &val = _data.find(what)->second;
res = boost::any_cast<T>(val);
};
void getVal(const char *what,std::string &res) const {
PRECONDITION(hasVal(what),"getVal called on non-existent key");
const boost::any &val = _data.find(what)->second;
try{
res = boost::any_cast<std::string>(val);
} catch (const boost::bad_any_cast &) {
if(val.type()==typeid(int)){
res = boost::lexical_cast<std::string>(boost::any_cast<int>(val));
} else if(val.type()==typeid(long)){
res = boost::lexical_cast<std::string>(boost::any_cast<long>(val));
} else if(val.type()==typeid(float)){
res = boost::lexical_cast<std::string>(boost::any_cast<float>(val));
} else if(val.type()==typeid(double)){
res = boost::lexical_cast<std::string>(boost::any_cast<double>(val));
} else if(val.type()==typeid(const char *)){
res = std::string(boost::any_cast<const char *>(val));
} else {
throw;
}
}
};
template <typename T>
void getVal(const std::string &what,T &res) const { getVal(what.c_str(),res); };
template <typename T>
void setVal(const char *what,T &val){
_data[what] = boost::any(val);
};
template <typename T>
void setVal(const std::string &what,T &val) { setVal(what.c_str(),val); };
void clearVal(const char *what) { _data.erase(what); };
void reset() { _data.clear(); };
private:
DataType _data;
};
void test1(){
// basic containers
std::cout << "----------- TEST1 -----------" << std::endl;
Contained c;
TEST_ASSERT(c._idx==0);
Contained d(c);
TEST_ASSERT(d._idx==0);
Contained e;
TEST_ASSERT(e._idx==1);
std::cout << "assign" << std::endl;
e=c;
TEST_ASSERT(e._idx==0);
std::cout <<" Done" << std::endl;
}
void test2(){
// shared pointers with containers
std::cout << "----------- TEST2 -----------" << std::endl;
typedef boost::shared_ptr<Contained> CONT_SPTR;
CONT_SPTR s_d(new Contained());
TEST_ASSERT(s_d.use_count()==1);
CONT_SPTR s_e=s_d;
TEST_ASSERT(s_e.use_count()==2);
s_d.reset();
TEST_ASSERT(s_e.use_count()==1);
s_e.reset();
std::cout <<" Done" << std::endl;
}
void test3(){
// basic dict stuff
std::cout << "----------- TEST3 -----------" << std::endl;
Dict dict;
TEST_ASSERT(!dict.hasVal("foo"));
int tmp=4;
dict.setVal("foo",tmp);
TEST_ASSERT(dict.hasVal("foo"));
tmp=0;
dict.getVal("foo",tmp);
TEST_ASSERT(tmp==4);
Dict d2(dict);
TEST_ASSERT(d2.hasVal("foo"));
d2.getVal("foo",tmp);
TEST_ASSERT(tmp==4);
Dict d3;
d3=d2;
TEST_ASSERT(d3.hasVal("foo"));
d3.getVal("foo",tmp);
TEST_ASSERT(tmp==4);
std::cout <<" Done" << std::endl;
}
void test4(){
// dict containing Contained objects
std::cout << "----------- TEST4 -----------" << std::endl;
Dict dict;
TEST_ASSERT(!dict.hasVal("foo"));
Contained tmp;
int hold=tmp._idx;
std::cout << " set" << std::endl;
dict.setVal("foo",tmp);
std::cout << " query" << std::endl;
TEST_ASSERT(dict.hasVal("foo"));
std::cout << " get" << std::endl;
dict.getVal("foo",tmp);
TEST_ASSERT(tmp._idx==hold);
std::cout << " copy" << std::endl;
Dict d2(dict);
TEST_ASSERT(d2.hasVal("foo"));
d2.getVal("foo",tmp);
TEST_ASSERT(tmp._idx==hold);
Dict d3;
d3=d2;
TEST_ASSERT(d3.hasVal("foo"));
d3.getVal("foo",tmp);
TEST_ASSERT(tmp._idx==hold);
std::cout <<" Done" << std::endl;
}
void test5(){
// dict containing sptrs to Contained objects
std::cout << "----------- TEST5 -----------" << std::endl;
typedef boost::shared_ptr<Contained> CONT_SPTR;
Dict dict;
TEST_ASSERT(!dict.hasVal("foo"));
CONT_SPTR tmp(new Contained());
int hold=tmp->_idx;
std::cout << " set" << std::endl;
dict.setVal("foo",tmp);
std::cout << " query" << std::endl;
TEST_ASSERT(dict.hasVal("foo"));
std::cout << " get" << std::endl;
dict.getVal("foo",tmp);
TEST_ASSERT(tmp->_idx==hold);
std::cout << " copy" << std::endl;
Dict d2(dict);
TEST_ASSERT(d2.hasVal("foo"));
d2.getVal("foo",tmp);
TEST_ASSERT(tmp->_idx==hold);
Dict d3;
d3=d2;
TEST_ASSERT(d3.hasVal("foo"));
d3.getVal("foo",tmp);
TEST_ASSERT(tmp->_idx==hold);
std::cout <<" Done" << std::endl;
}
int main(){
test1();
test2();
test3();
test4();
test5();
}