Atlas-C++
BaseObject.h
1 // This file may be redistributed and modified only under the terms of
2 // the GNU Lesser General Public License (See COPYING for details).
3 // Copyright (C) 2000-2004 Stefanus Du Toit, Aloril and Al Riddoch
4 
5 // $Id$
6 
7 #ifndef ATLAS_OBJECTS_BASEOBJECT_H
8 #define ATLAS_OBJECTS_BASEOBJECT_H
9 
10 #include <Atlas/Message/MEncoder.h>
11 #include <Atlas/Message/Element.h>
12 #include <Atlas/Bridge.h>
13 #include <Atlas/Exception.h>
14 
15 #include <map>
16 #include <list>
17 #include <string>
18 
19 #include <assert.h>
20 
21 namespace Atlas {
22 
26 namespace Objects {
27 
33 {
35  std::string m_name;
36  public:
37  explicit NoSuchAttrException(const std::string& name) noexcept :
38  Atlas::Exception("No such attribute '" + name + "'."),
39  m_name(name) {}
40 
41  ~NoSuchAttrException() noexcept override = default;
43  const std::string & getName() const {
44  return m_name;
45  }
46 };
47 
48 class BaseObjectData;
49 
62 template <typename T>
63 class Allocator {
64 protected:
69 
76 
77 public:
78 
82  std::map<std::string, int32_t> attr_flags_Data;
83 
87  Allocator();
88 
92  ~Allocator();
93 
103  T *getDefaultObjectInstance();
104 
112  T *alloc();
113 
121  void free(T *instance);
122 
126  void release();
127 
128 };
129 
130 template <typename T>
131 Allocator<T>::Allocator() : m_begin_Data(0)
132 {
133  T::fillDefaultObjectInstance(m_defaults_Data, attr_flags_Data);
134 }
135 
136 template <typename T>
138  release();
139 }
140 
141 template <typename T>
143 {
144  return &m_defaults_Data;
145 }
146 
147 template <typename T>
149 {
150  if (m_begin_Data) {
151  T *res = m_begin_Data;
152  assert( res->m_refCount == 0 );
153  res->m_attrFlags = 0;
154  res->m_attributes.clear();
155  m_begin_Data = static_cast<T*>(m_begin_Data->m_next);
156  return res;
157  }
158  return new T(&m_defaults_Data);
159 }
160 
161 template <typename T>
162 inline void Allocator<T>::free(T *instance)
163 {
164  instance->reset();
165  instance->m_next = m_begin_Data;
166  m_begin_Data = static_cast<T*>(instance);
167 }
168 
169 template <typename T>
171 {
172  //Delete all chained instances
173  T* next = m_begin_Data;
174  while (next) {
175  T* toDelete = next;
176  next = static_cast<T*>(next->m_next);
177  delete toDelete;
178  }
179  m_begin_Data = 0;
180 }
181 
182 
183 static const int BASE_OBJECT_NO = 0;
184 
215 {
216 public:
217  template <typename>
218  friend class Allocator;
219  template <typename>
220  friend class SmartPtr;
221 
226  explicit BaseObjectData(BaseObjectData *defaults);
227 
228  virtual ~BaseObjectData();
229 
230 
232  int getClassNo() const
233  {
234  return m_class_no;
235  }
236 
237  int32_t getAttrFlags() const
238  {
239  return m_attrFlags;
240  }
241 
242  virtual BaseObjectData * copy() const = 0;
243 
245  virtual bool instanceOf(int classNo) const;
246 
248  bool hasAttr(const std::string& name) const;
250  bool hasAttrFlag(int flag) const;
253  const Atlas::Message::Element getAttr(const std::string& name)
254  const;
257  virtual int copyAttr(const std::string& name,
258  Atlas::Message::Element & attr) const;
260  virtual void setAttr(const std::string& name,
261  const Atlas::Message::Element& attr);
263  virtual void removeAttr(const std::string& name);
265  virtual void removeAttrFlag(int flag);
266 
269  Atlas::Message::MapType asMessage() const;
270 
272  virtual void addToMessage(Atlas::Message::MapType &) const;
273 
275  virtual void sendContents(Atlas::Bridge & b) const;
276 
277  class const_iterator;
278 
279  // FIXME should this hold a reference to the object it's
280  // iterating over?
281 
296  class iterator
297  {
298  public:
299  friend class BaseObjectData;
300  friend class const_iterator;
301 
302  iterator() : m_obj(nullptr), m_val("", *this) {}
303  iterator(const iterator& I) : m_obj(I.m_obj),
304  m_current_class(I.m_current_class),
305  m_I(I.m_I), m_val(I.m_val.first, *this) {}
306  iterator(BaseObjectData& obj, int current_class);
307 
308  // default destructor is fine unless we hold a reference to m_obj
309 
310  iterator& operator=(const iterator& I);
311 
312  iterator& operator++(); // preincrement
313 
314  iterator operator++(int); // postincrement
315 
316  bool operator==(const iterator& I) const;
317 
318  bool operator!=(const iterator& I) const {return !operator==(I);}
319 
321  {
322  public:
323  PsuedoElement(const iterator& I) : m_I(I) {}
324 
325  operator Message::Element() const;
326  // this acts on const PsuedoElement instead of PsuedoElement
327  // so that we can assign to attributes refered to by
328  // a const iterator& (as opposed to a const_iterator, where
329  // we can't, but that's done later)
330  const PsuedoElement& operator=(const Message::Element& val) const;
331 
332  private:
333  const iterator& m_I;
334  };
335 
336  friend class PsuedoElement;
337 
338  typedef std::pair<std::string,PsuedoElement> value_type;
339 
340  const value_type& operator*() const {return m_val;}
341  const value_type* operator->() const {return &m_val;}
342 
343  private:
344  BaseObjectData *m_obj; // pointer to object whose args we're iterating
345  int m_current_class; // m_class_no for current class in the iteration
346  Message::MapType::iterator m_I; // iterator in m_obj->m_attributes
347  value_type m_val;
348  };
349  friend class iterator;
350 
351  // FIXME should this hold a reference to the object it's
352  // iterating over?
354  {
355  public:
356  friend class BaseObjectData;
357 
358  const_iterator() : m_obj(0), m_val("", *this) {}
359  const_iterator(const const_iterator& I) : m_obj(I.m_obj),
360  m_current_class(I.m_current_class),
361  m_I(I.m_I), m_val(I.m_val.first, *this) {}
362  const_iterator(const iterator& I) : m_obj(I.m_obj),
363  m_current_class(I.m_current_class),
364  m_I(I.m_I), m_val(I.m_val.first, *this) {}
365  const_iterator(const BaseObjectData& obj, int current_class);
366 
367  // default destructor is fine unless we hold a reference to m_obj
368 
369  const_iterator& operator=(const const_iterator& I);
370 
371  const_iterator& operator++(); // preincrement
372 
373  const_iterator operator++(int); // postincrement
374 
375  bool operator==(const const_iterator& I) const;
376 
377  bool operator!=(const const_iterator& I) const {return !operator==(I);}
378 
380  {
381  public:
382  PsuedoElement(const const_iterator& I) : m_I(I) {}
383 
384  operator Message::Element() const;
385 
386  private:
387  const const_iterator& m_I;
388  };
389 
390  friend class PsuedoElement;
391 
392  typedef std::pair<std::string,PsuedoElement> value_type;
393 
394  const value_type& operator*() const {return m_val;}
395  const value_type* operator->() const {return &m_val;}
396 
397  private:
398  const BaseObjectData *m_obj; // pointer to object whose args we're iterating
399  int m_current_class; // m_class_no for current class in the iteration
400  Message::MapType::const_iterator m_I; // const_iterator in m_obj->m_attributes
401  value_type m_val;
402  };
403 
404  friend class const_iterator;
405 
406  iterator begin() {return iterator(*this, -1);}
407  iterator end() {return iterator(*this, BASE_OBJECT_NO);}
408  iterator find(const std::string&);
409 
410  const_iterator begin() const {return const_iterator(*this, -1);}
411  const_iterator end() const {return const_iterator(*this, BASE_OBJECT_NO);}
412  const_iterator find(const std::string&) const;
413 
414 protected:
415 
420  virtual void free() = 0;
421  virtual void reset() = 0;
422  void incRef();
423  void decRef();
424 
426  virtual int getAttrClass(const std::string& name) const;
427 
429  virtual int getAttrFlag(const std::string& name) const;
430 
432  virtual void iterate(int& current_class, std::string& attr) const;
433 
434  int m_class_no; //each class has different enum
435  int m_refCount; //how many instances
436 
441 
446  std::map<std::string, Atlas::Message::Element> m_attributes;
447  // is attribute in this object or in default object?
448  int32_t m_attrFlags;
449 };
450 
451 inline void BaseObjectData::incRef() {
452  m_refCount++;
453 }
454 
455 inline void BaseObjectData::decRef() {
456  //why zero based refCount? avoids one m_refCount-- ;-)
457  assert( m_refCount >= 0 );
458  if(!m_refCount) {
459  free();
460  return;
461  }
462  m_refCount--;
463 }
464 
465 inline BaseObjectData::iterator BaseObjectData::iterator::operator++(int) // postincrement
466 {
467  iterator tmp = *this;
468  operator++();
469  return tmp;
470 }
471 
472 inline BaseObjectData::const_iterator BaseObjectData::const_iterator::operator++(int) // postincrement
473 {
474  const_iterator tmp = *this;
475  operator++();
476  return tmp;
477 }
478 
479 } } // namespace Atlas::Objects
480 
481 #endif
Allocator()
Ctor.
Definition: BaseObject.h:131
T m_defaults_Data
The default instance, acting as a prototype for all other instances.
Definition: BaseObject.h:68
Atlas stream bridge.
Definition: Bridge.h:35
const std::string & getName() const
Get the name of the attribute which does not exist.
Definition: BaseObject.h:43
The iterator first iterates over the contents of m_obj->m_attributes, holding an iterator to the attr...
Definition: BaseObject.h:296
void free(T *instance)
Frees up an instance.
Definition: BaseObject.h:162
BaseObjectData * m_defaults
The default instance, acting as a prototype for all other instances.
Definition: BaseObject.h:440
T * getDefaultObjectInstance()
Gets the default object instance, which acts as a prototype for all other instances in the system...
Definition: BaseObject.h:142
Multi-type container.
Definition: Element.h:60
int getClassNo() const
Get class number:
Definition: BaseObject.h:232
The Atlas namespace.
Definition: Bridge.h:20
An exception indicating the requested attribute does not exist.
Definition: BaseObject.h:32
void release()
Deletes all pooled but unused instances.
Definition: BaseObject.h:170
~Allocator()
Dtor.
Definition: BaseObject.h:137
T * m_begin_Data
The first available instance, not currently in use.
Definition: BaseObject.h:75
T * alloc()
Allocates a new instance to be used.
Definition: BaseObject.h:148
Definition: Decoder.h:16
BaseObjectData * m_next
The next instance, if this instance has been freed up.
Definition: BaseObject.h:445
Trait which handles allocation of instances of BaseObject.
Definition: BaseObject.h:63
Atlas base object class.
Definition: BaseObject.h:214
Base class for all exceptions thrown by Atlas-C++.
Definition: Exception.h:17
std::map< std::string, int32_t > attr_flags_Data
A map of attributes and their flags.
Definition: BaseObject.h:82

Copyright 2000-2004 the respective authors.

This document can be licensed under the terms of the GNU Free Documentation License or the GNU General Public License and may be freely distributed under the terms given by one of these licenses.