Я работаю с контейнером boost :: multi_index. По сути, он состоит из некоторых данных и информации, если информация о наборе данных является полной (когда элемент добавляется в контейнер, информация еще не завершена). Контейнер упорядочен, потому что я должен знать, что элементы заказа были добавлены в контейнер.
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/key_extractors.hpp>struct indexed_struct
{
unsigned int identifier;
unsigned int iterationFinished;
indexed_struct():
identifier(0), iterationFinished(0){}
indexed_struct(unsigned int identifier, unsigned int iterationFinished):
identifier(identifier), iterationFinished(iterationFinished){}friend std::ostream& operator<<(std::ostream& os,const indexed_struct& c)
{
os<<c.identifier<<std::endl;
return os;
}
};
struct identifierTag {};
struct finishedTag {};typedef boost::multi_index::multi_index_container<
indexed_struct,
boost::multi_index::indexed_by<boost::multi_index::sequenced<>,
boost::multi_index::ordered_unique<boost::multi_index::tag<identifierTag>,
BOOST_MULTI_INDEX_MEMBER(indexed_struct, unsigned int, identifier)
>,
boost::multi_index::ordered_non_unique<boost::multi_index::tag<finishedTag>,
BOOST_MULTI_INDEX_MEMBER(indexed_struct, unsigned int, iterationFinished)
>
>
> cmm_iteration_table;void setFinished(cmm_iteration_table& table, unsigned int iteration)
{
cmm_iteration_table::index<identifierTag>::type::iterator it;
it = table.get<identifierTag>().find(iteration);
indexed_struct mod(*it);
mod.iterationFinished = 1;
table.get<identifierTag>().replace(it, mod);
}void main()
{
cmm_iteration_table table;
//add some items with iterationFinished set to 0
table.push_back(indexed_struct(30,0));
table.push_back(indexed_struct(20,0));
table.push_back(indexed_struct(40,0));
//now set iterationFinished to 1 in a random order
setFinished(table, 30);
setFinished(table, 40);
setFinished(table, 20);
//try to get iterator for iterationFinished == 1 and sequenced
//30-20-40 as added
std::copy(table.get<finishedTag>().equal_range(1).first, table.get<finishedTag>().equal_range(1).second, std::ostream_iterator<indexed_struct>(std::cout)); //outputs 20,40,30 but 30, 20, 40 is intended
std::copy(table.begin(), table.end(), std::ostream_iterator<indexed_struct>(std::cout)); //outputs 30,20,40, but would also output items where iterationFinished == 0
}
Я хотел бы получить пару итераторов, повторяющихся в последовательных элементах, где iterationFinished установлен в 1.
Первый std :: copy с индексом для флага iterationFinished, но порядок не правильный (в том смысле, что я хотел, чтобы порядок был как элементы, которые были помещены в контейнер)
Второй std :: copy дает правильный порядок, но также печатает элементы с iterationFinished == 0.
Есть намеки?
Попробуйте использовать boost::filter_iterator
что-то вроде этого:
struct is_finished
{
bool operator()(indexed_struct const& x) { return x.iterationFinished; }
};
typedef cmm_iteration_table::index<identifierTag>::type::iterator iterator_type;
iterator_type it, ite;
it = table.get<identifierTag>().begin();
ite = table.get<identifierTag>().end();
typedef boost::filter_iterator<is_finished, iterator_type> filter_iter_t;
filter_iter_t f_it(is_finished(), it, ite), f_ite(is_finished(), ite, ite);
std::copy(f_it, f_ite, std::ostream_iterator<indexed_struct>(std::cout));
Других решений пока нет …