Overture  Version 25
DBase.hh
Go to the documentation of this file.
1 #ifndef __DBASE_HH__
2 #define __DBASE_HH__
3 
4 #include <string>
5 #include <map>
6 
7 #include "kk_defines.hh"
8 #include "kk_ptr.hh"
9 
11 namespace DBase
12 {
13 
15  class DBErr : public KK::Err
16  {
17  public:
18  DBErr(std::string s="") : KK::Err(s) { }
19  };
20 
22  enum EntryTrait {
23  persistent=0x1,
25  };
26 
28  class Entry
29  {
30  public:
32  Entry() : traits(0x0) { }
33 
35  virtual ~Entry() { }
36 
38  unsigned int traits;
39 
40  };
41 
43  template<typename T>
44  class SpecializedEntry : public Entry
45  {
46  public:
48 
51  EXPLICIT SpecializedEntry(const T &e, void (*dd)(T &)=0) :
52  Entry(), entry(e), destroy_data(dd) { }
53 
54  EXPLICIT SpecializedEntry(void (*dd)(T &)) : Entry(), destroy_data(dd) { }
55 
56  EXPLICIT SpecializedEntry() : Entry(), destroy_data(0) { }
57 
59  virtual ~SpecializedEntry()
60  { if (destroy_data) destroy_data(entry); }
61 
63  T & operator*() { return entry; }
64 
66  const T & operator*() const { return entry; }
67 
68  private:
69 
72 
74  T entry;
75 
77  void (*destroy_data)(T &);
78 
79  };
80 
82 
83  template<typename T>
85  { return dynamic_cast< SpecializedEntry< T > * >(&e); }
86 
87  template<typename T>
90 
91  template<typename T>
92  T & cast_entry(Entry &e)
93  {
94  KK::Assert<DBErr> ( can_cast_entry<T>(e), " cannot cast entry to mismatched type");
95  SpecializedEntry<T> & p = dynamic_cast< SpecializedEntry< T > & > (e);
96  return *p;
97  }
98 
99  template<typename T>
101  {
102  KK::Assert<DBErr> ( can_cast_entry<T>(e), " cannot cast entry to mismatched type");
104  return *p;
105  }
106 
108  class DataBase
109  {
111  typedef std::map< std::string, DBase::EntryP > dbtype;
112  // typedef std::map< std::string, Entry *> dbtype;
113 
114  public:
116  DataBase() { }
117 
119 
120  DataBase(const DataBase &d) : db(d.db) { }
121 
123  virtual ~DataBase()
124  {
125  clear();
126  }
127 
129  virtual void clear()
130  {
131 
132  // sptr now takes care of deletes
133 // for ( dbtype::iterator i=this->db.begin(); i!=this->db.end(); i++ )
134 // // if ( (*i).second !=NULL )
135 // if ( (*i).second )
136 // delete (*i).second;
137 // else
138 // throw DBErr();
139 
140  this->db.clear();
141  }
142 
144 
165  template<typename T>
166  inline
167  T &
168  put(std::string name, const T &entry, void (*entry_destructor)(T&)=0)
169  {
170  KK::Assert<DBErr> ( name!="", "cannot use empty name" );
171  KK::Assert<DBErr> ( this->db.count(name)==0, "name "+name+" already in use!");
172  KK::sptr< SpecializedEntry<T> > spece = new SpecializedEntry<T>(entry,entry_destructor);
173  this->db[name] = KK::sptr_dynamic_cast<Entry>( spece );
174  // this->db[name] = dynamic_cast<Entry *>( spece );
175 
176  return get<T>(name);
177  }
178 
180  template<typename T>
181  inline
182  T &
183  put(std::string name, void (*entry_destructor)(T&)=0)
184  {
185  KK::Assert<DBErr> ( name!="", "cannot use empty name" );
186  KK::Assert<DBErr> ( this->db.count(name)==0, "name "+name+" already in use!");
187  KK::sptr< SpecializedEntry<T> > spece = new SpecializedEntry<T>(entry_destructor);
188  this->db[name] = KK::sptr_dynamic_cast<Entry>( spece );
189  // this->db[name] = dynamic_cast<Entry *>( spece );
190 
191  return get<T>(name);
192  }
193 
195  template<typename T>
196  inline
197  T &
198  get(std::string name)
199  {
200  KK::Assert<DBErr> ( this->db.count(name)==1, "name "+name+" not in database!" );
201 
203  // SpecializedEntry<T> * p = dynamic_cast< SpecializedEntry< T > * > (this->db[name]);
204 
205  KK::Assert<DBErr> ( p , "type mismatch for variable "+name );
206  return **p;
207  }
208 
210  template<typename T>
211  inline
212  const T &
213  get(std::string name) const
214  {
215  KK::Assert<DBErr> ( this->db.count(name)==1, "name "+name+" not in database!" );
216 
218  // SpecializedEntry<T> * p = dynamic_cast< SpecializedEntry< T > * > (this->db[name]);
219 
220  KK::Assert<DBErr> ( p , "type mismatch for variable "+name );
221 
222  return **p;
223  }
224 
225  inline
226  const KK::sptr< Entry >
227  getEntry(std::string name) const
228  {
229  KK::Assert<DBErr> ( this->db.count(name)==1, "name "+name+" not in database!" );
230  return this->db[name];
231  }
232 
234  void
235  remove(std::string name)
236  {
237  KK::Assert<DBErr> ( this->db.count(name)==1, "name "+name+" not in database!" );
238 
239  //sptr takes care of this if ( this->db[name]!=NULL ) delete this->db[name];
240 
241  this->db.erase(name);
242  }
243 
245  void toggleTrait(std::string name, int t)
246  {
247  KK::Assert<DBErr> ( this->db.count(name)==1, "name "+name+" not in database!" );
248 
249  if ( this->db[name]->traits & t )
250  this->db[name]->traits ^= t;
251  else
252  this->db[name]->traits |= t;
253 
254  }
255 
257  bool traitActive(std::string name, int t)
258  {
259  KK::Assert<DBErr> ( this->db.count(name)==1, "name "+name+" not in database!" );
260 
261  return this->db[name]->traits & t;
262  }
263 
265  bool has_key(std::string name) const { return this->db.count(name)!=0; }
266 
268  size_t size() const { return db.size(); }
269 
271  typedef void (*EntryProcessingFunction)(std::string , Entry &);
272 
275  {
276  for ( dbtype::iterator i=this->db.begin(); i!=this->db.end(); i++ )
277  func((*i).first, *((*i).second));
278  }
279 
281  template<class F>
282  inline
283  void processEntries(F &func)
284  {
285  for ( dbtype::iterator i=this->db.begin(); i!=this->db.end(); i++ )
286  func((*i).first, *((*i).second));
287  }
288 
290  template<class F>
291  inline
292  void processEntries(const F &func)
293  {
294  for ( dbtype::iterator i=this->db.begin(); i!=this->db.end(); i++ )
295  func((*i).first, *((*i).second));
296  }
297 
299  void merge( DataBase &db_in ) throw(DBErr)
300  {
301  for ( iterator n=db_in.begin(); n!=db_in.end(); n++ )
302  {
303  if ( !has_key( n->first ) )
304  db.insert(*n);
305  else
306  throw DBErr("cannot merge databases with duplicate entries");
307  }
308  }
309 
311 
314  void link( DataBase &from, std::string from_nm, std::string to_nm )
315  {
316  KK::Assert<DBErr> ( !has_key(to_nm), "name "+to_nm+" already in use!");
317  KK::Assert<DBErr> ( from.has_key(from_nm), "name "+to_nm+" not in link database!");
318 
319  db[to_nm] = from.db[from_nm];
320  }
321 
323 
326  void link( DBase::EntryP &from, std::string to_nm )
327  {
328  KK::Assert<DBErr> ( !has_key(to_nm), "name "+to_nm+" already in use!");
329 
330  db[to_nm] = from;
331  }
332 
333  typedef dbtype::iterator iterator;
334  typedef dbtype::const_iterator const_iterator;
335 
336  iterator begin() { return db.begin(); }
337  const_iterator begin() const { return db.begin(); }
338  iterator end() { return db.end(); }
339  const_iterator end() const { return db.end(); }
340 
341  private:
342  mutable dbtype db;
343  };
344 }
345 
346 #endif