From 5da4b75d3e341da598ff245c586e93f1d6c22dd6 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Tue, 16 Jun 2015 20:01:07 +0100 Subject: [PATCH] refs #297 CDictionary: allow access to m_impl and added forEachIntersection function (only supported when impl is QMap). --- src/blackmisc/dictionary.h | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/blackmisc/dictionary.h b/src/blackmisc/dictionary.h index c3fc9dc1c..8fee9daf5 100644 --- a/src/blackmisc/dictionary.h +++ b/src/blackmisc/dictionary.h @@ -368,6 +368,12 @@ namespace BlackMisc //! Move assignment CDictionary &operator =(CDictionary && other) { m_impl = std::move(other.m_impl); return *this; } + //! Return reference to the internal implementation object. + friend impl_type &implementationOf(CDictionary &dict) { return dict.m_impl; } + + //! Return reference to the internal implementation object. + friend const impl_type &implementationOf(const CDictionary &dict) { return dict.m_impl; } + /*! * \brief Access an element by its key. * \note @@ -419,10 +425,35 @@ namespace BlackMisc } private: - Impl m_impl; }; + //! Identity function for API consistency with CDictionary::implementationOf. + template + QMap &implementationOf(QMap &dict) { return dict; } + + //! Identity function for API consistency with CDictionary::implementationOf. + template + const QMap &implementationOf(const QMap &dict) { return dict; } + + //! Call a functor for each {key,value1,value2} triple in the keywise intersection of two maps. + template + void forEachIntersection(const Map1 &map1, const Map2 &map2, F functor) + { + static_assert(std::is_same::value, "Maps must have the same key type"); + if (map1.empty() || map2.empty()) { return; } + auto it1 = implementationOf(map1).lowerBound(map2.cbegin().key()); + auto end1 = implementationOf(map1).upperBound((map2.cend() - 1).key()); + auto it2 = implementationOf(map2).lowerBound(map1.cbegin().key()); + auto end2 = implementationOf(map2).upperBound((map1.cend() - 1).key()); + while (it1 != end1 && it2 != end2) + { + if (it1.key() < it2.key()) { ++it1; } + else if (it2.key() < it1.key()) { ++it2; } + else { functor(it1.key(), it1.value(), it2.value()); ++it1; ++it2; } + } + } + } // namespace BlackMisc #endif // BLACKMISC_DICTIONARY_H