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 
59  QVariant propertyByIndex(CPropertyIndexRef index) const;
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  // *INDENT-OFF*
151 #define SWIFT_MISC_DECLARE_USING_MIXIN_INDEX(DERIVED) \
152  using ::swift::misc::mixin::Index<DERIVED>::apply; \
153  using ::swift::misc::mixin::Index<DERIVED>::setPropertyByIndex; \
154  using ::swift::misc::mixin::Index<DERIVED>::propertyByIndex; \
155  using ::swift::misc::mixin::Index<DERIVED>::comparePropertyByIndex; \
156  using ::swift::misc::mixin::Index<DERIVED>::equalsPropertyByIndex;
157  // *INDENT-ON*
158 
159  template <class Derived>
160  void Index<Derived>::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
161  {
162  if (index.isMyself()) { myself<Derived>(variant); }
163  else { baseSetPropertyByIndex(static_cast<TIndexBaseOfT<Derived> *>(derived()), variant, index); }
164  }
165 
166  template <class Derived>
168  {
169  if (index.isMyself()) { return myself<Derived>(); }
170  const auto i = index.frontCasted<ColumnIndex>(); // keep that "auto", otherwise I won's compile
171  switch (i)
172  {
173  case IndexIcon: return CIcons::toVariant(derived()->toIcon());
174  case IndexPixmap: return CIcons::toVariantPixmap(derived()->toIcon());
175  case IndexString: return QVariant(derived()->toQString());
176  default: return basePropertyByIndex(static_cast<const TIndexBaseOfT<Derived> *>(derived()), index);
177  }
178  }
179 
180  template <class Derived>
181  bool Index<Derived>::equalsPropertyByIndex(const QVariant &compareValue, CPropertyIndexRef index) const
182  {
183  return derived()->propertyByIndex(index) == compareValue;
184  }
185 
186  template <class Derived>
187  int Index<Derived>::comparePropertyByIndex(CPropertyIndexRef index, const Derived &compareValue) const
188  {
189  if (this == &compareValue) { return 0; }
190  if (index.isMyself())
191  {
192  // slow, only last resort
193  return derived()->toQString().compare(compareValue.toQString());
194  }
195 
196  const auto i = index.frontCasted<ColumnIndex>();
197  switch (i)
198  {
199  case IndexIcon:
200  case IndexPixmap:
201  case IndexString:
202  default: break; // also covers
203  }
204 
205  // slow, only last resort
206  return derived()->toQString().compare(compareValue.toQString());
207  }
208  } // namespace mixin
209 } // namespace swift::misc
210 
211 #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:187
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:160
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:167
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:181
Free functions in swift::misc.
typename TIndexBaseOf< T >::type TIndexBaseOfT
Alias for typename TIndexBaseOf<T>::type.