Boost logo

Boost Users :

From: Filip Konvička (filip.konvicka_at_[hidden])
Date: 2007-05-30 11:17:11


> Doing the arithmetic blindly is impossible, since each index
> adds some overhead to the overall node structure. I don't think
> you can follow this approach.
>
Yeah, I didn't mean it seriously, it was late night and I was bored from
all those debugger complaints, so I just wanted to give it a try in that
one specific case.
>> From the "binary" point of view, is there some generic scheme that
>> could be used to access the elements in the container? One can access
>> node_count, but being able to display the list / array of elements would
>> be nice (I don't think that it's necessary to be able to display the
>> tree structure of ordered_unique, for instance), even if there are some
>> additional requirements like that there is a sequenced<> index or that
>> it is even the first of the indices.
>>
> If you don't mind relying on index #0 being a sequenced one, then
> I think you can do it: the assumption about the first index being
> sequenced is equivalent to specifying that the type of the
> header node is of the form:
>
> sequenced_index_node<Q>*
>
> where Q is some complex type involving the rest of indices as
> well as the value type (that I call T1 according to your
> convention when writing the visualizer). You already know how
> to traverse a sequenced index, but just to document it again,
> the expression to go from a node n (of a sequenced index) to the
> following is:
>
> (sequenced_index_node<Q>*)
> (sequenced_index_node_trampoline<Q>*)
> ((sequenced_index_node_trampoline<Q>*)(n)->next_)
>
This is OK, but first I need to get the node "n", which seems hard. This
is because it is the "member" field of the container, which must be
accessed via some down-cast to header_holder<T1, Tx>, and Tx depends on
T2, but I can not derive Tx from T2 in the visualizer (I could use some
typedefs from multi_index::detail to get Tx, but this is not supported
by the debugger).

Specifically, given the multi_index_container<*,indexed_by<*>,*> >
pattern, I need to cast the container variable to

   header_holder<sequenced_index_node<Q2> >,
multi_index_container<T1,indexed_by<T2>,T3> >,

where Q2 is something like
sequenced_index_node<hashed_index_node<index_node_base<T1> > >, which I
don't know how to construct from T2.

[... long thinking ...]

So I tried to visualize sequenced_index_node instead of
multi_index_container, and I have some progress.

I'm doing a cast to sequenced_index_node ->
sequenced_index_node_trampoline --> sequenced_index_node_impl to get the
head of the list, next items of the list are retrieved by applying
".next_", and a node is displayed by casting sequenced_index_node_impl
--> sequenced_index_node_trampoline --> sequenced_index_node. This is a
next challenge point. The next cast would be
*(int*)(boost::multi_index::detail::index_node_base<int>*), which would
show the node data, but I don't know where to get the "int" type now :-)

[... long thinking ...]

I've come up with a solution that uses some compile-time support to
derive a type that can be reached in the visualizer, which in essence
enables to display the data. See the attached visualizer & sample code &
screenshot.

Next, I will try to dispose of the neccessity of clicking through to the
"member" field.

Thanks very much for support!

Cheers,
Filip


#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
using namespace boost::multi_index;
using std::wstring;

template<typename T>
struct multi_index_helper {
};

#define VISUALIZE_MULTI_INDEX_CONTAINER(ID, Type) \
typedef \
  boost::multi_index::detail::multi_index_node_type< \
    Type::value_type, \
    Type::index_specifier_type_list, \
    std::allocator<Type::value_type> >::type \
  VisHelper ## ID; \
template<> \
struct multi_index_helper<VisHelper ## ID> { \
  Type::value_type value; \
}



struct test {
  wstring x;
  test(wchar_t const *str) : x(str) {}
  bool operator<(test const& other) const {
    return x<other.x;
  }
};

typedef multi_index_container<test, indexed_by<sequenced<>, ordered_unique<identity<test> > > > cont;

VISUALIZE_MULTI_INDEX_CONTAINER(testx, cont);

int main() {
  cont x;
  x.push_back(test(L"aaa"));
  x.push_back(test(L"bbb"));
  return 0; // see screenshot
}

boost::multi_index::detail::sequenced_index_node<*>{
 preview(#("multi_index container node"))
 children(
   #(
       #list (
               head : *(((boost::multi_index::detail::sequenced_index_node_impl*)(boost::multi_index::detail::sequenced_index_node_trampoline<$T1>*)&$c)->next_),
               size : 2,
               next : next_
       ) : *(multi_index_helper<boost::multi_index::detail::sequenced_index_node<$T1> >*)(boost::multi_index::detail::sequenced_index_node<$T1>*)(boost::multi_index::detail::sequenced_index_node_trampoline<$T1>*)(&$e),
     original members: [$c,!]
   )
 )
}
multi_index_helper<*> {
  preview(#($c.value))
}


sample.PNG

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