QSet: add insert(T&&)
We already have all we need in QHash to support this, so the addition is simple enough. Add test checking how many copies and/or moves are needed for a single insert. As a drive-by: remove some unneeded static_cast Change-Id: Iaf768657644afa45f78f5c81ffcf89ba9607be96 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6364194456
commit
734c8aa9d9
@ -184,7 +184,9 @@ public:
|
||||
typedef const_iterator ConstIterator;
|
||||
inline qsizetype count() const { return q_hash.count(); }
|
||||
inline iterator insert(const T &value)
|
||||
{ return static_cast<typename Hash::iterator>(q_hash.insert(value, QHashDummyValue())); }
|
||||
{ return q_hash.insert(value, QHashDummyValue()); }
|
||||
inline iterator insert(T &&value)
|
||||
{ return q_hash.emplace(std::move(value), QHashDummyValue()); }
|
||||
iterator find(const T &value) { return q_hash.find(value); }
|
||||
const_iterator find(const T &value) const { return q_hash.find(value); }
|
||||
inline const_iterator constFind(const T &value) const { return find(value); }
|
||||
|
@ -177,13 +177,8 @@ void tst_QDuplicateTracker::appendTo_special()
|
||||
a.reserve(3);
|
||||
tracker.appendTo(a);
|
||||
for (const auto &counter : a) {
|
||||
#if QT_HAS_INCLUDE(<memory_resource>) && __cplusplus > 201402L // uses pmr::unordered_set
|
||||
QCOMPARE(counter.moves, 1);
|
||||
QCOMPARE(counter.copies, 1);
|
||||
#else // Uses QSet
|
||||
QCOMPARE(counter.moves, 1);
|
||||
QCOMPARE(counter.copies, 2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ private slots:
|
||||
void begin();
|
||||
void end();
|
||||
void insert();
|
||||
void insertConstructionCounted();
|
||||
void setOperations();
|
||||
void stlIterator();
|
||||
void stlMutableIterator();
|
||||
@ -579,6 +580,84 @@ void tst_QSet::insert()
|
||||
}
|
||||
}
|
||||
|
||||
struct ConstructionCounted
|
||||
{
|
||||
ConstructionCounted(int i) : i(i) { }
|
||||
ConstructionCounted(ConstructionCounted &&other) noexcept
|
||||
: i(other.i), copies(other.copies), moves(other.moves + 1)
|
||||
{
|
||||
// set to some easily noticeable values
|
||||
other.i = -64;
|
||||
other.copies = -64;
|
||||
other.moves = -64;
|
||||
}
|
||||
ConstructionCounted &operator=(ConstructionCounted &&other) noexcept
|
||||
{
|
||||
ConstructionCounted moved = std::move(other);
|
||||
std::swap(*this, moved);
|
||||
return *this;
|
||||
}
|
||||
ConstructionCounted(const ConstructionCounted &other) noexcept
|
||||
: i(other.i), copies(other.copies + 1), moves(other.moves)
|
||||
{
|
||||
}
|
||||
ConstructionCounted &operator=(const ConstructionCounted &other) noexcept
|
||||
{
|
||||
ConstructionCounted copy = other;
|
||||
std::swap(*this, copy);
|
||||
return *this;
|
||||
}
|
||||
~ConstructionCounted() = default;
|
||||
|
||||
friend bool operator==(const ConstructionCounted &lhs, const ConstructionCounted &rhs)
|
||||
{
|
||||
return lhs.i == rhs.i;
|
||||
}
|
||||
|
||||
QString toString() { return QString::number(i); }
|
||||
|
||||
int i;
|
||||
int copies = 0;
|
||||
int moves = 0;
|
||||
};
|
||||
|
||||
size_t qHash(const ConstructionCounted &c, std::size_t seed = 0)
|
||||
{
|
||||
return qHash(c.i, seed);
|
||||
}
|
||||
|
||||
void tst_QSet::insertConstructionCounted()
|
||||
{
|
||||
QSet<ConstructionCounted> set;
|
||||
|
||||
// copy-insert
|
||||
ConstructionCounted toCopy(7);
|
||||
auto inserted = set.insert(toCopy);
|
||||
QCOMPARE(set.size(), 1);
|
||||
auto element = set.begin();
|
||||
QCOMPARE(inserted, element);
|
||||
QCOMPARE(inserted->copies, 1);
|
||||
QCOMPARE(inserted->moves, 1);
|
||||
QCOMPARE(inserted->i, 7);
|
||||
|
||||
// move-insert
|
||||
ConstructionCounted toMove(8);
|
||||
inserted = set.insert(std::move(toMove));
|
||||
element = set.find(8);
|
||||
QCOMPARE(set.size(), 2);
|
||||
QVERIFY(element != set.end());
|
||||
QCOMPARE(inserted, element);
|
||||
QCOMPARE(inserted->copies, 0);
|
||||
QCOMPARE(inserted->moves, 1);
|
||||
QCOMPARE(inserted->i, 8);
|
||||
|
||||
inserted = set.insert(std::move(toCopy)); // move-insert an existing value
|
||||
QCOMPARE(set.size(), 2);
|
||||
// The previously existing key is used as they compare equal:
|
||||
QCOMPARE(inserted->copies, 1);
|
||||
QCOMPARE(inserted->moves, 1);
|
||||
}
|
||||
|
||||
void tst_QSet::setOperations()
|
||||
{
|
||||
QSet<QString> set1, set2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user