|
Boost Users : |
Subject: [Boost-users] [MultIndex] Iterator/Range validity when modify entries.
From: Deniz Bahadir (deniz.bahadir_at_[hidden])
Date: 2016-09-08 12:22:40
Hi guys,
While trying to implementing a new feature, I came across a question
concerning iterator/range validity of boost::multi_index.
To understand the question, here is my setup:
<code>
// Database entry.
struct Entry { int key1; int key2; };
// Access-keys.
struct Index1{};
struct Index2{};
using namespace boost::multi_index;
using namespace boost;
// The multi_index database.
using Database = multi_index_container<
Entry,
indexed_by<
hashed_non_unique<
tag<Index1>,
member<Entry, int, &Entry::key1>
>,
hashed_non_unique<
tag<Index2>,
member<Entry, int, &Entry::key2>
>
>
>;
Database db;
/* ... Here db is getting filled. ... */
</code>
I obtain a range of entries from that database with the same value for
key1 through the first index and want to modify each single entry of
that range. However, I will only modify key2 (which is only used as key
in the other index)!
My main question is now:
Does modifying an entry invalidate my range although I do not modify the
member that was used as key for obtaining the range?
The code in question would possibly look like this:
<code>
auto& index1 = db.get<Index1>();
auto range = index1.equal_range(42);
for (auto it = range.first; it != range.second; ++it)
{
index1.modify(it, [](Entry& entry)
{
entry.key2 = 123; // <---- Does this invalidate my range?
// entry.key1 is not getting modified!
});
}
</code>
My follow-up question is then:
If the range is indeed invalidated, what would be a working solution for
that problem?
Incrementing the loop-iterator by hand before modifying the entry (and
not letting the loop do it)?
So, would the following be a valid solution?
<code>
auto& index1 = db.get<Index1>();
auto range = index1.equal_range(42);
if (range.first != range.second)
{
auto it = range.first;
auto end = --range.second;
do {
index1.modify(it++, [](Entry& entry)
{
entry.key2 = 123; // <---- Does this invalidate my range?
// entry.key1 is not getting modified!
});
while (it != end);
}
</code>
Of course, neither do I want to iterate over an entry twice (and thereby
modify it twice) nor do I want miss an entry.
And one last question:
Does this problem or its solution apply to all index-types or just to
hashed indexes?
Thanks for the clarification.
Deniz
PS: Oh and by the way: Boost.MultiIndex is a really cool library. :-)
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net