BeeeOn Gateway  v2020.3.1-2-g6f737dc
Platform to interconnect the IoT world
DIWrapper.h
1 #pragma once
2 
3 #include <climits>
4 #include <cmath>
5 #include <list>
6 #include <string>
7 #include <typeinfo>
8 #include <list>
9 #include <map>
10 #include <type_traits>
11 
12 #include <Poco/SharedPtr.h>
13 #include <Poco/Dynamic/Var.h>
14 #include <Poco/Timespan.h>
15 
16 namespace BeeeOn {
17 
18 class DependencyInjector;
19 class DIWrapper;
20 
25 class DIWDuplicateException final : public std::exception {
26 public:
27  DIWDuplicateException(const std::string &key,
28  const std::type_info &method);
29 
30  const char *what() const noexcept override;
31 
32 private:
33  std::string m_text;
34 };
35 
40 class DIWCastException final : public std::bad_cast {
41 public:
42  DIWCastException(const std::type_info &from,
43  const std::type_info &to);
44 
45  const char *what() const noexcept override;
46 
47 private:
48  std::string m_text;
49 };
50 
51 class DIWWrongInputException final : public std::exception {
52 public:
53  DIWWrongInputException(const std::string &text);
54 
55  const char *what() const noexcept override;
56 
57 private:
58  std::string m_text;
59 };
60 
66  virtual ~DIWMethodHelper();
67 
68  virtual std::string id() const = 0;
69 
73  template <typename T, typename B>
74  static B &extractInstance(DIWrapper &w);
75 };
76 
80 struct DIWTextSetter : public DIWMethodHelper {
81  virtual ~DIWTextSetter();
82 
83  std::string id() const override
84  {
85  return "text";
86  }
87 
88  virtual void call(DIWrapper &b, const std::string &text) = 0;
89 };
90 
91 template <typename T, typename B>
92 class DIWStringSetter final : public DIWTextSetter {
93 public:
94  typedef void (B::*Setter)(const std::string &);
95 
96  DIWStringSetter(Setter setter):
97  m_setter(setter)
98  {
99  }
100 
101  void call(DIWrapper &b, const std::string &text) override;
102 private:
103  Setter m_setter;
104 };
105 
106 template <typename T, typename B>
107 class DIWCharSetter final : public DIWTextSetter {
108 public:
109  typedef void (B::*Setter)(const char);
110 
111  DIWCharSetter(Setter setter):
112  m_setter(setter)
113  {
114  }
115 
116  void call(DIWrapper &b, const std::string &text) override;
117 private:
118  Setter m_setter;
119 };
120 
125  virtual ~DIWTimeSetter();
126 
127  std::string id() const override
128  {
129  return "time";
130  }
131 
132  virtual void call(DIWrapper &b, const Poco::Timespan &time) = 0;
133 };
134 
135 template <typename T, typename B>
136 class DIWTimespanSetter final : public DIWTimeSetter {
137 public:
138  typedef void (B::*Setter)(const Poco::Timespan &);
139 
140  DIWTimespanSetter(Setter setter):
141  m_setter(setter)
142  {
143  }
144 
145  void call(DIWrapper &b, const Poco::Timespan &time) override;
146 
147 private:
148  Setter m_setter;
149 };
150 
155  virtual ~DIWNumberSetter();
156 
157  std::string id() const override
158  {
159  return "number";
160  }
161 
162  virtual void call(DIWrapper &b, double value) = 0;
163 };
164 
165 template <typename T, typename B>
166 class DIWIntSetter final : public DIWNumberSetter {
167 public:
168  typedef void (B::*Setter)(int value);
169 
170  DIWIntSetter(Setter setter):
171  m_setter(setter)
172  {
173  }
174 
175  void call(DIWrapper &b, double value) override;
176 private:
177  Setter m_setter;
178 };
179 
180 template <typename T, typename B>
181 class DIWDoubleSetter final : public DIWNumberSetter {
182 public:
183  typedef void (B::*Setter)(double value);
184 
185  DIWDoubleSetter(Setter setter):
186  m_setter(setter)
187  {
188  }
189 
190  void call(DIWrapper &b, double value) override;
191 private:
192  Setter m_setter;
193 };
194 
195 template <typename T, typename B>
196 class DIWBoolSetter final : public DIWNumberSetter {
197 public:
198  typedef void (B::*Setter)(bool value);
199 
200  DIWBoolSetter(Setter setter):
201  m_setter(setter)
202  {
203  }
204 
205  void call(DIWrapper &b, double value) override;
206 private:
207  Setter m_setter;
208 };
209 
213 struct DIWRefSetter : public DIWMethodHelper {
214  virtual ~DIWRefSetter();
215 
216  std::string id() const override
217  {
218  return "ref";
219  }
220 
221  virtual void call(DIWrapper &b, DIWrapper &i) = 0;
222 
223 protected:
224  template <typename I>
225  Poco::SharedPtr<I> extractTarget(DIWrapper &i) const;
226 };
227 
231 template <typename T, typename B, typename I>
232 class DIWRawPtrSetter final : public DIWRefSetter {
233 public:
234  typedef void (B::*Setter)(I *);
235 
236  DIWRawPtrSetter(Setter setter):
237  m_setter(setter)
238  {
239  }
240 
241  void call(DIWrapper &b, DIWrapper &i) override;
242 private:
243  Setter m_setter;
244 };
245 
249 template <typename T, typename B, typename I>
250 class DIWSharedPtrSetter final : public DIWRefSetter {
251 public:
252  typedef void (B::*Setter)(Poco::SharedPtr<I>);
253 
254  DIWSharedPtrSetter(Setter setter):
255  m_setter(setter)
256  {
257  }
258 
259  void call(DIWrapper &b, DIWrapper &i) override;
260 private:
261  Setter m_setter;
262 };
263 
265  virtual ~DIWListSetter();
266 
267  std::string id() const override
268  {
269  return "list";
270  }
271 
272  virtual void call(DIWrapper &b, const std::list<Poco::Dynamic::Var> &l) = 0;
273 };
274 
275 template <typename T, typename B>
276 class DIWStringListSetter final : public DIWListSetter {
277 public:
278  typedef void (B::*Setter)(const std::list<std::string> &);
279 
280  DIWStringListSetter(Setter setter):
281  m_setter(setter)
282  {
283  }
284 
285  void call(DIWrapper &b, const std::list<Poco::Dynamic::Var> &l) override;
286 private:
287  Setter m_setter;
288 };
289 
290 struct DIWMapSetter : public DIWMethodHelper {
291  virtual ~DIWMapSetter();
292 
293  std::string id() const override
294  {
295  return "map";
296  }
297 
298  virtual void call(DIWrapper &b,
299  const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &m) = 0;
300 };
301 
302 template <typename T, typename B>
304 public:
305  typedef void (B::*Setter)(const std::map<std::string, std::string> &);
306 
307  DIWStringStringMapSetter(Setter setter):
308  m_setter(setter)
309  {
310  }
311 
312  void call(DIWrapper &b,
313  const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &m) override;
314 private:
315  Setter m_setter;
316 };
317 
324 struct DIWCast {
325  virtual ~DIWCast();
326  virtual bool wouldCast(const std::type_info &info) = 0;
327  virtual bool isSame(const DIWrapper &wrapper) = 0;
328  virtual void cast(void *raw, void *dest) = 0;
329 
330  static void add(DIWCast *cast);
331  static DIWCast *find(const std::type_info &info, const DIWrapper &wrapper);
332 };
333 
334 template <typename From, typename To>
335 struct DIWCastImpl final : public DIWCast {
336  bool wouldCast(const std::type_info &info) override;
337  bool isSame(const DIWrapper &wrapper) override;
338  void cast(void *raw, void *dest) override;
339 
340  static_assert(
341  std::is_base_of<To, From>::value,
342  "Invalid cast, there is no inheritance defined"
343  );
344 
345 };
346 
350 struct DIWHook : public DIWMethodHelper {
351  virtual ~DIWHook();
352 
353  std::string id() const override
354  {
355  return "hook";
356  }
357 
358  virtual void call(DIWrapper &b) = 0;
359 };
360 
364 template <typename T, typename B>
365 class DIWHookHandler final : public DIWHook {
366 public:
367  typedef void (B::*Hook)();
368 
369  DIWHookHandler(Hook hook):
370  m_hook(hook)
371  {
372  }
373 
374  void call(DIWrapper &b) override;
375 
376 private:
377  Hook m_hook;
378 };
379 
386 class DIWrapper {
387  friend DependencyInjector;
388 public:
389  virtual ~DIWrapper();
390 
394  virtual void *raw() const = 0;
395 
399  virtual int referenceCount() = 0;
400 
405  virtual const std::type_info &type() const = 0;
406 
407 protected:
408  virtual void injectRef(const std::string &name,
409  DIWrapper &wrapper) = 0;
410  virtual void injectNumber(const std::string &name,
411  double value) = 0;
412  virtual void injectText(const std::string &name,
413  const std::string &value) = 0;
414  virtual void injectTime(const std::string &name,
415  const Poco::Timespan &value) = 0;
416  virtual void injectList(const std::string &name,
417  const std::list<Poco::Dynamic::Var> &l) = 0;
418  virtual void injectMap(const std::string &name,
419  const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &l) = 0;
420  virtual void callHook(const std::string &name) = 0;
421  virtual bool hasHook(const std::string &name) const = 0;
422 };
423 
428 template <typename T>
429 class AbstractDIWrapper : public DIWrapper {
430  friend DependencyInjector;
431 public:
433  virtual ~AbstractDIWrapper();
434 
438  Poco::SharedPtr<T> instance();
439 
440  void *raw() const override;
441  int referenceCount() override;
442  const std::type_info &type() const override;
443 
444 protected:
445  void injectRef(const std::string &name, DIWrapper &wrapper) override;
446  void injectNumber(const std::string &name, double value) override;
447  void injectText(const std::string &name, const std::string &value) override;
448  void injectTime(const std::string &name, const Poco::Timespan &value) override;
449  void injectList(const std::string &name,
450  const std::list<Poco::Dynamic::Var> &l) override;
451  void injectMap(const std::string &name,
452  const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &m) override;
453 
454  template <typename Setter, typename Target>
455  void injectGeneric(const std::string &name,
456  Target &value,
457  const std::string &property);
458 
459  void callHook(const std::string &name) override;
460  bool hasHook(const std::string &name) const override;
461 
462  template <typename B, typename I>
463  void setter(const std::string &name, void (B::*setter)(I *));
464 
465  template <typename B, typename I>
466  void setter(const std::string &name, void (B::*setter)(Poco::SharedPtr<I>));
467 
468  template <typename B>
469  void setter(const std::string &name, void (B::*setter)(int));
470 
471  template <typename B>
472  void setter(const std::string &name, void (B::*setter)(double));
473 
474  template <typename B>
475  void setter(const std::string &name, void (B::*setter)(bool));
476 
477  template <typename B>
478  void setter(const std::string &name, void (B::*setter)(const std::string &));
479 
480  template <typename B>
481  void setter(const std::string &name, void (B::*setter)(const char));
482 
483  template <typename B>
484  void setter(const std::string &name, void (B::*setter)(const Poco::Timespan &));
485 
486  template <typename B>
487  void setter(const std::string &name,
488  void (B::*setter)(const std::list<std::string> &));
489 
490  template <typename B>
491  void setter(const std::string &name,
492  void (B::*setter)(const std::map<std::string, std::string> &));
493 
494  template <typename B>
495  void hookHandler(const std::string &name, void (B::*hook)());
496 
502  void installMethod(const std::string &name, DIWMethodHelper *helper);
503 
504 private:
505  Poco::SharedPtr<T> m_instance;
506  std::map<std::string, DIWMethodHelper *> m_method;
507 };
508 
520 template <typename T, typename B>
522 {
523  static_assert(
524  std::is_same<B, T>::value
525  ||
526  (std::is_polymorphic<T>::value && std::is_base_of<B, T>::value),
527  "Dynamic casting is impossible here"
528  );
529 
530  AbstractDIWrapper<T> &wrapper = dynamic_cast<AbstractDIWrapper<T> &>(w);
531  Poco::SharedPtr<T> instance = wrapper.instance();
532  return dynamic_cast<B &>(*instance.get());
533 }
534 
535 template <typename T, typename B>
536 void DIWStringSetter<T, B>::call(DIWrapper &b, const std::string &text)
537 {
538  B &base = extractInstance<T, B>(b);
539  (base.*m_setter)(text);
540 }
541 
542 template <typename T, typename B>
543 void DIWCharSetter<T, B>::call(DIWrapper &b, const std::string &text)
544 {
545  if (text.size() != 1)
546  throw DIWWrongInputException("expected a single character: " + text);
547 
548  B &base = extractInstance<T, B>(b);
549  (base.*m_setter)(text.at(0));
550 }
551 
552 template <typename T, typename B>
553 void DIWTimespanSetter<T, B>::call(DIWrapper &b, const Poco::Timespan &time)
554 {
555  B &base = extractInstance<T, B>(b);
556  (base.*m_setter)(time);
557 }
558 
559 template <typename T, typename B>
560 void DIWIntSetter<T, B>::call(DIWrapper &b, double value)
561 {
562  B &base = extractInstance<T, B>(b);
563 
564  if (value > INT_MAX)
565  throw DIWWrongInputException("too big integer value");
566  if (value < INT_MIN)
567  throw DIWWrongInputException("too small integer value");
568  if (((double) ((int) value)) != value)
569  throw DIWWrongInputException("given number is not an integer");
570 
571  (base.*m_setter)((int) value);
572 }
573 
574 template <typename T, typename B>
575 void DIWDoubleSetter<T, B>::call(DIWrapper &b, double value)
576 {
577  B &base = extractInstance<T, B>(b);
578  (base.*m_setter)(value);
579 }
580 
581 template <typename T, typename B>
582 void DIWBoolSetter<T, B>::call(DIWrapper &b, double value)
583 {
584  B &base = extractInstance<T, B>(b);
585  (base.*m_setter)(value != 0? true : false);
586 }
587 
588 template <typename I>
589 Poco::SharedPtr<I> DIWRefSetter::extractTarget(DIWrapper &i) const
590 {
591  DIWCast *cast = DIWCast::find(typeid(I), i);
592  if (cast == NULL)
593  throw DIWCastException(i.type(), typeid(I));
594 
595  Poco::SharedPtr<I> inject;
596  cast->cast(i.raw(), reinterpret_cast<void *>(&inject));
597 
598  return inject;
599 }
600 
601 template <typename T, typename B, typename I>
602 void DIWRawPtrSetter<T, B, I>::call(DIWrapper &b, DIWrapper &i)
603 {
604  B &base = extractInstance<T, B>(b);
605  Poco::SharedPtr<I> inject = extractTarget<I>(i);
606  (base.*m_setter)(inject.get());
607 }
608 
609 template <typename T, typename B, typename I>
610 void DIWSharedPtrSetter<T, B, I>::call(DIWrapper &b, DIWrapper &i)
611 {
612  B &base = extractInstance<T, B>(b);
613  Poco::SharedPtr<I> inject = extractTarget<I>(i);
614  (base.*m_setter)(inject);
615 }
616 
617 template <typename T, typename B>
618 void DIWStringListSetter<T, B>::call(DIWrapper &b, const std::list<Poco::Dynamic::Var> &l)
619 {
620  std::list<std::string> value;
621  for (auto &v : l)
622  value.push_back(v.toString());
623 
624  B &base = extractInstance<T, B>(b);
625  (base.*m_setter)(value);
626 }
627 
628 template <typename T, typename B>
629 void DIWStringStringMapSetter<T, B>::call(DIWrapper &b,
630  const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &m)
631 {
632  std::map<std::string, std::string> value;
633  for (auto &pair : m)
634  value.emplace(pair.first.toString(), pair.second.toString());
635 
636  B &base = extractInstance<T, B>(b);
637  (base.*m_setter)(value);
638 }
639 
643 template <typename From, typename To>
644 bool DIWCastImpl<From, To>::wouldCast(const std::type_info &info)
645 {
646  return typeid(To) == info;
647 }
648 
652 template <typename From, typename To>
654 {
655  return wrapper.type() == typeid(From);
656 }
657 
665 template <typename From, typename To>
666 void DIWCastImpl<From, To>::cast(void *raw, void *dest)
667 {
668  Poco::SharedPtr<From> *from = reinterpret_cast<Poco::SharedPtr<From> *>(raw);
669  Poco::SharedPtr<To> *to = reinterpret_cast<Poco::SharedPtr<To> *>(dest);
670 
671  *to = *from;
672 }
673 
674 template <typename T, typename B>
676 {
677  B &base = extractInstance<T, B>(b);
678  (base.*m_hook)();
679 }
680 
681 template <typename T>
682 AbstractDIWrapper<T>::AbstractDIWrapper():
683  m_instance(new T)
684 {
685 }
686 
687 template <typename T>
688 AbstractDIWrapper<T>::~AbstractDIWrapper()
689 {
690  for (auto s : m_method)
691  delete s.second;
692 }
693 
694 template <typename T>
695 Poco::SharedPtr<T> AbstractDIWrapper<T>::instance()
696 {
697  return m_instance;
698 }
699 
700 template <typename T>
702 {
703  auto *self = const_cast<AbstractDIWrapper<T> *>(this);
704  return reinterpret_cast<void *>(&self->m_instance);
705 }
706 
707 template <typename T>
709 {
710  return m_instance.referenceCount();
711 }
712 
713 template <typename T>
714 const std::type_info &AbstractDIWrapper<T>::type() const
715 {
716  return typeid(T);
717 }
718 
719 template <typename T>
720 template <typename Setter, typename Target>
722  const std::string &name,
723  Target &value,
724  const std::string &property)
725 {
726  auto entry = m_method.find(name);
727  if (entry == m_method.end()) {
728  throw Poco::NotFoundException("missing "
729  + property + " property "
730  + name + " for type "
731  + typeid(T).name());
732  }
733 
734  Setter *setter = dynamic_cast<Setter *>(entry->second);
735  if (setter == NULL) {
736  throw DIWWrongInputException(
737  "injecting property "
738  + property
739  + " via method "
740  + entry->second->id());
741  }
742 
743  setter->call(*this, value);
744 }
745 
746 template <typename T>
747 void AbstractDIWrapper<T>::injectRef(
748  const std::string &name,
749  DIWrapper &wrapper)
750 {
751  injectGeneric<DIWRefSetter>(name, wrapper, "ref");
752 }
753 
754 template <typename T>
755 void AbstractDIWrapper<T>::injectNumber(
756  const std::string &name,
757  double value)
758 {
759  injectGeneric<DIWNumberSetter>(name, value, "number");
760 }
761 
762 template <typename T>
763 void AbstractDIWrapper<T>::injectText(
764  const std::string &name,
765  const std::string &value)
766 {
767  injectGeneric<DIWTextSetter>(name, value, "text");
768 }
769 
770 template <typename T>
771 void AbstractDIWrapper<T>::injectTime(
772  const std::string &name,
773  const Poco::Timespan &value)
774 {
775  injectGeneric<DIWTimeSetter>(name, value, "time");
776 }
777 
778 template <typename T>
779 void AbstractDIWrapper<T>::injectList(
780  const std::string &name,
781  const std::list<Poco::Dynamic::Var> &value)
782 {
783  injectGeneric<DIWListSetter>(name, value, "list");
784 }
785 
786 template <typename T>
787 void AbstractDIWrapper<T>::injectMap(
788  const std::string &name,
789  const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &value)
790 {
791  injectGeneric<DIWMapSetter>(name, value, "map");
792 }
793 
794 template <typename T>
795 void AbstractDIWrapper<T>::callHook(const std::string &name)
796 {
797  auto entry = m_method.find(name);
798  if (entry == m_method.end())
799  throw Poco::NotFoundException("no such hook " + name);
800 
801  DIWHook &handler = dynamic_cast<DIWHook &>(*(entry->second));
802  handler.call(*this);
803 }
804 
805 template <typename T>
806 bool AbstractDIWrapper<T>::hasHook(const std::string &name) const
807 {
808  return m_method.find(name) != m_method.end();
809 }
810 
811 template <typename T>
812 void AbstractDIWrapper<T>::installMethod(const std::string &name, DIWMethodHelper *helper)
813 {
814  if (m_method.find(name) != m_method.end()) {
815  delete helper;
816  throw DIWDuplicateException(name, typeid(*helper));
817  }
818 
819  m_method[name] = helper;
820 }
821 
822 template <typename T> template <typename B, typename I>
824  const std::string &name,
825  void (B::*setter)(I *))
826 {
827  installMethod(name, new DIWRawPtrSetter<T, B, I>(setter));
828 }
829 
830 template <typename T> template <typename B, typename I>
831 void AbstractDIWrapper<T>::setter(
832  const std::string &name,
833  void (B::*setter)(Poco::SharedPtr<I>))
834 {
835  installMethod(name, new DIWSharedPtrSetter<T, B, I>(setter));
836 }
837 
838 template <typename T> template <typename B>
839 void AbstractDIWrapper<T>::setter(
840  const std::string &name,
841  void (B::*setter)(int))
842 {
843  installMethod(name, new DIWIntSetter<T, B>(setter));
844 }
845 
846 template <typename T> template <typename B>
847 void AbstractDIWrapper<T>::setter(
848  const std::string &name,
849  void (B::*setter)(double))
850 {
851  installMethod(name, new DIWDoubleSetter<T, B>(setter));
852 }
853 
854 template <typename T> template <typename B>
855 void AbstractDIWrapper<T>::setter(
856  const std::string &name,
857  void (B::*setter)(bool))
858 {
859  installMethod(name, new DIWBoolSetter<T, B>(setter));
860 }
861 
862 template <typename T> template <typename B>
863 void AbstractDIWrapper<T>::setter(
864  const std::string &name,
865  void (B::*setter)(const std::string &))
866 {
867  installMethod(name, new DIWStringSetter<T, B>(setter));
868 }
869 
870 template <typename T> template <typename B>
871 void AbstractDIWrapper<T>::setter(
872  const std::string &name,
873  void (B::*setter)(const char))
874 {
875  installMethod(name, new DIWCharSetter<T, B>(setter));
876 }
877 
878 template <typename T> template <typename B>
879 void AbstractDIWrapper<T>::setter(
880  const std::string &name,
881  void (B::*setter)(const Poco::Timespan &))
882 {
883  installMethod(name, new DIWTimespanSetter<T, B>(setter));
884 }
885 
886 template <typename T> template <typename B>
887 void AbstractDIWrapper<T>::setter(
888  const std::string &name,
889  void (B::*setter)(const std::list<std::string> &))
890 {
891  installMethod(name, new DIWStringListSetter<T, B>(setter));
892 }
893 
894 template <typename T> template <typename B>
895 void AbstractDIWrapper<T>::setter(
896  const std::string &name,
897  void (B::*setter)(const std::map<std::string, std::string> &))
898 {
899  installMethod(name, new DIWStringStringMapSetter<T, B>(setter));
900 }
901 
902 template <typename T> template <typename B>
903 void AbstractDIWrapper<T>::hookHandler(
904  const std::string &name,
905  void (B::*hook)())
906 {
907  installMethod(name, new DIWHookHandler<T, B>(hook));
908 }
909 
916 public:
917  virtual DIWrapper *create() const = 0;
918 
919  static void registerFactory(
920  const std::string &name, DIWrapperFactory &factory);
921  static DIWrapperFactory &lookupFactory(const std::string &name);
922  static void listFactories(std::list<std::string> &names);
923 };
924 
925 #define _BEEEON_VA_EXPAND(x) x
926 #define _BEEEON_VA_COUNT_HELPER(_1, _2, _3, _4, _5, _6, _count, ...) _count
927 #define _BEEEON_VA_COUNT(...) \
928  _BEEEON_VA_EXPAND(_BEEEON_VA_COUNT_HELPER(__VA_ARGS__, 6, 5, 4, 3, 2, 1))
929 #define _BEEEON_VA_SELECT_CAT(name, count, ...)\
930  _BEEEON_VA_EXPAND(name##count(__VA_ARGS__))
931 #define _BEEEON_VA_SELECT_HELPER(name, count, ...) \
932  _BEEEON_VA_SELECT_CAT(name, count, __VA_ARGS__)
933 #define _BEEEON_VA_SELECT(name, ...) \
934  _BEEEON_VA_SELECT_HELPER(name, _BEEEON_VA_COUNT(__VA_ARGS__), __VA_ARGS__)
935 
936 #define BEEEON_OBJECT_IMPL(name, type) \
937 class name##Factory : public BeeeOn::DIWrapperFactory { \
938 public: \
939  name##Factory() \
940  { \
941  BeeeOn::DIWrapperFactory \
942  ::registerFactory(#type, *this);\
943  } \
944  \
945  BeeeOn::DIWrapper *create() const override \
946  { \
947  return new type##DIW; \
948  } \
949 }; \
950 static name##Factory name##Factory;
951 
952 #define BEEEON_WRAPPER(cls, wrapper) \
953  static_assert( \
954  std::is_default_constructible<cls>::value, \
955  #cls " is missing a default constructor"); \
956  static_assert( \
957  !std::is_polymorphic<cls>::value \
958  || \
959  std::has_virtual_destructor<cls>::value, \
960  #cls " is missing a virtual destructor"); \
961  struct wrapper final : public AbstractDIWrapper<cls> { \
962  friend cls; \
963  using Self = cls; \
964  wrapper() \
965  { \
966  DIWCast::add(new DIWCastImpl<cls, cls>);
967 
968 #define BEEEON_OBJECT_BEGIN1(cls) \
969 BEEEON_WRAPPER(cls, cls##DIW)
970 
971 #define BEEEON_OBJECT_BEGIN2(ns1, cls) \
972 namespace ns1 { \
973 BEEEON_WRAPPER(cls, cls##DIW)
974 
975 #define BEEEON_OBJECT_BEGIN3(ns1, ns2, cls) \
976 namespace ns1 { namespace ns2 { \
977 BEEEON_WRAPPER(cls, cls##DIW)
978 
979 #define BEEEON_OBJECT_BEGIN4(ns1, ns2, ns3, cls) \
980 namespace ns1 { namespace ns2 { namespace ns3 { \
981 BEEEON_WRAPPER(cls, cls##DIW)
982 
983 #define BEEEON_OBJECT_BEGIN(...) \
984  _BEEEON_VA_SELECT(BEEEON_OBJECT_BEGIN, __VA_ARGS__)
985 #define BEEEON_OBJECT_CASTABLE(to) \
986  static_assert( \
987  !std::is_same<Self, to>::value, \
988  "Redundant cast to itself for " #to); \
989  static_assert( \
990  std::is_base_of<to, Self>::value, \
991  "Cannot cast to " #to); \
992  static_assert( \
993  std::has_virtual_destructor<to>::value, \
994  #to " is missing a virtual destructor");\
995  DIWCast::add(new DIWCastImpl<Self, to>);
996 #define BEEEON_OBJECT_PROPERTY(name, method) \
997  setter(name, method);
998 
999 #define BEEEON_OBJECT_REF(name, method) \
1000  _Pragma ("GCC warning \"'BEEEON_OBJECT_REF' macro is deprecated\"") \
1001  BEEEON_OBJECT_PROPERTY(name, method)
1002 #define BEEEON_OBJECT_NUMBER(name, method) \
1003  _Pragma ("GCC warning \"'BEEEON_OBJECT_NUMBER' macro is deprecated\"") \
1004  BEEEON_OBJECT_PROPERTY(name, method)
1005 #define BEEEON_OBJECT_TEXT(name, method) \
1006  _Pragma ("GCC warning \"'BEEEON_OBJECT_TEXT' macro is deprecated\"") \
1007  BEEEON_OBJECT_PROPERTY(name, method)
1008 #define BEEEON_OBJECT_TIME(name, method) \
1009  _Pragma ("GCC warning \"'BEEEON_OBJECT_TIME' macro is deprecated\"") \
1010  BEEEON_OBJECT_PROPERTY(name, method)
1011 #define BEEEON_OBJECT_LIST(name, method) \
1012  _Pragma ("GCC warning \"'BEEEON_OBJECT_LIST' macro is deprecated\"") \
1013  BEEEON_OBJECT_PROPERTY(name, method)
1014 #define BEEEON_OBJECT_MAP(name, method) \
1015  _Pragma ("GCC warning \"'BEEEON_OBJECT_MAP' macro is deprecated\"") \
1016  BEEEON_OBJECT_PROPERTY(name, method)
1017 #define BEEEON_OBJECT_HOOK(name, method) \
1018  hookHandler(name, method);
1019 
1020 #define BEEEON_OBJECT_END1(cls) \
1021  } \
1022  }; \
1023 BEEEON_OBJECT_IMPL(cls, cls)
1024 
1025 #define BEEEON_OBJECT_END2(ns1, cls) \
1026  } \
1027  }; \
1028 } \
1029 BEEEON_OBJECT_IMPL(ns1##_##cls, ns1::cls)
1030 
1031 #define BEEEON_OBJECT_END3(ns1, ns2, cls) \
1032  } \
1033  }; \
1034 }} \
1035 BEEEON_OBJECT_IMPL(ns1##_##ns2##_##cls, ns1::ns2::cls)
1036 
1037 #define BEEEON_OBJECT_END4(ns1, ns2, ns3, cls) \
1038  } \
1039  }; \
1040 }}} \
1041 BEEEON_OBJECT_IMPL(ns1##_##ns2##_##ns3##_##cls, ns1::ns2::ns3::cls)
1042 
1043 #define BEEEON_OBJECT_END(...) \
1044  _BEEEON_VA_SELECT(BEEEON_OBJECT_END, __VA_ARGS__)
1045 
1046 }
virtual int referenceCount()=0
Definition: DIWrapper.h:51
int referenceCount() override
Definition: DIWrapper.h:708
Definition: DIWrapper.h:915
Definition: DIWrapper.h:429
Definition: DependencyInjector.h:110
Definition: DIWrapper.h:124
bool isSame(const DIWrapper &wrapper) override
Definition: DIWrapper.h:653
virtual void * raw() const =0
Definition: DIWrapper.h:232
Definition: DIWrapper.h:80
Definition: DIWrapper.h:25
Definition: DIWrapper.h:213
Definition: DIWrapper.h:92
Definition: DIWrapper.h:386
void * raw() const override
Definition: DIWrapper.h:701
virtual const std::type_info & type() const =0
Definition: DIWrapper.h:196
Definition: DIWrapper.h:324
Definition: DIWrapper.h:181
void cast(void *raw, void *dest) override
Definition: DIWrapper.h:666
Definition: DIWrapper.h:107
Poco::SharedPtr< T > instance()
Definition: DIWrapper.h:695
bool wouldCast(const std::type_info &info) override
Definition: DIWrapper.h:644
Definition: DIWrapper.h:276
Definition: DIWrapper.h:40
Definition: DIWrapper.h:350
Definition: DIWrapper.h:154
Definition: DIWrapper.h:65
Definition: DIWrapper.h:166
Definition: DIWrapper.h:335
Definition: DIWrapper.h:365
void installMethod(const std::string &name, DIWMethodHelper *helper)
Definition: DIWrapper.h:812
Definition: DIWrapper.h:303
Definition: DIWrapper.h:290
Definition: DIWrapper.h:136
Definition: DIWrapper.h:264
Definition: DIWrapper.h:250
static B & extractInstance(DIWrapper &w)
Definition: DIWrapper.h:521
const std::type_info & type() const override
Definition: DIWrapper.h:714