title: Using std::type_info for casting in natvis
body: <p>In the codebase I'm working, we use <code>std::any</code> instead of <code>void*</code> to pass classes through some generic non-template code. Specifically, we use Visual Studio 2019, its compiler and standard library.</p>
  
  <p>In order to visualize the <code>std::any</code>, microsoft already gives a natvis:</p>
  
  <pre><code>  &lt;Type Name="std::any"&gt;
        &lt;Intrinsic Name="has_value"   Expression="_Storage._TypeData != 0"/&gt;
        &lt;Intrinsic Name="_Rep"        Expression="_Storage._TypeData &amp;amp; _Rep_mask"/&gt;
        &lt;Intrinsic Name="type"        Expression="(const type_info*)(_Storage._TypeData &amp;amp; ~_Rep_mask)"/&gt;
        &lt;Intrinsic Name="_Is_trivial" Expression="has_value() &amp;amp;&amp;amp; _Rep() == 0"/&gt;
        &lt;Intrinsic Name="_Is_big"     Expression="has_value() &amp;amp;&amp;amp; _Rep() == 1"/&gt;
        &lt;Intrinsic Name="_Is_small"   Expression="has_value() &amp;amp;&amp;amp; _Rep() == 2"/&gt;
        &lt;DisplayString Condition="!has_value()"&gt;[empty]&lt;/DisplayString&gt;
        &lt;DisplayString Condition="_Is_trivial() || _Is_small()"&gt;[not empty (Small)]&lt;/DisplayString&gt;
        &lt;DisplayString Condition="_Is_big()"&gt;[not empty (Large)]&lt;/DisplayString&gt;
        &lt;Expand&gt;
            &lt;Synthetic Name="has_value"&gt;
                &lt;DisplayString&gt;{has_value()}&lt;/DisplayString&gt;
            &lt;/Synthetic&gt;
            &lt;Synthetic Name="type" Condition="has_value()"&gt;
                &lt;DisplayString&gt;{type()}&lt;/DisplayString&gt;
            &lt;/Synthetic&gt;
            &lt;Synthetic Name="[representation]" Condition="_Is_trivial()"&gt;
                &lt;DisplayString&gt;(Small/Trivial Object)&lt;/DisplayString&gt;
            &lt;/Synthetic&gt;
            &lt;Synthetic Name="[representation]" Condition="_Is_small()"&gt;
                &lt;DisplayString&gt;(Small Object)&lt;/DisplayString&gt;
            &lt;/Synthetic&gt;
            &lt;Synthetic Name="[representation]" Condition="_Is_big()"&gt;
                &lt;DisplayString&gt;(Dynamic Allocation)&lt;/DisplayString&gt;
            &lt;/Synthetic&gt;
        &lt;/Expand&gt;
    &lt;/Type&gt;
  </code></pre>
  
  <p>However, this ends up showing us <code>(Small Object)</code> instead of the <code>std::string</code> that we have stored into it.
  I've already managed to extend this with a few extra lines to get the pointer to the data:</p>
  
  <pre><code>          &lt;Item Name="[castable_ptr]" Condition="_Is_trivial()"&gt;(void*)(&amp;amp;_Storage._TrivialData)&lt;/Item&gt;
            &lt;Item Name="[castable_ptr]" Condition="_Is_small()"&gt;(void*)(&amp;amp;_Storage._SmallStorage._Data)&lt;/Item&gt;
            &lt;Item Name="[castable_ptr]" Condition="_Is_big()"&gt;(void*)(_Storage._BigStorage._Ptr)&lt;/Item&gt;
  </code></pre>
  
  <p>However, this shows the data as a <code>void*</code>, which you have to manually cast to a pointer of the actual type <code>std::string*</code>.
  However, this <code>std::any</code> implementation/visualization also comes with a <code>std::type_info</code>. (see field: type) that knows which underlying type we have.</p>
  
  <p>Is there a way to use this <code>std::type_info</code> so that the <code>(void*)</code> can be replaced by a cast to the actual stored type?</p>
  
  <p><strong>EDIT:</strong> An example of the information that visual studio provides for the type: <code>{mydll.dll!class std::tuple&lt;__int64,double,double,double&gt; 'RTTI Type Descriptor'} {...}</code>
  When explicitly casting the address to std::type_info*, I get access to <code>_Data</code> in the debugger, that contains <code>_DecoratedName</code> (<code>.?AV?$tuple@_JNNN@std@@</code>) and <code>_UndecoratedName</code> (<code>nullptr</code>).
  Unfortunately, I can't seem to find out how to write a cast that leverages this information.</p>