swift
mixindbus.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2014 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_MIXIN_MIXINDBUS_H
7 #define SWIFT_MISC_MIXIN_MIXINDBUS_H
8 
9 #include <type_traits>
10 
11 #include <QDBusArgument>
12 
13 #include "misc/dbus.h"
14 #include "misc/inheritancetraits.h"
15 #include "misc/metaclass.h"
16 #include "misc/typetraits.h"
17 
18 namespace swift::misc
19 {
20  class CEmpty;
21 
26  {};
27 
28  namespace mixin
29  {
37  template <class Derived, class...>
39  {
40  public:
42  friend const QDBusArgument &operator>>(const QDBusArgument &arg, Derived &obj)
43  {
44  arg.beginStructure();
45  obj.unmarshallFromDbus(arg);
46  arg.endStructure();
47  return arg;
48  }
49 
51  friend QDBusArgument &operator<<(QDBusArgument &arg, const Derived &obj)
52  {
53  arg.beginStructure();
54  obj.marshallToDbus(arg);
55  arg.endStructure();
56  return arg;
57  }
58  };
59  template <class Derived>
61  {};
62 
69  template <class Derived, class... Tags>
70  class DBusByMetaClass : public DBusOperators<Derived, Tags...>
71  {
72  public:
74  void marshallToDbus(QDBusArgument &arg, Tags...) const;
75 
77  void unmarshallFromDbus(const QDBusArgument &arg, Tags...);
78 
79  private:
80  const Derived *derived() const;
81  Derived *derived();
82 
83  template <typename T>
84  static void baseMarshall(const T *base, QDBusArgument &arg);
85  template <typename T>
86  static void baseUnmarshall(T *base, const QDBusArgument &arg);
87  static void baseMarshall(const void *, QDBusArgument &);
88  static void baseUnmarshall(void *, const QDBusArgument &);
89  static void baseMarshall(const CEmpty *, QDBusArgument &);
90  static void baseUnmarshall(CEmpty *, const QDBusArgument &);
91  };
92 
93  template <class Derived, class... Tags>
94  void DBusByMetaClass<Derived, Tags...>::marshallToDbus(QDBusArgument &arg, Tags...) const
95  {
96  baseMarshall(static_cast<const TBaseOfT<Derived> *>(derived()), arg);
97  introspect<Derived>().forEachMember([&, this](auto member) {
98  if constexpr (!decltype(member)::has(MetaFlags<DisabledForMarshalling>()))
99  {
100  const auto &value = member.in(*this->derived());
101  if constexpr (THasMarshallMethods<std::decay_t<decltype(value)>>::value)
102  {
103  if constexpr (member.has(MetaFlags<LosslessMarshalling>()))
104  {
105  value.marshallToDbus(arg, LosslessTag());
106  }
107  else { value.marshallToDbus(arg); }
108  }
109  else { arg << value; }
110  }
111  });
112  }
113 
114  template <class Derived, class... Tags>
115  void DBusByMetaClass<Derived, Tags...>::unmarshallFromDbus(const QDBusArgument &arg, Tags...)
116  {
117  baseUnmarshall(static_cast<TBaseOfT<Derived> *>(derived()), arg);
118  introspect<Derived>().forEachMember([&, this](auto member) {
119  if constexpr (!decltype(member)::has(MetaFlags<DisabledForMarshalling>()))
120  {
121  auto &value = member.in(*this->derived());
122  if constexpr (THasMarshallMethods<std::decay_t<decltype(value)>>::value)
123  {
124  if constexpr (member.has(MetaFlags<LosslessMarshalling>()))
125  {
126  value.unmarshallFromDbus(arg, LosslessTag());
127  }
128  else { value.unmarshallFromDbus(arg); }
129  }
130  else { arg >> value; }
131  }
132  });
133  }
134 
135  template <class Derived, class... Tags>
136  const Derived *DBusByMetaClass<Derived, Tags...>::derived() const
137  {
138  return static_cast<const Derived *>(this);
139  }
140 
141  template <class Derived, class... Tags>
142  Derived *DBusByMetaClass<Derived, Tags...>::derived()
143  {
144  return static_cast<Derived *>(this);
145  }
146 
147  template <class Derived, class... Tags>
148  template <typename T>
149  void DBusByMetaClass<Derived, Tags...>::baseMarshall(const T *base, QDBusArgument &arg)
150  {
151  base->marshallToDbus(arg, Tags()...);
152  }
153 
154  template <class Derived, class... Tags>
155  template <typename T>
156  void DBusByMetaClass<Derived, Tags...>::baseUnmarshall(T *base, const QDBusArgument &arg)
157  {
158  base->unmarshallFromDbus(arg, Tags()...);
159  }
160 
161  template <class Derived, class... Tags>
162  void DBusByMetaClass<Derived, Tags...>::baseMarshall(const void *, QDBusArgument &)
163  {}
164 
165  template <class Derived, class... Tags>
166  void DBusByMetaClass<Derived, Tags...>::baseUnmarshall(void *, const QDBusArgument &)
167  {}
168 
169  template <class Derived, class... Tags>
170  void DBusByMetaClass<Derived, Tags...>::baseMarshall(const CEmpty *, QDBusArgument &)
171  {}
172 
173  template <class Derived, class... Tags>
174  void DBusByMetaClass<Derived, Tags...>::baseUnmarshall(CEmpty *, const QDBusArgument &)
175  {}
176 
177  // *INDENT-OFF*
182 #define SWIFT_MISC_DECLARE_USING_MIXIN_DBUS(DERIVED, ...) \
183  using ::swift::misc::mixin::DBusByMetaClass<DERIVED SWIFT_TRAILING_VA_ARGS(__VA_ARGS__)>::marshallToDbus; \
184  using ::swift::misc::mixin::DBusByMetaClass<DERIVED SWIFT_TRAILING_VA_ARGS(__VA_ARGS__)>::unmarshallFromDbus;
185  // *INDENT-ON*
186 
187  } // namespace mixin
188 } // namespace swift::misc
189 
190 #endif // SWIFT_MISC_MIXIN_MIXINDBUS_H
Default base class for CValueObject.
Definition: valueobject.h:76
Tag type signifying overloaded marshalling methods that preserve data at the expense of size.
Definition: mixindbus.h:26
CRTP class template from which a derived class can inherit common methods dealing with marshalling in...
Definition: mixindbus.h:71
void marshallToDbus(QDBusArgument &arg, Tags...) const
Marshall without begin/endStructure, for when composed within another object.
Definition: mixindbus.h:94
void unmarshallFromDbus(const QDBusArgument &arg, Tags...)
Unmarshall without begin/endStructure, for when composed within another object.
Definition: mixindbus.h:115
CRTP class template which will generate marshalling operators for a derived class with its own marsha...
Definition: mixindbus.h:39
friend const QDBusArgument & operator>>(const QDBusArgument &arg, Derived &obj)
Unmarshalling operator >>, DBus to object.
Definition: mixindbus.h:42
friend QDBusArgument & operator<<(QDBusArgument &arg, const Derived &obj)
Marshalling operator <<, object to DBus.
Definition: mixindbus.h:51
Free functions in swift::misc.
typename TBaseOf< T >::type TBaseOfT
Alias for typename TBaseOf<T>::type.
Type wrapper for passing MetaFlag to CMetaMember::has.
Definition: metaclass.h:119
Trait which is true if T has methods marshallToDbus and unmarshallFromDbus.
Definition: typetraits.h:177