swift
mixinindex.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 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_MIXININDEX_H
7 #define SWIFT_MISC_MIXIN_MIXININDEX_H
8 
9 #include <type_traits>
10 
11 #include <QDBusArgument>
12 #include <QList>
13 #include <QMap>
14 #include <QMetaType>
15 #include <QString>
16 #include <QVariant>
17 #include <QtDebug>
18 #include <QtGlobal>
19 
20 #include "misc/icon.h"
21 #include "misc/inheritancetraits.h"
22 #include "misc/predicates.h"
23 #include "misc/propertyindexref.h"
24 
25 namespace swift::misc
26 {
27  class CPropertyIndexList;
28  class CPropertyIndexVariantMap;
29 
30  namespace mixin
31  {
38  template <class Derived>
39  class Index
40  {
41  public:
44  {
45  IndexPixmap = 10, // manually set to avoid circular dependencies
46  IndexIcon,
47  IndexString
48  };
49 
53  bool skipEqualValues = false); // impl in propertyindexvariantmap.h
54 
56  void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant);
57 
60 
62  int comparePropertyByIndex(CPropertyIndexRef index, const Derived &compareValue) const;
63 
65  bool equalsPropertyByIndex(const QVariant &compareValue, CPropertyIndexRef index) const;
66 
67  private:
68  const Derived *derived() const;
69  Derived *derived();
70 
71  template <typename T>
72  QVariant myself() const;
73  template <typename T>
74  void myself(const QVariant &variant);
75 
76  template <typename T>
77  QVariant basePropertyByIndex(const T *base, CPropertyIndexRef index) const;
78  template <typename T>
79  void baseSetPropertyByIndex(T *base, const QVariant &var, CPropertyIndexRef index);
80 
81  QVariant basePropertyByIndex(const void *, CPropertyIndexRef) const;
82  void baseSetPropertyByIndex(void *, const QVariant &, CPropertyIndexRef);
83  };
84 
85  template <class Derived>
86  const Derived *Index<Derived>::derived() const
87  {
88  return static_cast<const Derived *>(this);
89  }
90 
91  template <class Derived>
92  Derived *Index<Derived>::derived()
93  {
94  return static_cast<Derived *>(this);
95  }
96 
97  template <class Derived>
98  template <typename T>
99  QVariant Index<Derived>::myself() const
100  {
101  if constexpr (std::is_default_constructible_v<T>) { return QVariant::fromValue(*derived()); }
102  else
103  {
104  qFatal("isMyself should have been handled before reaching here");
105  return {};
106  }
107  }
108 
109  template <class Derived>
110  template <typename T>
111  void Index<Derived>::myself(const QVariant &variant)
112  {
113  if constexpr (std::is_default_constructible_v<T>) { *derived() = variant.value<T>(); }
114  else { qFatal("isMyself should have been handled before reaching here"); }
115  }
116 
117  template <class Derived>
118  template <typename T>
119  QVariant Index<Derived>::basePropertyByIndex(const T *base, CPropertyIndexRef index) const
120  {
121  return base->propertyByIndex(index);
122  }
123 
124  template <class Derived>
125  template <typename T>
126  void Index<Derived>::baseSetPropertyByIndex(T *base, const QVariant &var, CPropertyIndexRef index)
127  {
128  base->setPropertyByIndex(index, var);
129  }
130 
131  template <class Derived>
132  QVariant Index<Derived>::basePropertyByIndex(const void *, CPropertyIndexRef) const
133  {
134  // qFatal("%s", qPrintable("Property by index not found, index: " + index.toQString())); return {};
135  qFatal("Property by index not found");
136  return {};
137  }
138 
139  template <class Derived>
140  void Index<Derived>::baseSetPropertyByIndex(void *, const QVariant &, CPropertyIndexRef)
141  {
142  // qFatal("%s", qPrintable("Property by index not found (setter), index: " + index.toQString()));
143  qFatal("Property by index not found");
144  }
145 
150 #define SWIFT_MISC_DECLARE_USING_MIXIN_INDEX(DERIVED) \
151  using ::swift::misc::mixin::Index<DERIVED>::apply; \
152  using ::swift::misc::mixin::Index<DERIVED>::setPropertyByIndex; \
153  using ::swift::misc::mixin::Index<DERIVED>::propertyByIndex; \
154  using ::swift::misc::mixin::Index<DERIVED>::comparePropertyByIndex; \
155  using ::swift::misc::mixin::Index<DERIVED>::equalsPropertyByIndex;
156 
157  template <class Derived>
159  {
160  if (index.isMyself()) { myself<Derived>(variant); }
161  else { baseSetPropertyByIndex(static_cast<TIndexBaseOfT<Derived> *>(derived()), variant, index); }
162  }
163 
164  template <class Derived>
166  {
167  if (index.isMyself()) { return myself<Derived>(); }
168  const auto i = index.frontCasted<ColumnIndex>(); // keep that "auto", otherwise I won's compile
169  switch (i)
170  {
171  case IndexIcon: return CIcons::toVariant(derived()->toIcon());
172  case IndexPixmap: return CIcons::toVariantPixmap(derived()->toIcon());
173  case IndexString: return QVariant(derived()->toQString());
174  default: return basePropertyByIndex(static_cast<const TIndexBaseOfT<Derived> *>(derived()), index);
175  }
176  }
177 
178  template <class Derived>
179  bool Index<Derived>::equalsPropertyByIndex(const QVariant &compareValue, CPropertyIndexRef index) const
180  {
181  return derived()->propertyByIndex(index) == compareValue;
182  }
183 
184  template <class Derived>
185  int Index<Derived>::comparePropertyByIndex(CPropertyIndexRef index, const Derived &compareValue) const
186  {
187  if (this == &compareValue) { return 0; }
188  if (index.isMyself())
189  {
190  // slow, only last resort
191  return derived()->toQString().compare(compareValue.toQString());
192  }
193 
194  const auto i = index.frontCasted<ColumnIndex>();
195  switch (i)
196  {
197  case IndexIcon:
198  case IndexPixmap:
199  case IndexString:
200  default: break; // also covers
201  }
202 
203  // slow, only last resort
204  return derived()->toQString().compare(compareValue.toQString());
205  }
206  } // namespace mixin
207 } // namespace swift::misc
208 
209 #endif // SWIFT_MISC_MIXIN_MIXININDEX_H
static QVariant toVariant(IconIndex icon)
Variant containing CIcon.
Definition: icon.cpp:242
static QVariant toVariantPixmap(IconIndex icon)
Variant containing QPixmap.
Definition: icon.cpp:243
Value object encapsulating a list of property indexes.
Non-owning reference to a CPropertyIndex with a subset of its features.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
Specialized value object compliant map for variants, based on indexes.
CRTP class template from which a derived class can inherit property indexing functions.
Definition: mixinindex.h:40
ColumnIndex
Base class enums.
Definition: mixinindex.h:44
int comparePropertyByIndex(CPropertyIndexRef index, const Derived &compareValue) const
Compare for index.
Definition: mixinindex.h:185
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:158
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:165
CPropertyIndexList apply(const CPropertyIndexVariantMap &indexMap, bool skipEqualValues=false)
Update by variant map.
bool equalsPropertyByIndex(const QVariant &compareValue, CPropertyIndexRef index) const
Is given variant equal to value of property index?
Definition: mixinindex.h:179
Free functions in swift::misc.
typename TIndexBaseOf< T >::type TIndexBaseOfT
Alias for typename TIndexBaseOf<T>::type.
QVariant fromValue(T &&value)
T value() const &const