I'm trying to create debug visualizers for our company custom smart pointers. I would like to use ExpandItem
to get the contents just one level down, which works for concrete types like ref_ptr<Vector2d>
, but not for virtual types like ref_ptr<IStreamManager>
. When using the virtual types, I get two entries, one for the underlying type, which I can then expand, and one for the __vfptr
.
What I'm getting:
v streamManagerPtr shared_ptr { count=35, ptr=... }
[Reference Count] 2
v [StreamMgr] {...}
m_resourceMgr shared_ptr { count=35, ptr=... }
m_fileMgr shared_ptr { count=23, ptr=... }
...
> __vfptr 0xdeadbeef
> [Raw View] {...}
What I want:
v streamManagerPtr shared_ptr { count=35, ptr=... }
[Reference Count] 2
m_resourceMgr shared_ptr { count=35, ptr=... }
m_fileMgr shared_ptr { count=23, ptr=... }
...
> [Raw View] {...}
Is there any way to bring the contents of the underlying dynamic type up one more level so I don't have to deal with this useless level of nesting?
I believe you can use something like this:
<Type Name="shared_ptr<*>">
<Expand>
<ExpandedItem Condition="ptr != 0">*ptr</ExpandedItem>
</Expand>
</Type>
The ExpandedItem
tag basically removes a level of nesting, displaying the contents of the item in the tag as though they were regular items at the same nesting level as the rest of the Item
s in the Expand
tag.
I am not using ref_ptr
, so I tested with my own template class. So please be mercy if the following code might not immediately work with ref_ptr
.
<Type Name="ref_ptr<*>" Priority="MediumLow">
<Expand>
<ExpandedItem Condition="_ptr->__vfptr">*_ptr</ExpandedItem>
</Expand>
</Type>
<Type Name="ref_ptr<*>">
<Expand>
<ExpandedItem>_ptr</ExpandedItem>
</Expand>
</Type>
The trick is descibed on MSDN: natvis tries to parse the first entry. That one is checking if _ptr->__vfptr
is not nullptr
. For your IStreamManager
this can be parsed and evaluates to true, so the first entry is used, the object itself is taken and expanded. If the condition on the first entry fails to parse because there is no __vfptr
then the first entry is not used and the second entry is used. That one is doing just what you have now in your existing code.
User contributions licensed under CC BY-SA 3.0