[multi_index] MSVC 8.0 visualizers for boost::multi_index_container

Hello all, here is another version of MSVC 2005 visualizers for multi_index_container. Thanks to Joaquín for his invaluable support! This version supports sequenced, random_access, ordered and hashed indices. Hashed indices are visualized including the internal bucket structure, indicating empty bucket, single-item bucket and multiple-item bucket (see the example below). As in the previous version, contents of autoexp.dat.txt go into Microsoft Visual Studio 8\Common7\Packages\Debugger\autoexp.dat For your container to be visualized, you need to call the VISUALIZE_MULTI_INDEX_CONTAINER macro at the global namespace level (see the attached example, test2.cpp, and a screenshot of a test2.cpp debugging session, sample_hash.png). I strongly recommend using #define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE 5 #define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE 3 #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5 in order to reduce symbol name lengths, because otherwise the resulting symbols are too long for the visualizer to work (this typically happens with more than 1 index in a multi_index_container). Also beware, using type hiding techniques described at http://boost.org/libs/multi_index/doc/compiler_specifics.html#type_hiding will cause visualizers to fail. Enjoy! Cheers, Filip ;------------------------------------ ; boost::multi_index_container - base boost::multi_index::multi_index_container<*,*,*>{ preview(#($c.node_count, " items (multi_index_container)")) children( #( data:((msvc_helpers::multi_index_helper_2<boost::multi_index::multi_index_container<$T1,$T2,$T3> >*)&$c)->header, original members: [$c,!] ) ) } ;----------------------------------------------- ; boost::multi_index_container - sequenced index boost::multi_index::detail::header_holder<boost::multi_index::detail::sequenced_index_node<*>,*>{ preview(#("sequenced index")) children( #( #list( head : *(((boost::multi_index::detail::sequenced_index_node_impl*)(boost::multi_index::detail::sequenced_index_node_trampoline<$T1>*)($c.member))->next_), size : (($T2*)&$c)->node_count, next : next_ ) : ((msvc_helpers::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))->value ) ) } ;--------------------------------------------------- ; boost::multi_index_container - random access index boost::multi_index::detail::header_holder<boost::multi_index::detail::random_access_index_node<*>,*>{ preview(#("random access index")) children( #( #array( expr: (($T2*)&$c)->ptrs.spc.data_[$i], size: (($T2*)&$c)->node_count ) : ((msvc_helpers::multi_index_helper<boost::multi_index::detail::random_access_index_node<$T1> >*)(boost::multi_index::detail::random_access_index_node<$T1>*)(boost::multi_index::detail::random_access_index_node_trampoline<$T1>*)&$e)->value ) ) } ;-------------------------------------------- ; boost::multi_index_container - hashed index boost::multi_index::detail::header_holder<boost::multi_index::detail::hashed_index_node<*>,*>{ preview(#("hashed index - ", (($T2*)&$c)->node_count, " in ", (($T2*)&$c)->buckets.size_, " buckets")) children( #( #array( expr : (($T2*)&$c)->buckets.spc.data_[$i], size : (($T2*)&$c)->buckets.size_ ) : (msvc_helpers::multi_index_helper_3<boost::multi_index::detail::hashed_index_node<$T1> >*)(void*)&$e ) ) } msvc_helpers::multi_index_helper_3<boost::multi_index::detail::hashed_index_node<*> >{ preview(#if ( ((boost::multi_index::detail::hashed_index_node_impl*)&$c)->next_==((boost::multi_index::detail::hashed_index_node_impl*)&$c) ) ; no data at all (#("---")) #else ( #if ( ((boost::multi_index::detail::hashed_index_node_impl*)&$c)->next_->next_==((boost::multi_index::detail::hashed_index_node_impl*)&$c) ) ( ; 1 item: preview as _value_ #( ((msvc_helpers::multi_index_helper<boost::multi_index::detail::hashed_index_node<$T1> >*)(boost::multi_index::detail::hashed_index_node<$T1>*)(boost::multi_index::detail::hashed_index_node_trampoline<$T1>*)(((boost::multi_index::detail::hashed_index_node_impl*)&$c)->next_))->value) ) #else ( ; multiple items: preview as [_value_ ...] #("[", ((msvc_helpers::multi_index_helper<boost::multi_index::detail::hashed_index_node<$T1> >*)(boost::multi_index::detail::hashed_index_node<$T1>*)(boost::multi_index::detail::hashed_index_node_trampoline<$T1>*)(((boost::multi_index::detail::hashed_index_node_impl*)&$c)->next_))->value, " ...]") ) ) ) children( #( ; multiple items: view as list #list( head: ((boost::multi_index::detail::hashed_index_node_impl*)&$c)->next_, next: next_, skip: ((boost::multi_index::detail::hashed_index_node_impl*)&$c) ) : ((msvc_helpers::multi_index_helper<boost::multi_index::detail::hashed_index_node<$T1> >*)(boost::multi_index::detail::hashed_index_node<$T1>*)(boost::multi_index::detail::hashed_index_node_trampoline<$T1>*)(&$e))->value ) ) } ;--------------------------------------------- ; boost::multi_index_container - ordered index boost::multi_index::detail::header_holder<boost::multi_index::detail::ordered_index_node<*>,*>{ preview(#("ordered index")) children( #( #tree( head : *(boost::multi_index::detail::ordered_index_node_compressed_base*)(boost::multi_index::detail::ordered_index_node_impl*)(void*)(((boost::multi_index::detail::ordered_index_node_trampoline<$T1>*)($c.member))->parentcolor_&~1U), size : (($T2*)&$c)->node_count, left : left_, right : right_, skip : 0 ) : ((msvc_helpers::multi_index_helper<boost::multi_index::detail::ordered_index_node<$T1> >*)(boost::multi_index::detail::ordered_index_node<$T1>*)(boost::multi_index::detail::ordered_index_node_trampoline<$T1>*)(&$e))->value ) ) } #define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE 5 #define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE 3 #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5 #include "mic_visualizer.hpp" #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> #include <boost/multi_index/random_access_index.hpp> using namespace boost::multi_index; using std::wstring; using namespace std; struct test { wstring x; wstring y; test(wchar_t const *str, wchar_t const *str2=L"def") : x(str), y(str2) {} bool operator<(test const& other) const { return x<other.x; } bool operator==(test const& other) const { return x==other.x; } }; namespace boost { inline std::size_t hash_value(test const& t) { return hash_value(t.x); } } typedef multi_index_container<test, indexed_by<hashed_non_unique<identity<test> > > > cont; VISUALIZE_MULTI_INDEX_CONTAINER(cont); int wmain() { cont test_cont; test_cont.insert(test(L"aaa")); test_cont.insert(test(L"aaa", L"other")); test_cont.insert(test(L"aac")); return 0; // see screenshoxt } #ifndef MIC_VISUALIZER_HPP #define MIC_VISUALIZER_HPP #if !defined(_DEBUG)||!defined(_MSC_VER)||(_MSC_VER<1400) #define VISUALIZE_MULTI_INDEX_CONTAINER(Type) /* empty def */ #else namespace msvc_helpers { template<typename T> struct multi_index_helper { }; template<typename T> struct multi_index_helper_2 { }; template<typename T> struct multi_index_helper_3 { }; } #define __VISUALIZE_MIC_INDEX_DEF(Type) \ boost::multi_index::detail::multi_index_node_type< \ Type::value_type, \ Type::index_specifier_type_list, \ std::allocator<Type::value_type> >::type /// Enables MSVC visualizers for multi_index_container Type #define VISUALIZE_MULTI_INDEX_CONTAINER(Type) \ namespace msvc_helpers { \ template<> \ struct multi_index_helper_2<Type> { \ typedef __VISUALIZE_MIC_INDEX_DEF(Type) index_node_type; \ typedef \ boost::base_from_member< \ boost::detail::allocator::rebind_to< \ std::allocator<Type::value_type>, \ index_node_type \ >::type> \ base_type; \ typedef \ boost::multi_index::detail::header_holder< \ index_node_type, Type> \ header_holder_type; \ typedef \ boost::multi_index::detail::multi_index_base_type< \ Type::value_type, \ Type::index_specifier_type_list, \ std::allocator<Type::value_type> >::type \ index_type; \ /* mimic multi_index_container layout */ \ base_type base; \ header_holder_type header; \ index_type index; \ unsigned int node_count; \ /* ensure that the debugger sees this template instance */ \ static void get() { \ multi_index_helper_2<Type> *ensure_inst=0; \ } \ }; \ template<> \ struct multi_index_helper_3<__VISUALIZE_MIC_INDEX_DEF(Type)> { \ /* ensure that the debugger sees this template instance */ \ static void get() { \ multi_index_helper_3< \ __VISUALIZE_MIC_INDEX_DEF(Type)> *ensure_inst=0; \ } \ }; \ template<> \ struct multi_index_helper<__VISUALIZE_MIC_INDEX_DEF(Type)> { \ typedef __VISUALIZE_MIC_INDEX_DEF(Type) index_node_type; \ /* mimic index_node_base<Type::value_type> layout */ \ Type::value_type value; \ /* ensure that the debugger sees this template instance */ \ static void get() { \ multi_index_helper<index_node_type> *ensure_inst=0; \ } \ }; \ } #endif #endif
participants (1)
-
Filip Konvička