DiaDes  0.1
DIAgnosis of Discrete-Event System
InfoManager.hh
Go to the documentation of this file.
1 
9 #ifndef __DIADES__UTILS__INFOMANAGER__HH__
10 #define __DIADES__UTILS__INFOMANAGER__HH__
11 
12 #include<string>
13 #include<limits>
14 #include<unordered_map>
15 #include<vector>
20 
21 
22 namespace Diades
23 {
24  namespace Utils
25  {
26 
50  template<typename _Info,
51  typename _InfoId,
52  typename _NullInfo = NullValue<_Info>,
53  typename _NullInfoId = NullValue<_InfoId>,
54  typename _Hash = std::hash<_Info> >
56  {
57  public:
62  using Info = _Info;
63 
68  using InfoId = _InfoId;
69 
73  using NullInfo = _NullInfo;
74 
75 
76 
77 
81  using NullInfoId = _NullInfoId;
82 
83 
87  const Info nullInfo = NullInfo().nullValue();
88 
92  const InfoId nullInfoId = NullInfoId().nullValue();
93 
94 
98  using Hash = _Hash;
99 
104  static string
106  {
107  return "Diades::Utils::InfoManager";
108  }
109 
114 
115 
116 
117 
118  protected:
119  using Map = std::unordered_map<size_t, std::vector<InfoId> >;
120 
121 
125  using InfoIdIterator = typename std::vector<InfoId>::const_iterator;
126 
139  std::vector<Info> _infos;
140 
146  std::vector<InfoId> _infoIds;
147 
153  template<typename _Iterator>
154  class GetInfo
155  {
156  public:
157  using Data = Info;
158  using Iterator = _Iterator;
160 
161  const Data & operator()(const MapStructure & m, Iterator it) const
162  {
163  return m.getInfo(*it);
164  }
165  };
166 
167  public:
168 
173  template<typename InfoIdIterator>
175 
176 
177  public:
178 
179 
183  InfoManager() = default;
184 
185 
190  InfoManager(InfoManager const& other) = default;
191 
200  {
201  if(this != &other)
202  {
203  _infoMap = other._infoMap;
204  _infos = other._infos;
205  _infoIds = other._infoIds;
206  }
207  return *this;
208  }
209 
210 
216  _infoMap(std::move(other._infoMap)),
217  _infos(std::move(other._infos)),
218  _infoIds(std::move(other._infoIds)){}
219 
226  {
227  if(this != &other)
228  {
229  _infoMap = std::move(other._infoMap);
230  _infos = std::move(other._infos);
231  _infoIds = std::move(other._infoIds);
232  }
233  return *this;
234  }
235 
239  virtual ~InfoManager() = default;
240 
246  bool
247  hasInfo(const Info & info) const
248  {
249  if(!(info == nullInfo))
250  {
251  auto it = _infoMap.find(Hash()(info));
252  if(it != _infoMap.end())
253  {
254  return(std::find_if(it->second.begin(),
255  it->second.end(),
256  [&info, this](size_t index)
257  {
258  return info == _infos[index]; }))
259  != it->second.end();
260  }
261  else
262  {
263  return false;
264  }
265  }
266  return true;
267  }
268 
276  bool
277  hasInfoId(InfoId id) const
278  {
279  return _infos.size() > id && id != nullInfoId;
280  }
281 
291  bool
292  setInfo(const Info & info, InfoId id)
293  {
294  if(id == nullInfoId)
295  {
296  return false;
297  }
298  if(info == nullInfo)
299  {
300  return false;
301  }
302  if(hasInfo(info))
303  {
304  return infoId(info) == id;
305  }
306  if(id >= _infos.size())
307  {
308  _infos.resize(id + 1, nullInfo);
309  _infoIds.resize(id + 1, nullInfoId);
310  }
311  _infos[id] = info;
312  _infoIds[id] = id;
313  _infoMap[Hash()(info)].push_back(id);
314 
315  return true;
316  }
317 
325  InfoId
326  infoId(const Info & info)
327  {
328  if(info == nullInfo)
329  {
330  return nullInfoId;
331  }
332  size_t hashInfo = Hash()(info);
333  auto it = _infoMap.find(hashInfo);
334  if(it != _infoMap.end())
335  {
336  auto it2 = std::find_if(it->second.begin(),
337  it->second.end(),
338  [&info, this](size_t index)
339  {
340  return info == _infos[index]; });
341 
342  if(it2 != it->second.end())
343  {
344  return *it2;
345  }
346  _infos.push_back(info);
347  _infoIds.push_back(_infos.size() - 1);
348  it->second.push_back(_infos.size() - 1);
349  return it->second.back();
350  }
351  _infos.push_back(info);
352  _infoIds.push_back(_infos.size() - 1);
353  _infoMap[hashInfo].push_back(_infos.size() - 1);
354  return _infos.size() - 1;
355  }
356 
364  const Info &
365  getInfo(InfoId id) const
366  {
367  if(id == nullInfoId)
368  {
369  return nullInfo;
370  }
371  if(id >= _infos.size())
372  {
373  return nullInfo;
374  }
375  return _infos[id];
376  }
377 
390  InfoManager &
391  initialise(unsigned capacity)
392  {
393  require(Exception, capacity > 0,
394  Msg("initialise: capacity %1% is null, try capacity = 1 at least")
395  % capacity);
396 
397  clear();
398  _infos.reserve(capacity);
399  _infoIds.reserve(capacity);
400  return *this;
401  }
402 
407  const std::vector<Info> &
408  storage() const
409  {
410  return _infos;
411  }
412 
418  begin() const
419  {
420  return _infoIds.begin();
421  }
422 
428  end() const
429  {
430  return _infoIds.end();
431  }
432 
441  template<typename InfoIdIterator>
444  {
445  return InfoIdRangeInfoIterator<InfoIdIterator>(*this, iterator);
446  }
447 
448 
449 
450  private:
451 
455  void
457  {
458  _infoMap.clear();
459  _infos.clear();
460  }
461 
462  public:
463 
468  size_t
470  {
471  return _infos.size();
472  }
473 
484  bool
485  isConsistentWith(const InfoManager & manager) const
486  {
487  if(numberOfInfos() > manager.numberOfInfos())
488  {
489  return false;
490  }
491  bool result = true;
492  size_t index = 1;
493  while(index < numberOfInfos())
494  {
495  result = (_infos[index] == manager._infos[index]);
496  ++index;
497  }
498  return result;
499  }
500 
511  bool
512  isEquivalentTo(const InfoManager & manager) const
513  {
514  return isConsistentWith(manager) && manager.isConsistentWith(*this);
515  }
516 
530  InfoManager &
531  appendWith(const InfoManager & manager)
532  {
533  if(this != &manager)
534  {
535  for(InfoId id = 0; id < manager.numberOfInfos(); ++id)
536  {
537  infoId(manager.getInfo(id));
538  }
539  }
540  return *this;
541  }
542 
554  InfoManager &
556  const InfoManager & m2)
557  {
558  if(&m1 == &m2)
559  {
560  if(this != &m1)
561  {
562  *this = m1;
563  }
564  return *this;
565  }
566 
567  if(this == &m1)
568  {
569  InfoManager tmp(*this);
570  makeIntersection(tmp, m2);
571  }
572  else
573  {
574  if(this == &m2)
575  {
576  InfoManager tmp(*this);
577  makeIntersection(m1, tmp);
578  }
579  else
580  {
581  if(m1.numberOfInfos() == 0)
582  {
583  clear();
584  }
585  else
586  {
588  for(size_t i = 0; i < m1.numberOfInfos(); ++i)
589  {
590  if(m2.hasInfo(m1.getInfo(i)))
591  {
592  infoId(m1.getInfo(i));
593  }
594  }
595  }
596  }
597  }
598  return *this;
599  }
600 
612  InfoManager &
613  makeUnion(const InfoManager & m1,
614  const InfoManager & m2)
615  {
616  if(&m1 == &m2)
617  {
618  if(this != &m1)
619  {
620  *this = m1;
621  }
622  return *this;
623  }
624  if(this == &m1)
625  {
626  for(size_t i = 0; i < m2.numberOfInfos(); ++i)
627  {
628  if(!hasInfo(m2.getInfo(i)))
629  {
630  infoId(m2.getInfo(i));
631  }
632  }
633  }
634  else
635  {
636  if(this == &m2)
637  {
638 
639  for(size_t i = 0; i < m1.numberOfInfos(); ++i)
640  {
641  if(!hasInfo(m1.getInfo(i)))
642  {
643  infoId(m1.getInfo(i));
644  }
645  }
646 
647 
648 
649  }
650  else
651  {
652  *this = m1;
653  appendWith(m2);
654  }
655 
656  }
657  return *this;
658  }
659 
660 
661 
667  bool isNull(const Info & info) const
668  {
669  return info == nullInfo;
670  }
671 
677  bool isNullId(const InfoId & infoId) const
678  {
679  return infoId == nullInfoId;
680  }
681  };
682 
683 
684  }
685 }
686 
687 
688 #endif /* __DIADES__UTILS__INFOMANAGER__HH__ */
689 
static string typeName()
Definition: InfoManager.hh:105
InfoIdRangeInfoIterator< InfoIdIterator > infoIdRangeInfoIterator(InfoIdIterator iterator) const
Definition: InfoManager.hh:443
InfoManager & appendWith(const InfoManager &manager)
Definition: InfoManager.hh:531
bool isNullId(const InfoId &infoId) const
Definition: InfoManager.hh:677
InfoIdIterator end() const
Definition: InfoManager.hh:428
bool setInfo(const Info &info, InfoId id)
Definition: InfoManager.hh:292
InfoManager & operator=(InfoManager &&other)
Definition: InfoManager.hh:225
std::vector< InfoId > _infoIds
Definition: InfoManager.hh:146
bool hasInfo(const Info &info) const
Definition: InfoManager.hh:247
InfoManager & initialise(unsigned capacity)
Definition: InfoManager.hh:391
STL namespace.
bool isEquivalentTo(const InfoManager &manager) const
Definition: InfoManager.hh:512
InfoIdIterator begin() const
Definition: InfoManager.hh:418
bool hasInfoId(InfoId id) const
Definition: InfoManager.hh:277
InfoManager & operator=(InfoManager const &other)
Definition: InfoManager.hh:199
virtual ~InfoManager()=default
std::vector< Info > _infos
Definition: InfoManager.hh:139
bool isConsistentWith(const InfoManager &manager) const
Definition: InfoManager.hh:485
#define require(Exception, expr, message)
Definition: Assertion.hh:90
Namespace of the Diades project.
size_t numberOfInfos() const
Definition: InfoManager.hh:469
const Data & operator()(const MapStructure &m, Iterator it) const
Definition: InfoManager.hh:161
bool isNull(const Info &info) const
Definition: InfoManager.hh:667
ConstIterator on the Net.
InfoManager & makeUnion(const InfoManager &m1, const InfoManager &m2)
Definition: InfoManager.hh:613
InfoManager(InfoManager &&other)
Definition: InfoManager.hh:215
const Info & getInfo(InfoId id) const
Definition: InfoManager.hh:365
InfoId infoId(const Info &info)
Definition: InfoManager.hh:326
boost::format Msg
Definition: Verbose.hh:42
const std::vector< Info > & storage() const
Definition: InfoManager.hh:408
InfoManager & makeIntersection(const InfoManager &m1, const InfoManager &m2)
Definition: InfoManager.hh:555