10 #include <type_traits>
12 #include <Poco/SharedPtr.h>
13 #include <Poco/Dynamic/Var.h>
14 #include <Poco/Timespan.h>
18 class DependencyInjector;
28 const std::type_info &method);
30 const char *what()
const noexcept
override;
43 const std::type_info &to);
45 const char *what()
const noexcept
override;
55 const char *what()
const noexcept
override;
68 virtual std::string id()
const = 0;
73 template <
typename T,
typename B>
83 std::string id()
const override
88 virtual void call(
DIWrapper &b,
const std::string &text) = 0;
91 template <
typename T,
typename B>
94 typedef void (B::*Setter)(
const std::string &);
101 void call(
DIWrapper &b,
const std::string &text)
override;
106 template <
typename T,
typename B>
109 typedef void (B::*Setter)(
const char);
116 void call(
DIWrapper &b,
const std::string &text)
override;
127 std::string id()
const override
132 virtual void call(
DIWrapper &b,
const Poco::Timespan &time) = 0;
135 template <
typename T,
typename B>
138 typedef void (B::*Setter)(
const Poco::Timespan &);
145 void call(
DIWrapper &b,
const Poco::Timespan &time)
override;
157 std::string id()
const override
162 virtual void call(
DIWrapper &b,
double value) = 0;
165 template <
typename T,
typename B>
168 typedef void (B::*Setter)(
int value);
175 void call(
DIWrapper &b,
double value)
override;
180 template <
typename T,
typename B>
183 typedef void (B::*Setter)(
double value);
190 void call(
DIWrapper &b,
double value)
override;
195 template <
typename T,
typename B>
198 typedef void (B::*Setter)(
bool value);
205 void call(
DIWrapper &b,
double value)
override;
216 std::string id()
const override
224 template <
typename I>
225 Poco::SharedPtr<I> extractTarget(
DIWrapper &i)
const;
231 template <
typename T,
typename B,
typename I>
234 typedef void (B::*Setter)(I *);
249 template <
typename T,
typename B,
typename I>
252 typedef void (B::*Setter)(Poco::SharedPtr<I>);
267 std::string id()
const override
272 virtual void call(
DIWrapper &b,
const std::list<Poco::Dynamic::Var> &l) = 0;
275 template <
typename T,
typename B>
278 typedef void (B::*Setter)(
const std::list<std::string> &);
285 void call(
DIWrapper &b,
const std::list<Poco::Dynamic::Var> &l)
override;
293 std::string id()
const override
299 const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &m) = 0;
302 template <
typename T,
typename B>
305 typedef void (B::*Setter)(
const std::map<std::string, std::string> &);
313 const std::map<Poco::Dynamic::Var, Poco::Dynamic::Var> &m)
override;
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;
330 static void add(
DIWCast *cast);
334 template <
typename From,
typename To>
336 bool wouldCast(
const std::type_info &info)
override;
338 void cast(
void *raw,
void *dest)
override;
341 std::is_base_of<To, From>::value,
342 "Invalid cast, there is no inheritance defined"
353 std::string id()
const override
364 template <
typename T,
typename B>
367 typedef void (B::*Hook)();
394 virtual void *
raw()
const = 0;
405 virtual const std::type_info &
type()
const = 0;
408 virtual void injectRef(
const std::string &name,
410 virtual void injectNumber(
const std::string &name,
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;
428 template <
typename T>
440 void *
raw()
const override;
442 const std::type_info &
type()
const override;
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;
454 template <
typename Setter,
typename Target>
455 void injectGeneric(
const std::string &name,
457 const std::string &property);
459 void callHook(
const std::string &name)
override;
460 bool hasHook(
const std::string &name)
const override;
462 template <
typename B,
typename I>
463 void setter(
const std::string &name,
void (B::*setter)(I *));
465 template <
typename B,
typename I>
466 void setter(
const std::string &name,
void (B::*setter)(Poco::SharedPtr<I>));
468 template <
typename B>
469 void setter(
const std::string &name,
void (B::*setter)(
int));
471 template <
typename B>
472 void setter(
const std::string &name,
void (B::*setter)(
double));
474 template <
typename B>
475 void setter(
const std::string &name,
void (B::*setter)(
bool));
477 template <
typename B>
478 void setter(
const std::string &name,
void (B::*setter)(
const std::string &));
480 template <
typename B>
481 void setter(
const std::string &name,
void (B::*setter)(
const char));
483 template <
typename B>
484 void setter(
const std::string &name,
void (B::*setter)(
const Poco::Timespan &));
486 template <
typename B>
487 void setter(
const std::string &name,
488 void (B::*setter)(
const std::list<std::string> &));
490 template <
typename B>
491 void setter(
const std::string &name,
492 void (B::*setter)(
const std::map<std::string, std::string> &));
494 template <
typename B>
495 void hookHandler(
const std::string &name,
void (B::*hook)());
505 Poco::SharedPtr<T> m_instance;
506 std::map<std::string, DIWMethodHelper *> m_method;
520 template <
typename T,
typename B>
524 std::is_same<B, T>::value
526 (std::is_polymorphic<T>::value && std::is_base_of<B, T>::value),
527 "Dynamic casting is impossible here"
531 Poco::SharedPtr<T> instance = wrapper.
instance();
532 return dynamic_cast<B &
>(*instance.get());
535 template <
typename T,
typename B>
538 B &base = extractInstance<T, B>(b);
539 (base.*m_setter)(text);
542 template <
typename T,
typename B>
543 void DIWCharSetter<T, B>::call(DIWrapper &b,
const std::string &text)
545 if (text.size() != 1)
546 throw DIWWrongInputException(
"expected a single character: " + text);
548 B &base = extractInstance<T, B>(b);
549 (base.*m_setter)(text.at(0));
552 template <
typename T,
typename B>
553 void DIWTimespanSetter<T, B>::call(DIWrapper &b,
const Poco::Timespan &time)
555 B &base = extractInstance<T, B>(b);
556 (base.*m_setter)(time);
559 template <
typename T,
typename B>
560 void DIWIntSetter<T, B>::call(DIWrapper &b,
double value)
562 B &base = extractInstance<T, B>(b);
565 throw DIWWrongInputException(
"too big integer value");
567 throw DIWWrongInputException(
"too small integer value");
568 if (((
double) ((
int) value)) != value)
569 throw DIWWrongInputException(
"given number is not an integer");
571 (base.*m_setter)((
int) value);
574 template <
typename T,
typename B>
575 void DIWDoubleSetter<T, B>::call(DIWrapper &b,
double value)
577 B &base = extractInstance<T, B>(b);
578 (base.*m_setter)(value);
581 template <
typename T,
typename B>
582 void DIWBoolSetter<T, B>::call(DIWrapper &b,
double value)
584 B &base = extractInstance<T, B>(b);
585 (base.*m_setter)(value != 0?
true :
false);
588 template <
typename I>
589 Poco::SharedPtr<I> DIWRefSetter::extractTarget(DIWrapper &i)
const
591 DIWCast *cast = DIWCast::find(
typeid(I), i);
593 throw DIWCastException(i.type(),
typeid(I));
595 Poco::SharedPtr<I> inject;
596 cast->cast(i.raw(),
reinterpret_cast<void *
>(&inject));
601 template <
typename T,
typename B,
typename I>
602 void DIWRawPtrSetter<T, B, I>::call(DIWrapper &b, DIWrapper &i)
604 B &base = extractInstance<T, B>(b);
605 Poco::SharedPtr<I> inject = extractTarget<I>(i);
606 (base.*m_setter)(inject.get());
609 template <
typename T,
typename B,
typename I>
610 void DIWSharedPtrSetter<T, B, I>::call(DIWrapper &b, DIWrapper &i)
612 B &base = extractInstance<T, B>(b);
613 Poco::SharedPtr<I> inject = extractTarget<I>(i);
614 (base.*m_setter)(inject);
617 template <
typename T,
typename B>
618 void DIWStringListSetter<T, B>::call(DIWrapper &b,
const std::list<Poco::Dynamic::Var> &l)
620 std::list<std::string> value;
622 value.push_back(v.toString());
624 B &base = extractInstance<T, B>(b);
625 (base.*m_setter)(value);
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)
632 std::map<std::string, std::string> value;
634 value.emplace(pair.first.toString(), pair.second.toString());
636 B &base = extractInstance<T, B>(b);
637 (base.*m_setter)(value);
643 template <
typename From,
typename To>
646 return typeid(To) == info;
652 template <
typename From,
typename To>
655 return wrapper.
type() ==
typeid(From);
665 template <
typename From,
typename To>
668 Poco::SharedPtr<From> *from =
reinterpret_cast<Poco::SharedPtr<From> *
>(raw);
669 Poco::SharedPtr<To> *to =
reinterpret_cast<Poco::SharedPtr<To> *
>(dest);
674 template <
typename T,
typename B>
677 B &base = extractInstance<T, B>(b);
681 template <
typename T>
682 AbstractDIWrapper<T>::AbstractDIWrapper():
687 template <
typename T>
688 AbstractDIWrapper<T>::~AbstractDIWrapper()
690 for (
auto s : m_method)
694 template <
typename T>
700 template <
typename T>
704 return reinterpret_cast<void *
>(&
self->m_instance);
707 template <
typename T>
710 return m_instance.referenceCount();
713 template <
typename T>
719 template <
typename T>
720 template <
typename Setter,
typename Target>
722 const std::string &name,
724 const std::string &property)
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 "
734 Setter *setter =
dynamic_cast<Setter *
>(entry->second);
735 if (setter == NULL) {
736 throw DIWWrongInputException(
737 "injecting property "
740 + entry->second->id());
743 setter->call(*
this, value);
746 template <
typename T>
747 void AbstractDIWrapper<T>::injectRef(
748 const std::string &name,
751 injectGeneric<DIWRefSetter>(name, wrapper,
"ref");
754 template <
typename T>
755 void AbstractDIWrapper<T>::injectNumber(
756 const std::string &name,
759 injectGeneric<DIWNumberSetter>(name, value,
"number");
762 template <
typename T>
763 void AbstractDIWrapper<T>::injectText(
764 const std::string &name,
765 const std::string &value)
767 injectGeneric<DIWTextSetter>(name, value,
"text");
770 template <
typename T>
771 void AbstractDIWrapper<T>::injectTime(
772 const std::string &name,
773 const Poco::Timespan &value)
775 injectGeneric<DIWTimeSetter>(name, value,
"time");
778 template <
typename T>
779 void AbstractDIWrapper<T>::injectList(
780 const std::string &name,
781 const std::list<Poco::Dynamic::Var> &value)
783 injectGeneric<DIWListSetter>(name, value,
"list");
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)
791 injectGeneric<DIWMapSetter>(name, value,
"map");
794 template <
typename T>
795 void AbstractDIWrapper<T>::callHook(
const std::string &name)
797 auto entry = m_method.find(name);
798 if (entry == m_method.end())
799 throw Poco::NotFoundException(
"no such hook " + name);
801 DIWHook &handler =
dynamic_cast<DIWHook &
>(*(entry->second));
805 template <
typename T>
806 bool AbstractDIWrapper<T>::hasHook(
const std::string &name)
const
808 return m_method.find(name) != m_method.end();
811 template <
typename T>
814 if (m_method.find(name) != m_method.end()) {
819 m_method[name] = helper;
822 template <
typename T>
template <
typename B,
typename I>
824 const std::string &name,
825 void (B::*setter)(I *))
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>))
835 installMethod(name,
new DIWSharedPtrSetter<T, B, I>(setter));
838 template <
typename T>
template <
typename B>
839 void AbstractDIWrapper<T>::setter(
840 const std::string &name,
841 void (B::*setter)(
int))
843 installMethod(name,
new DIWIntSetter<T, B>(setter));
846 template <
typename T>
template <
typename B>
847 void AbstractDIWrapper<T>::setter(
848 const std::string &name,
849 void (B::*setter)(
double))
851 installMethod(name,
new DIWDoubleSetter<T, B>(setter));
854 template <
typename T>
template <
typename B>
855 void AbstractDIWrapper<T>::setter(
856 const std::string &name,
857 void (B::*setter)(
bool))
859 installMethod(name,
new DIWBoolSetter<T, B>(setter));
862 template <
typename T>
template <
typename B>
863 void AbstractDIWrapper<T>::setter(
864 const std::string &name,
865 void (B::*setter)(
const std::string &))
867 installMethod(name,
new DIWStringSetter<T, B>(setter));
870 template <
typename T>
template <
typename B>
871 void AbstractDIWrapper<T>::setter(
872 const std::string &name,
873 void (B::*setter)(
const char))
875 installMethod(name,
new DIWCharSetter<T, B>(setter));
878 template <
typename T>
template <
typename B>
879 void AbstractDIWrapper<T>::setter(
880 const std::string &name,
881 void (B::*setter)(
const Poco::Timespan &))
883 installMethod(name,
new DIWTimespanSetter<T, B>(setter));
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> &))
891 installMethod(name,
new DIWStringListSetter<T, B>(setter));
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> &))
899 installMethod(name,
new DIWStringStringMapSetter<T, B>(setter));
902 template <
typename T>
template <
typename B>
903 void AbstractDIWrapper<T>::hookHandler(
904 const std::string &name,
907 installMethod(name,
new DIWHookHandler<T, B>(hook));
919 static void registerFactory(
922 static void listFactories(std::list<std::string> &names);
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__)
936 #define BEEEON_OBJECT_IMPL(name, type) \
937 class name##Factory : public BeeeOn::DIWrapperFactory { \
941 BeeeOn::DIWrapperFactory \
942 ::registerFactory(#type, *this);\
945 BeeeOn::DIWrapper *create() const override \
947 return new type##DIW; \
950 static name##Factory name##Factory;
952 #define BEEEON_WRAPPER(cls, wrapper) \
954 std::is_default_constructible<cls>::value, \
955 #cls " is missing a default constructor"); \
957 !std::is_polymorphic<cls>::value \
959 std::has_virtual_destructor<cls>::value, \
960 #cls " is missing a virtual destructor"); \
961 struct wrapper final : public AbstractDIWrapper<cls> { \
966 DIWCast::add(new DIWCastImpl<cls, cls>);
968 #define BEEEON_OBJECT_BEGIN1(cls) \
969 BEEEON_WRAPPER(cls, cls##DIW)
971 #define BEEEON_OBJECT_BEGIN2(ns1, cls) \
973 BEEEON_WRAPPER(cls, cls##DIW)
975 #define BEEEON_OBJECT_BEGIN3(ns1, ns2, cls) \
976 namespace ns1 { namespace ns2 { \
977 BEEEON_WRAPPER(cls, cls##DIW)
979 #define BEEEON_OBJECT_BEGIN4(ns1, ns2, ns3, cls) \
980 namespace ns1 { namespace ns2 { namespace ns3 { \
981 BEEEON_WRAPPER(cls, cls##DIW)
983 #define BEEEON_OBJECT_BEGIN(...) \
984 _BEEEON_VA_SELECT(BEEEON_OBJECT_BEGIN, __VA_ARGS__)
985 #define BEEEON_OBJECT_CASTABLE(to) \
987 !std::is_same<Self, to>::value, \
988 "Redundant cast to itself for " #to); \
990 std::is_base_of<to, Self>::value, \
991 "Cannot cast to " #to); \
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);
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);
1020 #define BEEEON_OBJECT_END1(cls) \
1023 BEEEON_OBJECT_IMPL(cls, cls)
1025 #define BEEEON_OBJECT_END2(ns1, cls) \
1029 BEEEON_OBJECT_IMPL(ns1##_##cls, ns1::cls)
1031 #define BEEEON_OBJECT_END3(ns1, ns2, cls) \
1035 BEEEON_OBJECT_IMPL(ns1##_##ns2##_##cls, ns1::ns2::cls)
1037 #define BEEEON_OBJECT_END4(ns1, ns2, ns3, cls) \
1041 BEEEON_OBJECT_IMPL(ns1##_##ns2##_##ns3##_##cls, ns1::ns2::ns3::cls)
1043 #define BEEEON_OBJECT_END(...) \
1044 _BEEEON_VA_SELECT(BEEEON_OBJECT_END, __VA_ARGS__)
virtual int referenceCount()=0
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