mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-17 19:05:31 +08:00
Container classes: removed templated ctors and added static methods to replace them.
This resolves an issue with infinite recursion and stack overflows in MSVC2010. See also http://connect.microsoft.com/VisualStudio/feedback/details/522094/
This commit is contained in:
@@ -50,13 +50,6 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
CCollection() : m_pimpl(new Pimpl<QSet<T>>(QSet<T>())) {}
|
CCollection() : m_pimpl(new Pimpl<QSet<T>>(QSet<T>())) {}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Constructor.
|
|
||||||
* \tparam C Becomes the collection's implementation type.
|
|
||||||
* \param c Initial value for the collection; typically empty, but could contain elements.
|
|
||||||
*/
|
|
||||||
template <class C> CCollection(C c) : m_pimpl(new Pimpl<C>(std::move(c))) {}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy constructor.
|
* \brief Copy constructor.
|
||||||
* \param other
|
* \param other
|
||||||
@@ -69,13 +62,6 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
CCollection(CCollection &&other) : m_pimpl(other.m_pimpl.take()) {}
|
CCollection(CCollection &&other) : m_pimpl(other.m_pimpl.take()) {}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Assignment.
|
|
||||||
* \tparam C Becomes the collection's new implementation type.
|
|
||||||
* \param c New value for the collection; typically empty, but could contain elements.
|
|
||||||
*/
|
|
||||||
template <class C> CCollection &operator =(C c) { m_pimpl.reset(new Pimpl<C>(std::move(c))); return *this; }
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy assignment.
|
* \brief Copy assignment.
|
||||||
* \param other
|
* \param other
|
||||||
@@ -90,11 +76,19 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
CCollection &operator =(CCollection && other) { m_pimpl.reset(other.m_pimpl.take()); return *this; }
|
CCollection &operator =(CCollection && other) { m_pimpl.reset(other.m_pimpl.take()); return *this; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a new collection with a specific implementation type.
|
||||||
|
* \tparam C Becomes the collection's implementation type.
|
||||||
|
* \param c Initial value for the collection; default is empty, but it could contain elements if desired. The value is copied.
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
template <class C> static CCollection fromImpl(C c = C()) { return CCollection(new Pimpl<C>(std::move(c))); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Change the implementation type but keep all the same elements, by copying them into the new implementation.
|
* \brief Change the implementation type but keep all the same elements, by copying them into the new implementation.
|
||||||
* \tparam C Becomes the collection's new implementation type.
|
* \tparam C Becomes the collection's new implementation type.
|
||||||
*/
|
*/
|
||||||
template <class C> void changeImpl(C = C()) { CCollection c = C(); for (auto i = cbegin(); i != cend(); ++i) c.insert(*i); *this = std::move(c); }
|
template <class C> void changeImpl(C = C()) { auto c = fromImpl(C()); for (auto i = cbegin(); i != cend(); ++i) c.insert(*i); *this = std::move(c); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Like changeImpl, but uses the implementation type of another collection.
|
* \brief Like changeImpl, but uses the implementation type of another collection.
|
||||||
@@ -275,6 +269,8 @@ namespace BlackMisc
|
|||||||
typedef QScopedPointer<PimplBase> PimplPtr;
|
typedef QScopedPointer<PimplBase> PimplPtr;
|
||||||
PimplPtr m_pimpl;
|
PimplPtr m_pimpl;
|
||||||
|
|
||||||
|
CCollection(PimplBase *pimpl) : m_pimpl(pimpl) {} // private ctor used by fromImpl()
|
||||||
|
|
||||||
// using these methods to access m_pimpl.data() eases the cognitive burden of correctly forwarding const
|
// using these methods to access m_pimpl.data() eases the cognitive burden of correctly forwarding const
|
||||||
PimplBase *pimpl() { return m_pimpl.data(); }
|
PimplBase *pimpl() { return m_pimpl.data(); }
|
||||||
const PimplBase *pimpl() const { return m_pimpl.data(); }
|
const PimplBase *pimpl() const { return m_pimpl.data(); }
|
||||||
|
|||||||
@@ -50,13 +50,6 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
CSequence() : m_pimpl(new Pimpl<QList<T>>(QList<T>())) {}
|
CSequence() : m_pimpl(new Pimpl<QList<T>>(QList<T>())) {}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Constructor.
|
|
||||||
* \tparam C Becomes the sequence's implementation type.
|
|
||||||
* \param c Initial value for the sequence; typically empty, but could contain elements.
|
|
||||||
*/
|
|
||||||
template <class C> CSequence(C c) : m_pimpl(new Pimpl<C>(std::move(c))) {}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy constructor.
|
* \brief Copy constructor.
|
||||||
* \param other
|
* \param other
|
||||||
@@ -69,13 +62,6 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
CSequence(CSequence &&other) : m_pimpl(other.m_pimpl.take()) {}
|
CSequence(CSequence &&other) : m_pimpl(other.m_pimpl.take()) {}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Assignment.
|
|
||||||
* \tparam C Becomes the sequence's new implementation type.
|
|
||||||
* \param c New value for the sequence; typically empty, but could contain elements.
|
|
||||||
*/
|
|
||||||
template <class C> CSequence &operator =(C c) { m_pimpl.reset(new Pimpl<C>(std::move(c))); return *this; }
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy assignment.
|
* \brief Copy assignment.
|
||||||
* \param other
|
* \param other
|
||||||
@@ -90,11 +76,19 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
CSequence &operator =(CSequence &&other) { m_pimpl.reset(other.m_pimpl.take()); return *this; }
|
CSequence &operator =(CSequence &&other) { m_pimpl.reset(other.m_pimpl.take()); return *this; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a new sequence with a specific implementation type.
|
||||||
|
* \tparam C Becomes the sequence's implementation type.
|
||||||
|
* \param c Initial value for the sequence; default is empty, but it could contain elements if desired. The value is copied.
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
template <class C> static CSequence fromImpl(C c = C()) { return CSequence(new Pimpl<C>(std::move(c))); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Change the implementation type but keep all the same elements, by copying them into the new implementation.
|
* \brief Change the implementation type but keep all the same elements, by copying them into the new implementation.
|
||||||
* \tparam C Becomes the sequence's new implementation type.
|
* \tparam C Becomes the sequence's new implementation type.
|
||||||
*/
|
*/
|
||||||
template <class C> void changeImpl(C = C()) { CSequence c = C(); for (auto i = cbegin(); i != cend(); ++i) c.push_back(*i); *this = std::move(c); }
|
template <class C> void changeImpl(C = C()) { auto c = fromImpl(C()); for (auto i = cbegin(); i != cend(); ++i) c.push_back(*i); *this = std::move(c); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Like changeImpl, but uses the implementation type of another sequence.
|
* \brief Like changeImpl, but uses the implementation type of another sequence.
|
||||||
@@ -508,6 +502,8 @@ namespace BlackMisc
|
|||||||
typedef QScopedPointer<PimplBase> PimplPtr;
|
typedef QScopedPointer<PimplBase> PimplPtr;
|
||||||
PimplPtr m_pimpl;
|
PimplPtr m_pimpl;
|
||||||
|
|
||||||
|
explicit CSequence(PimplBase *pimpl) : m_pimpl(pimpl) {} // private ctor used by fromImpl()
|
||||||
|
|
||||||
// using these methods to access m_pimpl.data() eases the cognitive burden of correctly forwarding const
|
// using these methods to access m_pimpl.data() eases the cognitive burden of correctly forwarding const
|
||||||
PimplBase *pimpl() { return m_pimpl.data(); }
|
PimplBase *pimpl() { return m_pimpl.data(); }
|
||||||
const PimplBase *pimpl() const { return m_pimpl.data(); }
|
const PimplBase *pimpl() const { return m_pimpl.data(); }
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "testcontainers.h"
|
||||||
#include "blackmisc/collection.h"
|
#include "blackmisc/collection.h"
|
||||||
#include "blackmisc/sequence.h"
|
#include "blackmisc/sequence.h"
|
||||||
#include "testcontainers.h"
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -19,7 +19,7 @@ namespace BlackMiscTest
|
|||||||
{
|
{
|
||||||
CCollection<int> c1;
|
CCollection<int> c1;
|
||||||
QVERIFY2(c1.empty(), "Uninitialized collection is empty");
|
QVERIFY2(c1.empty(), "Uninitialized collection is empty");
|
||||||
CCollection<int> c2 = QList<int>();
|
auto c2 = CCollection<int>::fromImpl(QList<int>());
|
||||||
QVERIFY2(c1 == c2, "Uninitialized and empty collections are equal");
|
QVERIFY2(c1 == c2, "Uninitialized and empty collections are equal");
|
||||||
c1.changeImpl(std::vector<int>());
|
c1.changeImpl(std::vector<int>());
|
||||||
QVERIFY2(c1 == c2, "Two empty collections are equal");
|
QVERIFY2(c1 == c2, "Two empty collections are equal");
|
||||||
@@ -42,7 +42,7 @@ namespace BlackMiscTest
|
|||||||
{
|
{
|
||||||
CSequence<int> s1;
|
CSequence<int> s1;
|
||||||
QVERIFY2(s1.empty(), "Uninitialized sequence is empty");
|
QVERIFY2(s1.empty(), "Uninitialized sequence is empty");
|
||||||
CSequence<int> s2 = QList<int>();
|
auto s2 = CSequence<int>::fromImpl(QList<int>());
|
||||||
QVERIFY2(s1 == s2, "Uninitialized and empty sequence are equal");
|
QVERIFY2(s1 == s2, "Uninitialized and empty sequence are equal");
|
||||||
s1.changeImpl(std::vector<int>());
|
s1.changeImpl(std::vector<int>());
|
||||||
QVERIFY2(s1 == s2, "Two empty sequences are equal");
|
QVERIFY2(s1 == s2, "Two empty sequences are equal");
|
||||||
|
|||||||
Reference in New Issue
Block a user