swift
metaclass.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2016 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_METACLASS_H
7 #define SWIFT_MISC_METACLASS_H
8 
9 #include <functional>
10 #include <type_traits>
11 
12 #include <QHash>
13 #include <QLatin1String>
14 #include <QString>
15 
16 #include "misc/invoke.h"
17 #include "misc/tuple.h"
18 
26 
27 // Work around MinGW problem with combination of constexpr and extern template
28 #if defined(Q_OS_WIN) && defined(Q_CC_GNU)
29 # define SWIFT_NO_EXPORT_CONSTEXPR constexpr inline __attribute__((always_inline))
30 #else
31 # define SWIFT_NO_EXPORT_CONSTEXPR constexpr
32 #endif
33 
34 // MSVC, GCC, Clang all have non-standard extensions for skipping trailing
35 // commas in variadic macros, but the MSVC extension differs from the others.
36 #ifdef Q_CC_MSVC
37 # define SWIFT_TRAILING_VA_ARGS(...) , __VA_ARGS__
38 #else
39 # define SWIFT_TRAILING_VA_ARGS(...) , ##__VA_ARGS__
40 #endif
41 
43 
44 // *INDENT-OFF*
53 #define SWIFT_METACLASS(CLASS, ...) \
54  friend struct swift::misc::private_ns::CMetaClassAccessor; \
55  struct MetaClass : public swift::misc::CMetaClass \
56  { \
57  using Class = CLASS; \
58  SWIFT_NO_EXPORT_CONSTEXPR static auto getMemberList() { return makeMetaMemberList(__VA_ARGS__); } \
59  }
60 
73 #define SWIFT_METAMEMBER(MEMBER, ...) makeMetaMember(&Class::m_##MEMBER, #MEMBER SWIFT_TRAILING_VA_ARGS(__VA_ARGS__))
74 
81 #define SWIFT_METAMEMBER_NAMED(MEMBER, NAME, ...) \
82  makeMetaMember(&Class::m_##MEMBER, NAME SWIFT_TRAILING_VA_ARGS(__VA_ARGS__))
83 // *INDENT-ON*
84 
86 inline size_t qHash(const std::string &key, uint seed) { return qHash(QString::fromStdString(key), seed); }
87 
89 inline size_t qHash(const std::string &key) { return qHash(QString::fromStdString(key)); }
90 
91 namespace swift::misc
92 {
93  class CVariant;
94 
102  {
104  const QLatin1String m_latin1;
105 
107  constexpr CExplicitLatin1String(QLatin1String s) : m_latin1(s) {}
108 
110  constexpr operator QLatin1String() const { return m_latin1; }
111  };
112 
117  template <quint64 F>
118  struct MetaFlags : public std::integral_constant<quint64, F>
119  {
121  constexpr operator std::bool_constant<static_cast<bool>(F)>() const { return {}; }
122  };
123 
128  template <quint64 A, quint64 B>
130  {
131  return {};
132  }
133 
138  template <quint64 A, quint64 B>
140  {
141  return {};
142  }
143 
148  template <typename M, quint64 Flags>
149  struct CMetaMember
150  {
152  const M m_ptr;
153 
155  const char *const m_name;
156 
159  const int m_index;
160 
163 
165  template <typename Flags2>
166  static constexpr bool has(Flags2 flags)
167  {
168  return (MetaFlags<Flags>() & flags) == flags;
169  }
170 
172  template <typename T, typename... Ts>
173  decltype(auto) in(T &&object, Ts &&...args) const
174  {
175  return std::invoke(m_ptr, std::forward<T>(object), std::forward<Ts>(args)...);
176  }
177 
179  constexpr auto latin1Name() const { return QLatin1String(m_name); }
180  };
181 
186  template <typename... Members>
188  {
190  const private_ns::tuple<Members...> m_members;
191 
193  static constexpr size_t c_size = sizeof...(Members);
194  };
195 
200  enum MetaFlag
201  {
206  DisabledForJson = 1 << 4,
209  RequiredForJson = 1 << 7
210  };
211 
218  {
219  protected:
231 
234  template <typename... Members>
235  constexpr static CMetaMemberList<Members...> makeMetaMemberList(Members... members)
236  {
237  return { { { { members }... } } };
238  }
239 
242  template <typename M, quint64 Flags = 0>
243  constexpr static CMetaMember<M, Flags> makeMetaMember(M ptrToMember, const char *name = nullptr, int index = 0,
244  MetaFlags<Flags> flags = {})
245  {
246  static_assert(std::is_member_object_pointer_v<M>, "M must be a pointer to member object");
247  return { ptrToMember, name, index, flags };
248  }
249  };
250 
256  template <typename MetaClass>
258  {
259  public:
261  template <typename F>
262  static void forEachMember(F &&visitor)
263  {
264  MetaClass::getMemberList().m_members.for_each(std::forward<F>(visitor));
265  }
266  };
267 
268  namespace private_ns
269  {
271  struct CMetaClassAccessor
272  {
273  template <typename T>
274  constexpr static auto getIntrospector()
275  {
276  return CMetaClassIntrospector<typename T::MetaClass>();
277  }
278  };
279  } // namespace private_ns
280 
286  template <typename T>
287  constexpr auto introspect()
288  {
289  return private_ns::CMetaClassAccessor::getIntrospector<T>();
290  }
291 
292 } // namespace swift::misc
293 
294 #endif // SWIFT_MISC_METACLASS_H
Base class for meta classes.
Definition: metaclass.h:218
constexpr static MetaFlags< MetaFlag::DisabledForComparison > DisabledForComparison
Flags wrapped as compile-time constants.
Definition: metaclass.h:222
constexpr static CMetaMemberList< Members... > makeMetaMemberList(Members... members)
Return a CMetaMemberList of type deduced from the types of the meta members. Usually not used directl...
Definition: metaclass.h:235
constexpr static MetaFlags< MetaFlag::DisabledForJson > DisabledForJson
Flags wrapped as compile-time constants.
Definition: metaclass.h:226
constexpr static CMetaMember< M, Flags > makeMetaMember(M ptrToMember, const char *name=nullptr, int index=0, MetaFlags< Flags > flags={})
Return a CMetaMethod of type deduced from the type of the member. Usually not used directly,...
Definition: metaclass.h:243
constexpr static MetaFlags< MetaFlag::RequiredForJson > RequiredForJson
Flags wrapped as compile-time constants.
Definition: metaclass.h:229
constexpr static MetaFlags< MetaFlag::DisabledForDebugging > DisabledForDebugging
Flags wrapped as compile-time constants.
Definition: metaclass.h:224
constexpr static MetaFlags< MetaFlag::CaseInsensitiveComparison > CaseInsensitiveComparison
Flags wrapped as compile-time constants.
Definition: metaclass.h:227
constexpr static MetaFlags< MetaFlag::LosslessMarshalling > LosslessMarshalling
Flags wrapped as compile-time constants.
Definition: metaclass.h:228
constexpr static MetaFlags< MetaFlag::DisabledForMarshalling > DisabledForMarshalling
Flags wrapped as compile-time constants.
Definition: metaclass.h:223
constexpr static MetaFlags< MetaFlag::DisabledForHashing > DisabledForHashing
Flags wrapped as compile-time constants.
Definition: metaclass.h:225
An introspector for a metaclass.
Definition: metaclass.h:258
static void forEachMember(F &&visitor)
For each metamember in metaclass, pass metamember as argument to visitor function.
Definition: metaclass.h:262
constexpr auto introspect()
Obtain the CMetaClassIntrospector for the metaclass of T.
Definition: metaclass.h:287
constexpr MetaFlags< A &B > operator&(MetaFlags< A >, MetaFlags< B >)
Compile-time intersection of MetaFlags.
Definition: metaclass.h:139
MetaFlag
Metadata flags attached to members of a meta class.
Definition: metaclass.h:201
constexpr MetaFlags< A|B > operator|(MetaFlags< A >, MetaFlags< B >)
Compile-time union of MetaFlags.
Definition: metaclass.h:129
@ CaseInsensitiveComparison
Element will be compared case insensitively (must be a QString)
Definition: metaclass.h:207
@ DisabledForComparison
Element will be ignored by compare() and comparison operators.
Definition: metaclass.h:202
@ LosslessMarshalling
Element marshalling will preserve data at the expense of size.
Definition: metaclass.h:208
@ RequiredForJson
Element is required when parsing from JSON.
Definition: metaclass.h:209
@ DisabledForJson
Element will be ignored during JSON serialization.
Definition: metaclass.h:206
@ DisabledForMarshalling
Element will be ignored during DBus and QDataStream marshalling.
Definition: metaclass.h:203
@ DisabledForHashing
Element will be ignored by qHash()
Definition: metaclass.h:205
@ DisabledForDebugging
Element will be ignored when streaming to QDebug.
Definition: metaclass.h:204
size_t qHash(const std::string &key, uint seed)
std::string qHash
Definition: metaclass.h:86
Free functions in swift::misc.
Simple literal type containing a single QLatin1String.
Definition: metaclass.h:102
const QLatin1String m_latin1
Embedded string.
Definition: metaclass.h:104
constexpr CExplicitLatin1String(QLatin1String s)
Implicit constructor.
Definition: metaclass.h:107
Literal aggregate type representing attributes of one member of a value class.
Definition: metaclass.h:150
const M m_ptr
Pointer to the member.
Definition: metaclass.h:152
decltype(auto) in(T &&object, Ts &&...args) const
Invoke the member on an instance of the value class.
Definition: metaclass.h:173
const char *const m_name
Member name.
Definition: metaclass.h:155
constexpr auto latin1Name() const
Return name as QLatin1String.
Definition: metaclass.h:179
const int m_index
Property index of the member.
Definition: metaclass.h:159
const MetaFlags< Flags > m_flags
Any flags applying to the member.
Definition: metaclass.h:162
static constexpr bool has(Flags2 flags)
True if m_flags contains all flags.
Definition: metaclass.h:166
Literal aggregate type representing attributes of the members of a value class.
Definition: metaclass.h:188
static constexpr size_t c_size
Number of members.
Definition: metaclass.h:193
const private_ns::tuple< Members... > m_members
Tuple of CMetaMember.
Definition: metaclass.h:190
Type wrapper for passing MetaFlag to CMetaMember::has.
Definition: metaclass.h:119