正如我上面提到的,一种使用boost intrusive的更灵活(非基于谓词)的方法。使用两个或多个列表挂钩,您可以使一个对象同时参与两个或多个序列。
#include <boost/intrusive/list.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
#include <memory>
#include <iostream>
namespace intr = boost::intrusive;
template<class Value>
struct Sequence2
{
typedef intr::link_mode< intr::auto_unlink > AutoUnlinkMode;
typedef intr::list_member_hook< AutoUnlinkMode > SeqHook;
struct Node
{
Node( const Value& i ) : value(i) {}
operator Value&()
{
return value;
}
Value value;
SeqHook mainHook;
SeqHook hook0;
SeqHook hook1;
};
typedef intr::member_hook< Node, SeqHook,&Node::mainHook > UsingMainHook;
typedef intr::member_hook< Node, SeqHook,&Node::hook0 > UsingSeqHook0;
typedef intr::member_hook< Node, SeqHook,&Node::hook1 > UsingSeqHook1;
typedef intr::constant_time_size<false> NonConstantTimeSized;
typedef intr::list< Node, UsingMainHook, NonConstantTimeSized > NodesList;
typedef intr::list< Node, UsingSeqHook0, NonConstantTimeSized > Sequence0;
typedef intr::list< Node, UsingSeqHook1, NonConstantTimeSized > Sequence1;
NodesList nodes;
Sequence0 seq0;
Sequence1 seq1;
typename NodesList::iterator insert( const Value& item )
{
Node* node = new Node(item);
nodes.push_back( *node );
typename NodesList::iterator iter = nodes.end(); iter--;
seq0.push_back( *node );
seq1.push_back( *node );
return iter;
}
typename Sequence0::iterator iterator0( typename NodesList::iterator iter )
{
return seq0.iterator_to( *iter );
}
typename Sequence1::iterator iterator1( typename NodesList::iterator iter )
{
return seq1.iterator_to( *iter );
}
//! Erase from both sequences
void erase( typename NodesList::iterator at )
{
nodes.erase_and_dispose( at, std::default_delete<Node>() );
}
//! Erase from sequence 0
void erase( typename Sequence0::iterator at )
{
Node& n = *at;
assert( n.hook0.is_linked() );
if( ! n.hook1.is_linked() )
{
seq0.erase_and_dispose( at, std::default_delete<Node>() );
}
else
{
seq0.erase(at);
}
}
//! Erase from sequence 1
void erase( typename Sequence1::iterator at )
{
Node& n = *at;
assert( n.hook1.is_linked() );
if( ! n.hook0.is_linked() )
{
seq1.erase_and_dispose( at, std::default_delete<Node>() );
}
else
{
seq1.erase(at);
}
}
~Sequence2()
{
nodes.clear_and_dispose( std::default_delete<Node>() );
}
};
template< class T >
void show( Sequence2<T>& mseq, const std::string& comment )
{
std::cout << comment << "\nseq 0:\t";
BOOST_FOREACH( T& i, mseq.seq0 )
{
std::cout << i << " ";
}
std::cout << "\nseq 1:\t";
BOOST_FOREACH( T& i, mseq.seq1 )
{
std::cout << i << " ";
}
std::cout << "\n\n";
}
int main(void)
{
Sequence2< std::string > mseq;
mseq.insert( "." );
auto iterX = mseq.insert("X");
auto iterY = mseq.insert("Y");
auto iterZ = mseq.insert("Z");
mseq.insert(".");
mseq.insert(".");
show(mseq, "start" );
mseq.seq0.reverse();
show(mseq, "after reverse seq0");
mseq.erase( mseq.iterator0(iterY) );
show(mseq, "after erase Y in seq0");
// Update a value in both sequences
std::string& v = *iterZ;
v = "z";
show(mseq, "after modify Z in both");
mseq.erase( iterX );
show(mseq, "after erase X in both");
mseq.erase( iterY );
show(mseq, "after erase Y in both");
return 0;
}
产生:
start
seq 0: . X Y Z . .
seq 1: . X Y Z . .
after reverse seq0
seq 0: . . Z Y X .
seq 1: . X Y Z . .
after erase Y in seq0
seq 0: . . Z X .
seq 1: . X Y Z . .
after modify Z in both
seq 0: . . z X .
seq 1: . X Y z . .
after erase X in both
seq 0: . . z .
seq 1: . Y z . .
after erase Y in both
seq 0: . . z .
seq 1: . z . .