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,
85 if (a.m_impl.size() < b.m_impl.size()) {
return -1; }
86 if (a.m_impl.size() > b.m_impl.size()) {
return 1; }
110 typedef typename Impl<Key, Value>::iterator
iterator;
117 template <
class Predicate>
121 for (
auto it = result.
begin(); it != result.
end();)
123 if (!p(it.key())) { it = result.
erase(it); }
131 template <
class... Pairs>
138 template <
class Predicate>
142 for (
auto it = result.
begin(); it != result.
end();)
144 if (!p(it.value())) { it = result.
erase(it); }
152 template <
class... Pairs>
159 template <
class Predicate>
162 auto keys = m_impl.keys();
163 return std::any_of(
keys.cbegin(),
keys.cend(), p);
167 template <
class MembFunc,
class ReturnValue>
174 template <
class Predicate>
177 return std::any_of(m_impl.cbegin(), m_impl.cend(), p);
181 template <
class MembFunc,
class ReturnValue>
188 template <
class Predicate>
191 for (
auto it = m_impl.begin(); it != m_impl.end();)
193 if (p(it.key())) { it = m_impl.erase(it); }
199 template <
class Predicate>
202 for (
auto it = m_impl.begin(); it != m_impl.end();)
204 if (p(it.value())) { it = m_impl.erase(it); }
210 template <
class MembFunc,
class ReturnValue>
217 template <
class MembFunc,
class ReturnValue>
226 for (
auto it =
begin(); it !=
end();)
228 auto it2 = other.
find(it.key());
229 if (it2 != other.
end() && it.value() == it2.value()) { it =
erase(it); }
240 for (
auto it = m_impl.cbegin(); it != m_impl.cend(); ++it) { array << it.key() << it.value(); }
241 json.
insert(
"associativecontainerbase", array);
252 for (
auto it = array.
begin(); it != array.
end(); ++it)
254 QJsonValueRef jsonKey = (*it);
256 if (it == array.
end())
258 qWarning(
"Odd number of elements in CDictionary::convertFromJson");
261 QJsonValueRef jsonValue = (*it);
265 CJsonScope scope(
"associativecontainerbase", 2 * index);
270 CJsonScope scope(
"associativecontainerbase", 2 * index++ + 1);
274 m_impl.insert(std::move(
key), std::move(val));
282 CDictionary(std::initializer_list<std::pair<Key, Value>> il) : m_impl(il) {}
312 auto keyBegin()
const {
return m_impl.keyBegin(); }
315 auto keyEnd()
const {
return m_impl.keyEnd(); }
363 int count()
const {
return m_impl.count(); }
366 bool empty()
const {
return m_impl.empty(); }
377 for (
auto i = other.
cbegin(); i != other.
cend(); ++i) {
insert(i.key(), i.value()); }
381 bool isEmpty()
const {
return m_impl.isEmpty(); }
387 const Key
key(
const Value &
value,
const Key &defaultKey)
const {
return m_impl.key(
value, defaultKey); }
396 int size()
const {
return m_impl.size(); }
402 const Value
value(
const Key &
key)
const {
return m_impl.value(
key); }
405 const Value
value(
const Key &
key,
const Value &defaultValue)
const {
return m_impl.value(
key, defaultValue); }
413 m_impl = other.m_impl;
420 m_impl = std::move(other.m_impl);
447 for (
auto it = m_impl.cbegin(); it != m_impl.end(); ++it)
454 return "{" + str +
"}";
471 Impl<Key, Value> m_impl;
477 template <
class Key,
class Value>
486 template <
class Key,
class Value>
495 template <
class Map1,
class Map2,
class F>
498 static_assert(std::is_same_v<typename Map1::key_type, typename Map2::key_type>,
499 "Maps must have the same key type");
500 if (map1.empty() || map2.empty()) {
return; }
505 while (it1 != end1 && it2 != end2)
507 if (it1.key() < it2.key()) { ++it1; }
508 else if (it2.key() < it1.key()) { ++it2; }
511 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.
QJsonArray::iterator begin()
QJsonArray::iterator end()
QJsonObject::iterator insert(QLatin1StringView key, const QJsonValue &value)
QJsonValue value(QLatin1StringView key) const const
Trait to detect whether a class T can be used as a key in a QMap.