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 
52 #define SWIFT_METACLASS(CLASS, ...) \
53  friend struct swift::misc::private_ns::CMetaClassAccessor; \
54  struct MetaClass : public swift::misc::CMetaClass \
55  { \
56  using Class = CLASS; \
57  SWIFT_NO_EXPORT_CONSTEXPR static auto getMemberList() { return makeMetaMemberList(__VA_ARGS__); } \
58  }
59 
72 #define SWIFT_METAMEMBER(MEMBER, ...) makeMetaMember(&Class::m_##MEMBER, #MEMBER SWIFT_TRAILING_VA_ARGS(__VA_ARGS__))
73 
80 #define SWIFT_METAMEMBER_NAMED(MEMBER, NAME, ...) \
81  makeMetaMember(&Class::m_##MEMBER, NAME SWIFT_TRAILING_VA_ARGS(__VA_ARGS__))
82 
84 inline size_t qHash(const std::string &key, uint seed) { return qHash(QString::fromStdString(key), seed); }
85 
87 inline size_t qHash(const std::string &key) { return qHash(QString::fromStdString(key)); }
88 
89 namespace swift::misc
90 {
91  class CVariant;
92 
100  {
103 
106 
108  constexpr operator QLatin1String() const { return m_latin1; }
109  };
110 
115  template <quint64 F>
116  struct MetaFlags : public std::integral_constant<quint64, F>
117  {
119  constexpr operator std::bool_constant<static_cast<bool>(F)>() const { return {}; }
120  };
121 
126  template <quint64 A, quint64 B>
128  {
129  return {};
130  }
131 
136  template <quint64 A, quint64 B>
138  {
139  return {};
140  }
141 
146  template <typename M, quint64 Flags>
147  struct CMetaMember
148  {
150  const M m_ptr;
151 
153  const char *const m_name;
154 
157  const int m_index;
158 
161 
163  template <typename Flags2>
164  static constexpr bool has(Flags2 flags)
165  {
166  return (MetaFlags<Flags>() & flags) == flags;
167  }
168 
170  template <typename T, typename... Ts>
171  decltype(auto) in(T &&object, Ts &&...args) const
172  {
173  return std::invoke(m_ptr, std::forward<T>(object), std::forward<Ts>(args)...);
174  }
175 
177  constexpr auto latin1Name() const { return QLatin1String(m_name); }
178  };
179 
184  template <typename... Members>
186  {
188  const private_ns::tuple<Members...> m_members;
189 
191  static constexpr size_t c_size = sizeof...(Members);
192  };
193 
198  enum MetaFlag
199  {
204  DisabledForJson = 1 << 4,
207  RequiredForJson = 1 << 7
208  };
209 
216  {
217  protected:
229 
232  template <typename... Members>
233  constexpr static CMetaMemberList<Members...> makeMetaMemberList(Members... members)
234  {
235  return { { { { members }... } } };
236  }
237 
240  template <typename M, quint64 Flags = 0>
241  constexpr static CMetaMember<M, Flags> makeMetaMember(M ptrToMember, const char *name = nullptr, int index = 0,
242  MetaFlags<Flags> flags = {})
243  {
244  static_assert(std::is_member_object_pointer_v<M>, "M must be a pointer to member object");
245  return { ptrToMember, name, index, flags };
246  }
247  };
248 
254  template <typename MetaClass>
256  {
257  public:
259  template <typename F>
260  static void forEachMember(F &&visitor)
261  {
262  MetaClass::getMemberList().m_members.for_each(std::forward<F>(visitor));
263  }
264  };
265 
266  namespace private_ns
267  {
269  struct CMetaClassAccessor
270  {
271  template <typename T>
272  constexpr static auto getIntrospector()
273  {
274  return CMetaClassIntrospector<typename T::MetaClass>();
275  }
276  };
277  } // namespace private_ns
278 
284  template <typename T>
285  constexpr auto introspect()
286  {
287  return private_ns::CMetaClassAccessor::getIntrospector<T>();
288  }
289 
290 } // namespace swift::misc
291 
292 #endif // SWIFT_MISC_METACLASS_H
Base class for meta classes.
Definition: metaclass.h:216
constexpr static MetaFlags< MetaFlag::DisabledForComparison > DisabledForComparison
Flags wrapped as compile-time constants.
Definition: metaclass.h:220
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:233
constexpr static MetaFlags< MetaFlag::DisabledForJson > DisabledForJson
Flags wrapped as compile-time constants.
Definition: metaclass.h:224
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:241
constexpr static MetaFlags< MetaFlag::RequiredForJson > RequiredForJson
Flags wrapped as compile-time constants.
Definition: metaclass.h:227
constexpr static MetaFlags< MetaFlag::DisabledForDebugging > DisabledForDebugging
Flags wrapped as compile-time constants.
Definition: metaclass.h:222
constexpr static MetaFlags< MetaFlag::CaseInsensitiveComparison > CaseInsensitiveComparison
Flags wrapped as compile-time constants.
Definition: metaclass.h:225
constexpr static MetaFlags< MetaFlag::LosslessMarshalling > LosslessMarshalling
Flags wrapped as compile-time constants.
Definition: metaclass.h:226
constexpr static MetaFlags< MetaFlag::DisabledForMarshalling > DisabledForMarshalling
Flags wrapped as compile-time constants.
Definition: metaclass.h:221
constexpr static MetaFlags< MetaFlag::DisabledForHashing > DisabledForHashing
Flags wrapped as compile-time constants.
Definition: metaclass.h:223
An introspector for a metaclass.
Definition: metaclass.h:256
static void forEachMember(F &&visitor)
For each metamember in metaclass, pass metamember as argument to visitor function.
Definition: metaclass.h:260
constexpr auto introspect()
Obtain the CMetaClassIntrospector for the metaclass of T.
Definition: metaclass.h:285
constexpr MetaFlags< A &B > operator&(MetaFlags< A >, MetaFlags< B >)
Compile-time intersection of MetaFlags.
Definition: metaclass.h:137
MetaFlag
Metadata flags attached to members of a meta class.
Definition: metaclass.h:199
constexpr MetaFlags< A|B > operator|(MetaFlags< A >, MetaFlags< B >)
Compile-time union of MetaFlags.
Definition: metaclass.h:127
@ CaseInsensitiveComparison
Element will be compared case insensitively (must be a QString)
Definition: metaclass.h:205
@ DisabledForComparison
Element will be ignored by compare() and comparison operators.
Definition: metaclass.h:200
@ LosslessMarshalling
Element marshalling will preserve data at the expense of size.
Definition: metaclass.h:206
@ RequiredForJson
Element is required when parsing from JSON.
Definition: metaclass.h:207
@ DisabledForJson
Element will be ignored during JSON serialization.
Definition: metaclass.h:204
@ DisabledForMarshalling
Element will be ignored during DBus and QDataStream marshalling.
Definition: metaclass.h:201
@ DisabledForHashing
Element will be ignored by qHash()
Definition: metaclass.h:203
@ DisabledForDebugging
Element will be ignored when streaming to QDebug.
Definition: metaclass.h:202
size_t qHash(const std::string &key, uint seed)
std::string qHash
Definition: metaclass.h:84
Free functions in swift::misc.
QString fromStdString(const std::string &str)
Simple literal type containing a single QLatin1String.
Definition: metaclass.h:100
const QLatin1String m_latin1
Embedded string.
Definition: metaclass.h:102
constexpr CExplicitLatin1String(QLatin1String s)
Implicit constructor.
Definition: metaclass.h:105
Literal aggregate type representing attributes of one member of a value class.
Definition: metaclass.h:148
const M m_ptr
Pointer to the member.
Definition: metaclass.h:150
decltype(auto) in(T &&object, Ts &&...args) const
Invoke the member on an instance of the value class.
Definition: metaclass.h:171
const char *const m_name
Member name.
Definition: metaclass.h:153
constexpr auto latin1Name() const
Return name as QLatin1String.
Definition: metaclass.h:177
const int m_index
Property index of the member.
Definition: metaclass.h:157
const MetaFlags< Flags > m_flags
Any flags applying to the member.
Definition: metaclass.h:160
static constexpr bool has(Flags2 flags)
True if m_flags contains all flags.
Definition: metaclass.h:164
Literal aggregate type representing attributes of the members of a value class.
Definition: metaclass.h:186
static constexpr size_t c_size
Number of members.
Definition: metaclass.h:191
const private_ns::tuple< Members... > m_members
Tuple of CMetaMember.
Definition: metaclass.h:188
Type wrapper for passing MetaFlag to CMetaMember::has.
Definition: metaclass.h:117