SIMLIB/C++  3.07
object.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file object.cc Root of SIMLIB/C++ class hierarchy
3 //
4 // Copyright (c) 1991-2004 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 //
10 // this module contains implementation of base class SimObject
11 //
12 
13 #include "simlib.h"
14 #include "internal.h"
15 #include <unordered_map> // used by name dictionary
16 
17 ////////////////////////////////////////////////////////////////////////////
18 namespace simlib3 {
19 
21 ////////////////////////////////////////////////////////////////////////////
22 
23 // static flag for IsAllocated()
24 static bool SimObject_allocated = false;
25 
26 // NameDict singleton: dictionary for partial SimObject->name mapping
27 // Naming is not performance sensitive part of SIMLIB/C++
28 // We use this approach to save memory (64bit: sizeof(std::string)==32)
29 class NameDict {
30  using TNameDict = std::unordered_map<SimObject*,std::string>;
31  static TNameDict *dict;
32  public:
34  if(dict==nullptr) { // can be created before construction
35  dict = new TNameDict;
36  }
37  }
38  // Set name of object
39  // can be used before singleton construction
40  // Warning: do not use in destructors!
41  void Set(SimObject *o, const std::string &name) {
42  if(dict==nullptr) {
43  dict = new TNameDict;
44  }
45  (*dict)[o] = name;
46  }
47  std::string Get(const SimObject *o) const {
48  if(dict==nullptr)
49  return ""; // name dictionary not created -> empty name
50  TNameDict::iterator it = dict->find(const_cast<SimObject*>(o));
51  if(it == dict->end()) // not found
52  return ""; // empty name
53  return it->second;
54  }
55  void Erase(SimObject *o) {
56  if(dict!=nullptr)
57  dict->erase(o);
58  }
59  ~NameDict() { // remove dictionary, all named objects -> ""
60  delete dict;
61  dict=nullptr; // important for Get called after dict destruction
62  }
63 };
64 
65 NameDict::TNameDict *NameDict::dict = nullptr; // static member initialization
66 static NameDict name_dict; // SINGLETON, possible problems (empty names) if used after destruction
67 
68 ////////////////////////////////////////////////////////////////////////////
69 //! allocate memory for object
70 // TODO: optimize for small objects?
71 void *SimObject::operator new(size_t size) {
72  void *ptr;
73 // try {
74  ptr = ::new char[size]; // global operator new
75 // Dprintf(("SimObject::operator new(%u) = %p ", size, ptr)); // ### add extra debug level for this
76 // }catch(...) { SIMLIB_error(MemoryError); }
77 // if(!ptr) SIMLIB_error(MemoryError); // only for VERY old compilers
78  SimObject_allocated = true; // update flag (checked in constructor)
79  return ptr;
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////
83 //! free memory
84 //
85 //TODO: this can create trouble if called from e.g. Behavior()
86 //
87 void SimObject::operator delete(void *ptr) {
88 // Dprintf(("SimObject::operator delete(%p) ", ptr));
89  SimObject *sp = static_cast<SimObject*>(ptr);
90  if (sp->isAllocated()) {
91  sp->_flags = 0; // clear all flags
92  ::operator delete[](ptr); // free memory
93  }
94 }
95 
96 
97 ////////////////////////////////////////////////////////////////////////////
98 //! constructor
99 //
101  //_name(0),
102  _flags(0)
103 {
104 // Dprintf(("SimObject::SimObject() this=%p ", this));
105  if(SimObject_allocated) {
106  SimObject_allocated = false;
108  }
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////
112 //! virtual destructor
113 //
115 {
116 // Dprintf(("SimObject::~SimObject() this=%p ", this));
117  if(HasName()) {
118  name_dict.Erase(this);
119  }
120 }
121 
122 ////////////////////////////////////////////////////////////////////////////
123 //! set the name of object
124 //
125 void SimObject::SetName(const std::string &name)
126 {
127  name_dict.Set(this,name);
129 }
130 
131 ////////////////////////////////////////////////////////////////////////////
132 //! get the name of object
133 //
134 std::string SimObject::Name() const
135 {
136  // TODO: use RTTI+pointer if empty name by default
137  return name_dict.Get(this);
138 }
139 
140 
141 ////////////////////////////////////////////////////////////////////////////
142 //! print object's info
143 /// TODO: use operator <<
144 void SimObject::Output() const
145 {
146  Print("SimObject: this=%p, name=%s\n", this, Name().c_str()); // default
147 }
148 
149 } // namespace
150 
std::unordered_map< SimObject *, std::string > TNameDict
Definition: object.cc:30
void SetName(const std::string &name)
assign the name
Definition: object.cc:125
SimObject()
constructor
Definition: object.cc:100
unsigned _flags
bool flags for internal use (TODO bitfield?)
Definition: simlib.h:308
std::string Get(const SimObject *o) const
Definition: object.cc:47
bool HasName() const
Definition: simlib.h:321
bool isAllocated() const
Definition: simlib.h:318
int Print(const char *fmt,...)
for Output methods, can be redirected
Definition: print.cc:92
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
static TNameDict * dict
Definition: object.cc:31
virtual void Output() const
print object to default output
Definition: object.cc:144
Base class for almost all SIMLIB classes.
Definition: simlib.h:299
virtual ~SimObject()
virtual destructor
Definition: object.cc:114
static NameDict name_dict
Definition: object.cc:66
Internal header file for SIMLIB/C++.
Main SIMLIB/C++ interface.
virtual std::string Name() const
get object name
Definition: object.cc:134
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
void Set(SimObject *o, const std::string &name)
Definition: object.cc:41
void Erase(SimObject *o)
Definition: object.cc:55
static bool SimObject_allocated
Definition: object.cc:24