I have a boost::intrusive::list<Foo, constant_time_size<false>>, where Foo inherits from the list_base_hook<auto_unlink> hook. With a list element foo, I am able to get its iterator by calling list::s_iterator_to(foo). My question is how I can traverse the list with this iterator. In particular, is there a way to tell if this element is the only one in the list?
The source suggests list uses a cicular_list_algorithms in its value traits and perhaps I can use the following test?
auto itr1 = list_t::s_iterator_to(foo);
auto itr2 = list_t::s_iterator_to(foo);
&(*++itr1) == &(*--itr2);
It looks quite hacky but it seeminly works. I'm not sure if it is correct and idiomatic. Can somebody please advise?
The complete listing:
#include <iostream>
#include <boost/intrusive/list.hpp>
using namespace boost::intrusive;
typedef list_base_hook<link_mode<auto_unlink> > auto_unlink_hook;
class Foo : public auto_unlink_hook
{
int int_;
public:
Foo(int i = 0) : int_(i) {}
int get_int() { return int_; }
void unlink() { auto_unlink_hook::unlink(); }
bool is_linked() { return auto_unlink_hook::is_linked(); }
};
int main()
{
typedef list<Foo, constant_time_size<false>> ListType;
ListType l;
Foo foo1{42};
l.push_back(foo1);
auto itr1 = ListType::s_iterator_to(foo1);
auto itr2 = ListType::s_iterator_to(foo1);
std::cout << (&(*++itr1) == &(*--itr2)) << std::endl;
Foo foo2{43};
l.push_back(foo2);
itr1 = ListType::s_iterator_to(foo1);
itr2 = ListType::s_iterator_to(foo1);
std::cout << (&(*++itr1) == &(*--itr2)) << std::endl;
foo1.unlink();
return 0;
}
Yes, I do realize dereferencing ++itr1 and --itr1 is wrong. Is there any way that I can compare the addresses of the underlying nodes directly? I imagine foo has both links to its predecessor and successor and they should be equal to each other if foo is the only element.
I tried these, and it worked. However, it is tightly coupled with the implementation details. The idea is to get the underlying node pointer from the value and compare the pointers.