|
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))
}
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