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, 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,
multi_index_container >,
where Q2 is something like
sequenced_index_node >, 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
#include
#include
#include
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::allocatorType::value_type >::type \
VisHelper ## ID; \
template<> \
struct multi_index_helper { \
Type::value_type value; \
}
struct test {
wstring x;
test(wchar_t const *str) : x(str) {}
bool operator<(test const& other) const {
return x, ordered_unique > > 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_trampoline<$T1>*)(&$e),
original members: [$c,!]
)
)
}
multi_index_helper<*> {
preview(#($c.value))
}