QtMvvm  1.1.0
A mvvm oriented library for Qt, to create Projects for Widgets and Quick in parallel
qtmvvmcore_helpertypes.h
1 #ifndef QTMVVMCORE_HELPERTYPES_H
2 #define QTMVVMCORE_HELPERTYPES_H
3 
4 #include <type_traits>
5 #include <tuple>
6 #include <functional>
7 
8 #include <QtCore/qobject.h>
9 #include <QtCore/qbytearray.h>
10 #include <QtCore/qvariant.h>
11 
12 namespace QtMvvm {
13 namespace __helpertypes {
14 
15 static const QByteArray InjectablePrefix = QByteArrayLiteral("de.skycoder42.qtmvvm.injectable.");
16 
17 template <typename T>
18 struct is_qobj : public std::is_base_of<QObject, T> {};
19 
20 template <typename T>
21 struct is_qobj_ptr : public is_qobj<std::remove_pointer_t<T>> {};
22 
23 template <typename TInterface, typename TService>
24 struct is_valid_interface : public std::integral_constant<bool, std::is_base_of<TInterface, TService>::value && is_qobj<TService>::value> {};
25 
26 template <typename TInjectPtr>
27 inline QByteArray qobject_iid(std::enable_if_t<is_qobj_ptr<TInjectPtr>::value, void*> = nullptr) {
28  return InjectablePrefix + std::remove_pointer_t<TInjectPtr>::staticMetaObject.className();
29 }
30 
31 template <typename TInjectPtr>
32 inline QByteArray qobject_iid(std::enable_if_t<!is_qobj_ptr<TInjectPtr>::value, void*> = nullptr) {
33  Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid injection type");
34  return "";
35 }
36 
37 template <typename TInjectPtr>
38 inline QByteArray inject_iid() {
39  auto iid = qobject_interface_iid<TInjectPtr>();
40  if(iid)
41  return iid;
42  else
43  return qobject_iid<TInjectPtr>();
44 }
45 
46 template <typename TFunc, typename T1, typename... TArgs>
47 inline std::function<QObject*(QObjectList)> pack_function_imp(TFunc fn, QByteArrayList &injectables);
48 template <typename TFunc>
49 inline std::function<QObject*(QObjectList)> pack_function_imp(TFunc fn, QByteArrayList &injectables);
50 
51 template <typename TFunc, typename T1, typename... TArgs>
52 inline std::function<QObject*(QObjectList)> pack_function_imp(TFunc fn, QByteArrayList &injectables) {
53  injectables.append(inject_iid<T1>());
54  auto subFn = [fn](const QObjectList &params, int index, TArgs... tArgs) {
55  --index;
56  return fn(params, index, qobject_cast<T1>(params[index]), tArgs...);
57  };
58  return pack_function_imp<decltype(subFn), TArgs...>(std::move(subFn), injectables);
59 }
60 
61 template <typename TFunc>
62 inline std::function<QObject*(QObjectList)> pack_function_imp(TFunc fn, QByteArrayList &injectables) {
63  Q_UNUSED(injectables)
64  return [fn](const QObjectList &params) {
65  return fn(params, params.size());
66  };
67 }
68 
69 template <typename T>
70 struct fn_info : public fn_info<decltype(&T::operator())> {};
71 
72 template <typename TClass, typename TRet, typename... TArgs>
73 struct fn_info<TRet(TClass::*)(TArgs...) const>
74 {
75  template <typename TFunctor>
76  static inline std::function<QObject*(QObjectList)> pack(TFunctor fn, QByteArrayList &injectables) {
77  auto subFn = [fn](const QObjectList &params, int index, TArgs... args) -> QObject* {
78  Q_UNUSED(params)
79  Q_ASSERT_X(index == 0, Q_FUNC_INFO, "number of params does not equal recursion depth");
80  return fn(args...);
81  };
82  return pack_function_imp<decltype(subFn), TArgs...>(std::move(subFn), injectables);
83  }
84 };
85 
86 template <typename TFunc>
87 inline std::function<QObject*(QObjectList)> pack_function(TFunc fn, QByteArrayList &injectables) {
88  return fn_info<TFunc>::pack(std::move(fn), injectables);
89 }
90 
91 
92 }
93 }
94 
95 #endif // QTMVVMCORE_HELPERTYPES_H
void append(const T &value)
The primary namespace of the QtMvvm library.