diff --git a/src/blackmisc/collection.h b/src/blackmisc/collection.h index 7a7393e8d..e9c334366 100644 --- a/src/blackmisc/collection.h +++ b/src/blackmisc/collection.h @@ -188,6 +188,19 @@ namespace BlackMisc */ iterator insert(T &&value) { Q_ASSERT(pimpl()); return pimpl()->insert(std::move(value)); } + /*! + * \brief Inserts all elements from another collection into this collection. + * \pre This collection must be initialized. + */ + void insert(const CCollection &other) { std::copy(other.begin(), other.end(), std::inserter(*this, begin())); } + + /*! + * \brief Inserts all elements from another collection into this collection. + * This version moves elements instead of copying. + * \pre This collection must be initialized. + */ + void insert(CCollection &&other) { std::move(other.begin(), other.end(), std::inserter(*this, begin())); } + /*! * \brief Synonym for insert. * \return An iterator to the position where value was inserted. @@ -202,6 +215,48 @@ namespace BlackMisc */ iterator push_back(T &&value) { return insert(std::move(value)); } + /*! + * \brief Synonym for insert. + * \pre This collection must be initialized. + */ + void push_back(const CCollection &other) { insert(other); } + + /*! + * \brief Synonym for insert. + * \pre This collection must be initialized. + */ + void push_back(CCollection &&other) { insert(std::move(other)); } + + /*! + * \brief Returns a collection which is the union of this collection and another. + */ + CCollection makeUnion(const CCollection &other) const + { + CCollection result; + std::set_union(begin(), end(), other.begin(), other.end(), std::inserter(result, result.begin())); + return result; + } + + /*! + * \brief Returns a collection which is the intersection of this collection and another. + */ + CCollection intersection(const CCollection &other) const + { + CCollection result; + std::set_intersection(begin(), end(), other.begin(), other.end(), std::inserter(result, result.begin())); + return result; + } + + /*! + * \brief Returns a collection which contains all the elements from this collection which are not in the other collection. + */ + CCollection difference(const CCollection &other) const + { + CCollection result; + std::set_difference(begin(), end(), other.begin(), other.end(), std::inserter(result, result.begin())); + return result; + } + /*! * \brief Remove the element pointed to by the given iterator. * \return An iterator to the position of the next element after the one removed. @@ -237,6 +292,12 @@ namespace BlackMisc */ void remove(const T &object) { auto it = find(object); if (it != end()) { erase(it); } } + /*! + * \brief Removes from this collection all of the elements of another collection. + * \pre This sequence must be initialized. + */ + void remove(const CCollection &other) { *this = CCollection(*this).difference(other); } + /*! * \brief Test for equality. * \todo Improve inefficient implementation. diff --git a/src/blackmisc/sequence.h b/src/blackmisc/sequence.h index 2ef33c65d..9a98e7d98 100644 --- a/src/blackmisc/sequence.h +++ b/src/blackmisc/sequence.h @@ -206,6 +206,19 @@ namespace BlackMisc */ void push_back(T &&value) { Q_ASSERT(pimpl()); pimpl()->push_back(std::move(value)); } + /*! + * \brief Appends all elements from another sequence at the end of this sequence. + * \pre This sequence must be initialized. + */ + void push_back(const CSequence &other) { std::copy(other.begin(), other.end(), std::back_inserter(*this)); } + + /*! + * \brief Appends all elements from another sequence at the end of this sequence. + * This version moves elements instead of copying. + * \pre This sequence must be initialized. + */ + void push_back(CSequence &&other) { std::move(other.begin(), other.end(), std::back_inserter(*this)); } + /*! * \brief Synonym for push_back. * \pre The sequence must be initialized. @@ -218,6 +231,24 @@ namespace BlackMisc */ void insert(T &&value) { push_back(std::move(value)); } + /*! + * \brief Synonym for push_back. + * \pre The sequence must be initialized. + */ + void insert(const CSequence &other) { push_back(other); } + + /*! + * \brief Synonym for push_back. + * \pre The sequence must be initialized. + */ + void insert(CSequence &&other) { push_back(std::move(other)); } + + /*! + * \brief Concatenates two sequences and returns the result. + * \pre This sequence must be initialized. + */ + CSequence join(const CSequence &other) const { CSequence copy(*this); copy.push_back(other); return copy; } + /*! * \brief Removes an element at the end of the sequence. * \pre The sequence must contain at least one element. diff --git a/tests/blackmisc/testcontainers.cpp b/tests/blackmisc/testcontainers.cpp index 9f1e97e44..8d2bad3c9 100644 --- a/tests/blackmisc/testcontainers.cpp +++ b/tests/blackmisc/testcontainers.cpp @@ -67,4 +67,46 @@ namespace BlackMiscTest QVERIFY2(s1.back() == 1, "Last element has expected value"); } + void CTestContainers::joinAndSplit() + { + CSequence s1, s2; + s1.push_back(1); + s1.push_back(2); + s1.push_back(3); + s2.push_back(4); + s2.push_back(5); + s2.push_back(6); + auto joined = s1.join(s2); + s1.push_back(s2); + QVERIFY2(s1.size() == 6, "Combine sequences"); + QVERIFY2(s1 == joined, "Combine sequences"); + + CCollection c1, c2, c3, c4; + c1.push_back(1); + c1.push_back(2); + c1.push_back(3); + c1.push_back(4); + c1.push_back(5); + c1.push_back(6); + c2.push_back(1); + c2.push_back(2); + c2.push_back(3); + c3.push_back(4); + c3.push_back(5); + c3.push_back(6); + c4.push_back(10); + c4.push_back(20); + c4.push_back(30); + QVERIFY2(c1.makeUnion(c2) == c1, "Combine collections"); + QVERIFY2(c2.makeUnion(c3) == c1, "Combine collections"); + QVERIFY2(c1.intersection(c2) == c2, "Combine collections"); + QVERIFY2(c1.difference(c2) == c3, "Split collections"); + c1.insert(c4); + QVERIFY2(c1.size() == 9, "Combine collections"); + c1.remove(c4); + QVERIFY2(c1.size() == 6, "Split collections"); + c1.remove(c2); + QVERIFY2(c1 == c3, "Split collections"); + } + } //namespace BlackMiscTest \ No newline at end of file diff --git a/tests/blackmisc/testcontainers.h b/tests/blackmisc/testcontainers.h index 39686a0c2..b9c5a6730 100644 --- a/tests/blackmisc/testcontainers.h +++ b/tests/blackmisc/testcontainers.h @@ -21,6 +21,7 @@ namespace BlackMiscTest private slots: void collectionBasics(); void sequenceBasics(); + void joinAndSplit(); }; } //namespace BlackMiscTest