// Copyright (C) 2016 Jochen Becher // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "parameters.h" #include #include namespace qark { static Flag ENFORCE_REFERENCED_ITEMS; // QList template inline void save(Archive &archive, const QList &list, const Parameters &) { archive << tag("qlist"); for (const T &t : list) archive << attr("item", t); archive << end; } template inline void save(Archive &archive, const QList &list, const Parameters ¶meters) { archive << tag("qlist"); if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) { for (const T *t : list) archive << ref("item", t); } else { for (const T *t : list) archive << attr("item", t); } archive << end; } template inline void load(Archive &archive, QList &list, const Parameters &) { archive >> tag("qlist"); void (QList::*appendMethod)(const T &) = &QList::append; archive >> attr("item", list, appendMethod); archive >> end; } template inline void load(Archive &archive, QList &list, const Parameters ¶meters) { archive >> tag("qlist"); if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) { // why does the following line not compile but the line below selects the correct function? //archive >> ref, T * const &>("item", list, &QList::append); archive >> ref("item", list, &QList::append); } else { using ParameterType = typename QList::parameter_type; void (QList::*appendMethod)(ParameterType) = &QList::append; archive >> attr("item", list, appendMethod); } archive >> end; } // QSet template inline void save(Archive &archive, const QSet &set, const Parameters &) { archive << tag("qset"); for (const T &t : set) archive << attr("item", t); archive << end; } template inline void save(Archive &archive, const QSet &set, const Parameters ¶meters) { archive << tag("qset"); if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) { for (const T *t : set) archive << ref("item", t); } else { for (const T *t : set) archive << attr("item", t); } archive << end; } namespace impl { template void insertIntoSet(QSet &set, const T &t) { set.insert(t); } } // namespace impl template inline void load(Archive &archive, QSet &set, const Parameters &) { archive >> tag("qset"); archive >> attr("item", set, &impl::insertIntoSet); archive >> end; } template inline void load(Archive &archive, QSet &set, const Parameters ¶meters) { archive >> tag("qset"); if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) archive >> ref("item", set, &impl::insertIntoSet); else archive >> attr("item", set, &impl::insertIntoSet); archive >> end; } // QHash namespace impl { template class KeyValuePair { public: KeyValuePair() = default; KeyValuePair(const KEY &key, const VALUE &value) : m_key(key), m_value(value) { } KEY m_key; VALUE m_value; }; } // namespace impl template inline void save(Archive &archive, const impl::KeyValuePair &pair, const Parameters &) { archive << tag("pair") << attr("key", pair.m_key) << attr("value", pair.m_value) << end; } template inline void load(Archive &archive, impl::KeyValuePair &pair, const Parameters &) { archive >> tag("pair") >> attr("key", pair.m_key) >> attr("value", pair.m_value) >> end; } template inline void save(Archive &archive, const QHash &hash, const Parameters &) { archive << tag("qhash"); for (auto it = hash.begin(); it != hash.end(); ++it) { impl::KeyValuePair pair(it.key(), it.value()); archive << attr("item", pair); } archive << end; } namespace impl { template inline void keyValuePairInsert(QHash &hash, const KeyValuePair &pair) { hash.insert(pair.m_key, pair.m_value); } } // namespace impl template inline void load(Archive &archive, QHash &hash, const Parameters &) { archive >> tag("qhash"); archive >> attr("item", hash, &impl::keyValuePairInsert); archive >> end; } } // namespace qark