6 #ifndef SWIFT_MISC_DICTIONARY_H
7 #define SWIFT_MISC_DICTIONARY_H
10 #include <initializer_list>
11 #include <type_traits>
14 #include <QDBusArgument>
17 #include <QJsonObject>
19 #include <QJsonValueRef>
40 template <
bool KeySupportsQHash ,
bool KeySupportsQMap>
41 struct TAssociativityTraits
43 template <
class Key,
class Value>
47 struct TAssociativityTraits<false, true>
49 template <
class Key,
class Value>
53 struct TAssociativityTraits<false, false>
55 template <
class Key,
class>
58 static_assert(std::is_void_v<Key>,
"Key does not support either QHash or QMap");
67 template <
typename K,
typename V>
69 typename private_ns::TAssociativityTraits<TModelsQHashKey<K>::value,
87 if (a.m_impl.size() < b.m_impl.size()) {
return -1; }
88 if (a.m_impl.size() > b.m_impl.size()) {
return 1; }
112 typedef typename Impl<Key, Value>::iterator
iterator;
119 template <
class Predicate>
123 for (
auto it = result.
begin(); it != result.
end();)
125 if (!p(it.key())) { it = result.
erase(it); }
133 template <
class... Pairs>
140 template <
class Predicate>
144 for (
auto it = result.
begin(); it != result.
end();)
146 if (!p(it.value())) { it = result.
erase(it); }
154 template <
class... Pairs>
161 template <
class Predicate>
164 auto keys = m_impl.keys();
165 return std::any_of(
keys.cbegin(),
keys.cend(), p);
169 template <
class MembFunc,
class ReturnValue>
176 template <
class Predicate>
179 return std::any_of(m_impl.cbegin(), m_impl.cend(), p);
183 template <
class MembFunc,
class ReturnValue>
190 template <
class Predicate>
193 for (
auto it = m_impl.begin(); it != m_impl.end();)
195 if (p(it.key())) { it = m_impl.erase(it); }
201 template <
class Predicate>
204 for (
auto it = m_impl.begin(); it != m_impl.end();)
206 if (p(it.value())) { it = m_impl.erase(it); }
212 template <
class MembFunc,
class ReturnValue>
219 template <
class MembFunc,
class ReturnValue>
228 for (
auto it =
begin(); it !=
end();)
230 auto it2 = other.
find(it.key());
231 if (it2 != other.
end() && it.value() == it2.value()) { it =
erase(it); }
242 for (
auto it = m_impl.cbegin(); it != m_impl.cend(); ++it) { array << it.key() << it.value(); }
243 json.insert(
"associativecontainerbase", array);
250 QJsonValue
value = json.value(
"associativecontainerbase");
252 QJsonArray array =
value.toArray();
254 for (
auto it = array.begin(); it != array.end(); ++it)
256 QJsonValueRef jsonKey = (*it);
258 if (it == array.end())
260 qWarning(
"Odd number of elements in CDictionary::convertFromJson");
263 QJsonValueRef jsonValue = (*it);
267 CJsonScope scope(
"associativecontainerbase", 2 * index);
272 CJsonScope scope(
"associativecontainerbase", 2 * index++ + 1);
276 m_impl.insert(std::move(
key), std::move(val));
284 CDictionary(std::initializer_list<std::pair<Key, Value>> il) : m_impl(il) {}
314 auto keyBegin()
const {
return m_impl.keyBegin(); }
317 auto keyEnd()
const {
return m_impl.keyEnd(); }
365 int count()
const {
return m_impl.count(); }
368 bool empty()
const {
return m_impl.empty(); }
379 for (
auto i = other.
cbegin(); i != other.
cend(); ++i) {
insert(i.key(), i.value()); }
383 bool isEmpty()
const {
return m_impl.isEmpty(); }
389 const Key
key(
const Value &
value,
const Key &defaultKey)
const {
return m_impl.key(
value, defaultKey); }
398 int size()
const {
return m_impl.size(); }
404 const Value
value(
const Key &
key)
const {
return m_impl.value(
key); }
407 const Value
value(
const Key &
key,
const Value &defaultValue)
const {
return m_impl.value(
key, defaultValue); }
415 m_impl = other.m_impl;
422 m_impl = std::move(other.m_impl);
449 for (
auto it = m_impl.cbegin(); it != m_impl.end(); ++it)
456 return "{" + str +
"}";
473 Impl<Key, Value> m_impl;
479 template <
class Key,
class Value>
488 template <
class Key,
class Value>
497 template <
class Map1,
class Map2,
class F>
500 static_assert(std::is_same_v<typename Map1::key_type, typename Map2::key_type>,
501 "Maps must have the same key type");
502 if (map1.empty() || map2.empty()) {
return; }
507 while (it1 != end1 && it2 != end2)
509 if (it1.key() < it2.key()) { ++it1; }
510 else if (it2.key() < it1.key()) { ++it2; }
513 functor(it1.key(), it1.value(), it2);
static QString stringify(const U &obj, bool i18n)
Stringify value object.
Associative container with value semantics, chooses a sensible default implementation container type.
int count(const Key &key) const
Returns the number of items with key.
void removeByKeyIf(Predicate p)
Remove elements for which a given predicate for value returns true.
CDictionary findValueBy(Predicate p) const
Return a copy containing only those elements for which a given predicate returns true.
void clear()
Removes all items from the dictionary.
const Value value(const Key &key) const
Returns the value associated with the key.
Impl< Key, Value >::size_type size_type
STL compatibility.
~CDictionary()=default
Destructor.
CDictionary & operator=(const CDictionary &other)
Copy assignment.
void marshalToDataStream(QDataStream &stream) const
Marshal a value to a QDataStream.
const_iterator constEnd() const
Returns const iterator at the end of the dictionary.
Value value_type
STL compatibility.
const Value & const_reference
STL compatibility.
CDictionary findValueBy(Pairs... pairs) const
Return a copy containing only those elements which value matches a particular pair.
CDictionary(std::initializer_list< std::pair< Key, Value >> il)
Initializer list constructor.
auto keyEnd() const
Returns const iterator for iterating over keys.
friend const impl_type & implementationOf(const CDictionary &dict)
Return reference to the internal implementation object.
void convertFromJson(const QJsonObject &json)
Assign from JSON object.
friend bool operator==(const CDictionary &a, const CDictionary &b)
Test for equality.
void unmarshallFromDbus(const QDBusArgument &argument)
Unmarshall without begin/endStructure, for when composed within another object.
void marshallToDbus(QDBusArgument &argument) const
Marshall without begin/endStructure, for when composed within another object.
const_iterator end() const
Returns const iterator at the end of the dictionary.
int size() const
Returns the number of items in the hash.
const_iterator constBegin() const
Returns const iterator at the beginning of the dictionary.
Value & operator[](const Key &key)
Access an element by its key.
friend int compare(const CDictionary &a, const CDictionary &b)
Return negative, zero, or positive if a is less than, equal to, or greater than b.
QJsonObject toJson() const
Cast to JSON object.
auto constKeyValueBegin() const
Returns const iterator for iterating over keys and values together.
auto keyValueBegin()
Returns iterator for iterating over keys and values together.
void insert(const CDictionary &other)
Insert all items of other dictionary into this dictionary.
CDictionary findKeyBy(Pairs... pairs) const
Return a copy containing only those elements which key matches a particular pair.
auto keyValueBegin() const
Returns const iterator for iterating over keys and values together.
void removeDuplicates(const CDictionary &other)
Remove elements for which the same key/value pair is present in an other dictionary.
void removeByValueIf(MembFunc membFunc, ReturnValue returnValue)
Remove elements for which value matches a particular pair.
const Value value(const Key &key, const Value &defaultValue) const
Returns the value associated with the key or if key is not found defaultValue.
QString convertToQString(bool i18n=false) const
Cast as QString.
CDictionary findKeyBy(Predicate p) const
Return a copy containing only those elements for which the dictionary keys return true for a given pr...
const_iterator constFind(const Key &key) const
Returns an const iterator pointing to the item with the key.
auto keyValueEnd() const
Returns const iterator for iterating over keys and values together.
iterator end()
Returns iterator at the end of the dictionary.
auto keys() const
Return a range of all keys (does not allocate a temporary container)
bool containsByValue(MembFunc membFunc, ReturnValue returnValue) const
Return true if there is an element which value matches a given pair.
Key key_type
STL compatibility.
const_iterator find(const Key &key) const
Returns an const iterator pointing to the item with the key.
auto keyBegin() const
Returns const iterator for iterating over keys.
int remove(const Key &key)
Remove all items with key from the dictionary.
friend bool operator!=(const CDictionary &a, const CDictionary &b)
Test for inequality.
CDictionary & operator=(CDictionary &&other) noexcept
Move assignment.
const_iterator cbegin() const
Returns const iterator at the beginning of the dictionary.
bool isEmpty() const
Returns true if dictionary is empty.
auto keyValueEnd()
Returns iterator for iterating over keys and values together.
Impl< Key, Value > impl_type
The implementation container.
const_iterator begin() const
Returns const iterator at the beginning of the dictionary.
CDictionary(CDictionary &&other) noexcept
Move constructor.
auto constKeyValueEnd() const
Returns const iterator for iterating over keys and values together.
iterator insert(const Key &key, const Value &value)
Insert new item with key and value.
Impl< Key, Value >::iterator iterator
STL compatibility.
CDictionary()
Default constructor.
void removeByValueIf(Predicate p)
Remove elements for which a given predicate for key returns true.
CRange< const_iterator > values() const
Return a range of all values (does not allocate a temporary container)
bool empty() const
Returns true if the.
const Value operator[](const Key &key) const
Access an element by its key.
void unmarshalFromDataStream(QDataStream &stream)
Unmarshal a value from a QDataStream.
friend impl_type & implementationOf(CDictionary &dict)
Return reference to the internal implementation object.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key.
bool contains(const Key &key) const
Returns true if dictionary contains an item with key, otherwise false.
const Key key(const Value &value) const
Return key assigned to value.
bool containsByValue(Predicate p) const
Return true if there is an element for which a given predicate returns true.
Value & reference
STL compatibility.
const_iterator cend() const
Returns const iterator at the end of the dictionary.
iterator erase(iterator pos)
Removes the key/value pair iterator is currently pointing to and returns an iterator to the next item...
void removeByKeyIf(MembFunc membFunc, ReturnValue returnValue)
Remove elements for which key matches a particular pair.
CDictionary(const CDictionary &)=default
Copy constructor.
int count() const
Returns the size of the dictionary.
Impl< Key, Value >::const_iterator const_iterator
STL compatibility.
bool containsByKey(Predicate p) const
Return true if there is an element for which a given predicate returns true.
const Key key(const Value &value, const Key &defaultKey) const
Return key assigned to value or if key is not found defaultKey.
bool containsByKey(MembFunc membFunc, ReturnValue returnValue) const
Return true if there is an element which key matches a given pair.
void swap(CDictionary &other) noexcept
Swaps hash other with this hash. This operation is very fast and never fails.
iterator begin()
Returns iterator at the beginning of the dictionary.
Thrown when a convertFromJson method encounters an unrecoverable error in JSON data.
Pseudo-RAII pattern that tracks the current JSON value being converted.
A range is a conceptual container which does not contain any elements of its own, but is constructed ...
CRTP class template which will generate marshalling operators for a derived class with its own marsha...
CRTP class template to generate non-member QDataStream streaming operators.
CRTP class template which will generate marshalling operators for a derived class with its own marsha...
CRTP class template from which a derived class can inherit string streaming operations.
auto MemberEqual(Ts... vs)
Predicate which tests whether some member functions return some values.
Free functions in swift::misc.
auto makeRange(I begin, I2 end) -> CRange< I >
Returns a CRange constructed from begin and end iterators of deduced types.
typename private_ns::TAssociativityTraits< TModelsQHashKey< K >::value, TModelsQMapKey< K >::value >::template DefaultType< K, V > TDefaultAssociativeType
Trait to select the appropriate default associative container type depending on what the key type sup...
void forEachIntersection(const Map1 &map1, const Map2 &map2, F functor)
Call a functor for each {key,value1,value2} triple in the keywise intersection of two maps.
QMap< Key, Value > & implementationOf(QMap< Key, Value > &dict)
Identity function for API consistency with CDictionary::implementationOf.
Trait to detect whether a class T can be used as a key in a QMap.