DiaDes  0.1
DIAgnosis of Discrete-Event System
Event.hh
Go to the documentation of this file.
1 /*
2  * @file Event,hh
3  * @author Yannick PencolĂ©, ypencole@laas.fr, LAAS-CNRS,Univ. Toulouse
4  *
5  * Created on October 23rd 2017, 22:19
6  */
7 
8 #ifndef __DIADES_AUTOMATA_EXPERIMENTAL_EVENT_HH
9 #define __DIADES_AUTOMATA_EXPERIMENTAL_EVENT_HH
10 #include<unordered_map>
11 #include<vector>
14 #include <diades/utils/Verbose.hh>
16 
17 namespace Diades
18 {
19  namespace Automata
20  {
21  namespace Experimental
22  {
23  using Diades::Utils::Msg;
26 
34  template<typename _Event,
35  typename _EventId,
36  typename NullEvent = NullValue<_Event>,
37  typename NullEventId = NullValue<_EventId>,
38  typename Hash = std::hash<_Event> >
39  class EventManager :
40  public InfoManager<_Event,
41  _EventId,
42  NullEvent,
43  NullEventId,
44  Hash>
45  {
46  public:
47  using IM = InfoManager<_Event,
48  _EventId,
49  NullEvent,
50  NullEventId,
51  Hash>;
52  using Event = typename IM::Info;
53  using EventId = typename IM::InfoId;
54 
55  static string
57  {
58  return "Diades::Automata::Experimental::EventManager";
59  }
61 
62 
63 
64 
65 
66  private:
67 
72 
73 
74 
75 
76 
77 
78  public:
79 
80 
81 
82 
86  EventManager() = default;
87 
88 
93  EventManager(EventManager const& other) = default;
94 
100  EventManager& operator=(EventManager const& other) = default;
101 
102 
103 
104 
109  EventManager(EventManager&& other) = default;
115  EventManager& operator=(EventManager&& other) = default;
116 
120  virtual ~EventManager() = default;
121 
127  bool
128  hasEvent(const Event & event) const
129  {
130  return IM::hasInfo(event);
131  }
132 
140  bool
141  hasEventId(EventId id) const
142  {
143  return IM::hasInfoId(id);
144  }
145 
155  bool
156  setEvent(const Event & event, EventId id)
157  {
158  return IM::setInfo(event,id);
159  }
160 
169  EventId
170  eventId(const Event & event)
171  {
172  return IM::infoId(event);
173  }
174 
182  const Event &
183  getEvent(EventId id) const
184  {
185  return IM::getInfo(id);
186  }
187 
188 
193  size_t
195  {
196  return IM::numberOfInfos();
197  }
198 
204  {
205  return IM::nullInfoId;
206  }
207 
212  Event nullEvent() const
213  {
214  return IM::nullInfo;
215  }
216 
217  };
218 
219 
220 // /**
221 // * @struct EventStringLabel
222 // * This structure can be used to instanciate EventManager
223 // * that would create Event with label as string.
224 // *
225 // *
226 // */
227 // struct EventStringLabel
228 // {
229 // typedef std::string Label;
230 //
231 // static Label
232 // nullLabel()
233 // {
234 // return "";
235 // }
236 //
237 // static Label
238 // appendLabel(const Label & prefix, const Label & postfix)
239 // {
240 // return prefix + postfix;
241 // }
242 //
243 // };
244 //
245 // /**
246 // * @class EventManager
247 // * An EventManager is a container of EventStructure. An EventStructure
248 // * associates to an identifier an EventLabel. Based on this class
249 // * it is then possible to manipulate Event as simple ids. No pointers/references
250 // * are embedded in an Event. To get the effective label of a given Event ask
251 // * the EventManager (hash table + vector). For efficiency purpose, an Event
252 // * does not even hold a pointer about the EventManager that creates it.
253 // * It means that an Event may have several meanings depending on the
254 // * EventManagers that are available. It is up to the client to manage
255 // * Event's ownership.
256 // *
257 // * An EventManager aims at being very flexible. It can be copied. We can perform
258 // * intersection, union of EventManagers. But be aware that two EventManagers are
259 // * totally independent. A consistency check can be performed to attest that
260 // * an EventManager owns a subset of events from another manager with the same codes.
261 // * If two EventManagers own the same EventLabel with the same codes they are equivalent.
262 // *
263 // * The template parameter EventLabel should implement a static method nullLabel()
264 // * that returns a null label of class Label
265 // */
266 // template<typename EventLabel, typename EventId>
267 // class EventManager
268 // {
269 // public:
270 //
271 //
272 // /// Label the real content of an Event
273 // typedef typename EventLabel::Label Label;
274 //
275 // /// the mapping between any Label and any Event
276 // typedef std::unordered_map<Label, EventId> Map;
277 //
278 // static string
279 // typeName()
280 // {
281 // return "Automata::Experimental::EventManager";
282 // }
283 // typedef Diades::Utils::Exception<EventManager> Exception;
284 //
285 //
286 //
287 // private:
288 //
289 // /**
290 // * @class EventStructure
291 // * This class implements the content of an Event (data associated
292 // * to an Event). Basically, it is a name (Label) and possibly a nickname
293 // * (Label).
294 // */
295 // struct EventStructure
296 // {
297 //
298 // EventStructure() : _label(EventLabel::nullLabel()), _nickname(EventLabel::nullLabel()), _event(0)
299 // {
300 // }
301 //
302 // /**
303 // * Paramterized constructor
304 // * @param label the Label of the Event
305 // * @param nickname the nickname of the Event (Label)
306 // * @param event the id of the Event.
307 // *
308 // */
309 // EventStructure(Label label, Label nickname, EventId event) :
310 // _label(label), _nickname(nickname), _event(event)
311 // {
312 // }
313 //
314 // /**
315 // * Move constructor
316 // * @param structure the EventStructure to move
317 // */
318 // EventStructure(EventStructure && structure) :
319 // _label(structure._label),
320 // _nickname(structure._nickname),
321 // _event(structure._event)
322 // {
323 // }
324 //
325 // /**
326 // * Copy constructor
327 // * @param structure the EventStructure to copy
328 // */
329 // EventStructure(const EventStructure & structure) :
330 // _label(structure._label),
331 // _nickname(structure._nickname),
332 // _event(structure._event)
333 // {
334 // }
335 //
336 // /**
337 // * Assignment operator
338 // * @param es the EventStructure to copy
339 // * @return the current EventStructure
340 // */
341 // EventStructure & operator=(const EventStructure & es)
342 // {
343 // if(this != &es)
344 // {
345 // _label = es._label;
346 // _nickname = es._nickname;
347 // _event = es._event;
348 // }
349 // return *this;
350 // }
351 //
352 // /**
353 // * Equality operator
354 // * @param es the EventStructure to compare with
355 // * @return true is both EventStructure are equal (value equality)
356 // */
357 // bool operator==(const EventStructure & es) const
358 // {
359 // return(_event == es._event) && (_nickname == es._nickname) && (_label == es._label);
360 // }
361 //
362 // /** Difference operator
363 // * @param es the EventStructure to compare with
364 // * @return true is both EventStructure are difference (value difference)
365 // */
366 // bool operator!=(const EventStructure & es) const
367 // {
368 // return !(*this == es);
369 // }
370 // Label _label;
371 // Label _nickname;
372 // EventId _event;
373 // };
374 //
375 //
376 // /// _eventMap association between a Label and its corresponding Event id
377 // Map _eventMap;
378 // /** _events Event storage of the Events created by the manager. The Event of
379 // * index i is stored in _events[i] and _events[i]._event == i
380 // *
381 // **/
382 // std::vector<EventStructure> _events;
383 //
384 // /**
385 // * _eventIds might look redundant as it is a vector such that
386 // * _events[i] = index useful to implement an iterator begin/end
387 // * on the _events of the manager
388 // **/
389 // std::vector<EventId> _eventIds;
390 //
391 //
392 //
393 //
394 // public:
395 //
396 // /**
397 // * Default constructor
398 // *
399 // * Any default manager owns a null Event
400 // */
401 // EventManager() : _eventMap(), _events(), _eventIds()
402 // {
403 // _events.emplace_back();
404 // _eventMap[EventLabel::nullLabel()] = nullEvent();
405 // _eventIds.push_back(0);
406 // }
407 //
408 // /**
409 // * Copy constructor
410 // * @param manager the manager to copy
411 // */
412 // EventManager(const EventManager & manager) :
413 // _eventMap(manager._eventMap),
414 // _events(manager._events),
415 // _eventIds(manager._eventIds)
416 // {
417 // }
418 //
419 // /**
420 // * Move constructor
421 // * @param manager the manager to move
422 // */
423 // EventManager(EventManager && manager) :
424 // _eventMap(manager._eventMap),
425 // _events(manager._events),
426 // _eventIds(manager._eventIds)
427 // {
428 // }
429 //
430 // /**
431 // * Destructor
432 // */
433 // ~EventManager()
434 // {
435 // clear();
436 // }
437 //
438 // /**
439 // * Assignment operator
440 // * @param manager the manager to copy
441 // * @return the current manager
442 // */
443 // EventManager & operator=(const EventManager & manager)
444 // {
445 // if(this != &manager)
446 // {
447 // _eventMap = manager._eventMap;
448 // _events = manager._events;
449 // _eventIds = manager._eventIds;
450 // }
451 // return *this;
452 // }
453 //
454 // /**
455 // *
456 // * @param label a Label
457 // * @return true if the manager owns an Event with such a Label
458 // */
459 // bool
460 // hasEvent(const Label & label) const
461 // {
462 // return _eventMap.find(label) != _eventMap.end();
463 // }
464 //
465 // /**
466 // *
467 // * @param event an Event
468 // * @return true if the manager owns such an Event
469 // */
470 // bool
471 // hasEvent(EventId event) const
472 // {
473 // if(event == 0)
474 // {
475 // return true;
476 // }
477 // return _events.size() > event && _events[event]._event != 0;
478 // }
479 //
480 // /**
481 // * Associate the specific label to a specific event id
482 // * @param label
483 // * @param event
484 // * @return true if the assignement is a success
485 // * (i.e. label is indeed associated with id. id was not assigned to
486 // * anything else, and label was not assigned to another id
487 // */
488 // bool
489 // setEvent(const Label & label, EventId evt)
490 // {
491 // if(hasEvent(label))
492 // {
493 // return event(label) == evt;
494 // }
495 // if(evt >= _events.size())
496 // {
497 // _events.resize(evt + 1);
498 // }
499 // _events[evt]._event = evt;
500 // _events[evt]._label = label;
501 // _events[evt]._nickname = label;
502 // _eventIds.push_back(evt);
503 // _eventMap[label] = evt;
504 // return true;
505 // }
506 //
507 // /**
508 // *
509 // * @param label a Label
510 // * @return the Event of the manager whose Label is label
511 // */
512 // EventId
513 // event(const Label & label)
514 // {
515 // auto it = _eventMap.find(label);
516 // if(it == _eventMap.end())
517 // {
518 // _eventMap[label] = _events.size();
519 // _events.emplace_back(label, label, _events.size());
520 // _eventIds.push_back(_events.back()._event);
521 // return _events.back()._event;
522 // }
523 // return it->second;
524 // }
525 //
526 // /**
527 // *
528 // * @param event an Event
529 // * @return the Label of the Event
530 // * @pre hasEvent(event)
531 // */
532 // const Label &
533 // getLabel(EventId event) const
534 // {
535 // require(Exception, hasEvent(event),
536 // Msg("getLabel: event %1% does not exist in this EventManager")
537 // % event);
538 // return _events[event]._label;
539 // }
540 //
541 // /**
542 // *
543 // * @param event an Event
544 // * @return the nickname (Label) of the Event
545 // * @pre hasEvent(event)
546 // */
547 // const Label &
548 // getNickname(EventId event) const
549 // {
550 // require(Exception, hasEvent(event),
551 // Msg("getNickname: event %1% does not exist in this EventManager")
552 // % event);
553 // return _events[event]._nickname;
554 // }
555 //
556 // /**
557 // *
558 // * @return the set of (Label -> Event) contained in the manager
559 // */
560 // const EventManager::Map &
561 // map() const
562 // {
563 // return _eventMap;
564 // }
565 //
566 // /**
567 // *
568 // * @return the null Event of the manager
569 // */
570 // EventId
571 // nullEvent() const
572 // {
573 // return EventId();
574 // }
575 //
576 // /**
577 // *
578 // * @param e an Event
579 // * @return true if e is the null Event of the manager
580 // */
581 // bool
582 // isNull(EventId e) const
583 // {
584 // return e == nullEvent();
585 // }
586 //
587 // /**
588 // * @param capacity the capacity to reserve
589 // * @return the current EventManager
590 // *
591 // * The current EventManager is fully reinitialised so any
592 // * Event that was associate with it is now invalid (except the
593 // * null Event). 'capacity' allocates memory. The recommended
594 // * use is to create less Events than capacity. If more, there
595 // * will be memory reallocation (performance issue only).
596 // *
597 // * @pre capacity > 0
598 // */
599 // EventManager &
600 // initialise(unsigned capacity)
601 // {
602 // require(Exception, capacity > 0,
603 // Msg("initialise: capacity is set to %1%")
604 // % capacity);
605 // clear();
606 // _events.reserve(capacity + 1);
607 // _events.emplace_back();
608 // _eventIds.push_back(0);
609 // _eventMap[EventLabel::nullLabel()] = nullEvent();
610 // return *this;
611 // }
612 //
613 // private:
614 //
615 // /**
616 // * Clear the manager, the manager is invalid
617 // */
618 // void
619 // clear()
620 // {
621 // _events.clear();
622 // _eventIds.clear();
623 // _eventMap.clear();
624 // }
625 //
626 // public:
627 // using EventIterator = typename std::vector<EventId>::const_iterator;
628 //
629 // /**
630 // *
631 // * @return an iterator on the first Event of the manager
632 // */
633 // EventIterator
634 // begin() const
635 // {
636 // return _eventIds.begin();
637 // }
638 //
639 // /**
640 // *
641 // * @return an iterator after the last Event of the manager
642 // */
643 // EventIterator
644 // end() const
645 // {
646 // return _eventIds.end();
647 // }
648 //
649 // /**
650 // *
651 // * @return the number of events (null event is included)
652 // */
653 // EventId
654 // numberOfEvents() const
655 // {
656 // return(EventId) _eventIds.size();
657 // }
658 //
659 // /**
660 // * Consistency checking
661 // * @param manager the manager to check with
662 // * @return true if the current manager is consistent with
663 // * the other one.
664 // *
665 // * @p consistency: a manager is consistent with another one
666 // * if any Event owned by the current manager is owned by
667 // * the other one with the same Label.
668 // */
669 // bool
670 // isConsistentWith(const EventManager & manager) const
671 // {
672 // if(numberOfEvents() > manager.numberOfEvents())
673 // {
674 // return false;
675 // }
676 // bool result = true;
677 // size_t index = 1;
678 // while(index < numberOfEvents())
679 // {
680 // result = (_events[index] == manager._events[index]);
681 // ++index;
682 // }
683 // return result;
684 // }
685 //
686 // /**
687 // * Equivalence checking
688 // * @param manager the manager to check with
689 // * @return true if the current manager is equivalent to
690 // * the other one.
691 // *
692 // * @p equivalence: a manager is equivalent to another one
693 // * if any Event owned by the current manager is owned by
694 // * the other one with the same Label and reciprocally
695 // */
696 // bool
697 // isEquivalentTo(const EventManager & manager) const
698 // {
699 // return isConsistentWith(manager) && manager.isConsistentWith(*this);
700 // }
701 //
702 // /**
703 // * Manager appending
704 // * @param manager the manage to append
705 // * @return the current EventManager that results from the appending
706 // * with the other one.
707 // *
708 // *
709 // * By appending, we mean that any Label of the manager in
710 // * parameter will be included in the current manager. However,
711 // * the Event of the current manager associated with a given Label
712 // * might not be (will certainly be not) the same as the Event
713 // * in the other manager.
714 // */
715 // EventManager &
716 // appendWith(const EventManager & manager)
717 // {
718 // if(this != &manager)
719 // {
720 // for(EventId evt = 1; evt < manager.numberOfEvents(); ++evt)
721 // {
722 // event(manager.getLabel(evt));
723 // }
724 // }
725 // return *this;
726 // }
727 //
728 // /**
729 // * Intersection of two EventManager's
730 // * @param m1 the first EventManager
731 // * @param m2 the second EventManager
732 // * @return the current EventManager.
733 // *
734 // * The current EventManager is the intersection of m1 and m2.
735 // * It means that the current EventManager consists of the Label
736 // * owned by both m1 and m2. The associated Event is obviously
737 // * different.
738 // */
739 // EventManager &
740 // makeIntersection(const EventManager & m1,
741 // const EventManager & m2)
742 // {
743 // if(&m1 == &m2)
744 // {
745 // if(this != &m1)
746 // {
747 // *this = m1;
748 // }
749 // return *this;
750 // }
751 //
752 // if(this == &m1)
753 // {
754 // EventManager tmp(*this);
755 // makeIntersection(tmp, m2);
756 // }
757 // else
758 // {
759 // if(this == &m2)
760 // {
761 // EventManager tmp(*this);
762 // makeIntersection(m1, tmp);
763 // }
764 // else
765 // {
766 // initialise(m1.numberOfEvents() + 1);
767 // for(size_t i = 1; i < m1.numberOfEvents(); ++i)
768 // {
769 // if(m2.hasEvent(m1.getLabel(i)))
770 // {
771 // event(m1.getLabel(i));
772 // }
773 // }
774 //
775 // }
776 // }
777 // return *this;
778 // }
779 //
780 // /**
781 // * Union of two EventManager's
782 // * @param m1 the first EventManager
783 // * @param m2 the second EventManager
784 // * @return the current EventManager.
785 // *
786 // * The current EventManager is the union of m1 and m2.
787 // * It means that the current EventManager consists of the Label
788 // * owned by at least one EventManager m1 or m2. The associated
789 // * Event is obviously different.
790 // */
791 // EventManager &
792 // makeUnion(const EventManager & m1,
793 // const EventManager & m2)
794 // {
795 // if(&m1 == &m2)
796 // {
797 // if(this != &m1)
798 // {
799 // *this = m1;
800 // }
801 // return *this;
802 // }
803 // if(this == &m1)
804 // {
805 // for(size_t i = 1; i < m2.numberOfEvents(); ++i)
806 // {
807 // if(!hasEvent(m2.getLabel(i)))
808 // {
809 // event(m2.getLabel(i));
810 // }
811 // }
812 // }
813 // else
814 // {
815 // if(this == &m2)
816 // {
817 //
818 // for(size_t i = 1; i < m1.numberOfEvents(); ++i)
819 // {
820 // if(!hasEvent(m1.getLabel(i)))
821 // {
822 // event(m1.getLabel(i));
823 // }
824 // }
825 //
826 //
827 //
828 // }
829 // else
830 // {
831 // *this = m1;
832 // appendWith(m2);
833 // }
834 //
835 // }
836 // return *this;
837 // }
838 //
839 // /**
840 // * Assign the current EventManager with all the events from
841 // * the other one. Each event has a label appended with a prefix
842 // * Note that the null event remains unmodified
843 // * @param mgr the EventManager to copy
844 // * @param prefix the prefix to add to any Event of mgr
845 // * @return the current EventManager
846 // */
847 // EventManager &
848 // assignWith(const EventManager & mgr,
849 // const Label & prefix)
850 // {
851 // initialise(mgr._events.capacity());
852 // for(auto & pair : mgr.map())
853 // {
854 // if(!mgr.isNull(pair.second))
855 // {
856 // event(EventLabel::appendLabel(prefix, pair.first));
857 // }
858 // }
859 // return *this;
860 // }
861 // };
862  }
863  }
864 }
865 
866 
867 
868 
869 
870 #endif /* EVENT_HH */
871 
bool hasEvent(const Event &event) const
Definition: Event.hh:128
EventId eventId(const Event &event)
Definition: Event.hh:170
bool setEvent(const Event &event, EventId id)
Definition: Event.hh:156
EventManager & operator=(EventManager const &other)=default
const Event & getEvent(EventId id) const
Definition: Event.hh:183
Namespace of the Diades project.
boost::format Msg
Definition: Verbose.hh:42