Boost logo

Boost Users :

From: Filip Konvička (filip.konvicka_at_[hidden])
Date: 2007-06-04 10:13:38


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



sample_hash.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