Alex
Alex

Reputation: 846

Is it possible to NATVIS a recursive tuple (variadic template)?

I implemented the tuple from here: https://voidnish.wordpress.com/2013/07/13/tuple-implementation-via-variadic-templates/

Is it possible to visualize it with NATVIS? I got as far as

<Type Name="tuple">
  <DisplayString>()</DisplayString>  
</Type>

<Type Name="tuple&lt;*&gt;">
  <DisplayString>({_Myfirst})</DisplayString>
</Type>

How can I get the _Myfirst value for more than one type, to get

<Type Name="tuple&lt;*,*&gt;">
  <DisplayString>({_Myfirst}, {???})</DisplayString>
</Type>

<Type Name="tuple&lt;*,*,*&gt;">
  <DisplayString>({_Myfirst}, {???}, {???})</DisplayString>
</Type>

etc?

Upvotes: 3

Views: 814

Answers (1)

Grant Peters
Grant Peters

Reputation: 7835

You'll have to modify the type a little to get this to work. What's required is a base_type typedef.

i.e.

// tuple 
template<class... _Types> class tuple;

// empty tuple
template<> class tuple<> {};

// recursive tuple definition
template<class _This,
class... _Rest>
class tuple<_This, _Rest...>
    : private tuple<_Rest...>
{
public:
    typedef tuple<_Rest...> base_type; // ***** Added this line

    _This _Myfirst;
};

Now we can recursively evaluate the base types with the natvis declarations:

<!-- Handle empty tuples -->
<Type Name="tuple&lt;&gt;">
    <DisplayString>()</DisplayString>
    <Expand/>
</Type>

<!-- Handle a single parameter (this is also our terminator for recursion) -->
<Type Name="tuple&lt;*&gt;">
    <DisplayString IncludeView="noparens">{_Myfirst}</DisplayString>
    <DisplayString ExcludeView="noparens">({_Myfirst})</DisplayString>
    <Expand>
        <Item Name="Value">_Myfirst</Item>
    </Expand>
</Type>

<!-- Handle 2 or more items -->
<Type Name="tuple&lt;*,*&gt;">
    <!-- show the first item and then recurse by casting this to 'base_type' -->
    <DisplayString IncludeView="noparens">{_Myfirst}, {*(base_type *)this,view(noparens)}</DisplayString>
    <!-- Wrap our display string that doesn't a have any parentheses, this will be only done for the top level tuple -->
    <DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
    <Expand>
        <!-- Show the top level item -->
        <Item Name="Value">_Myfirst</Item>
        <!-- Recursively expand our base types -->
        <ExpandedItem>*(base_type *)this</ExpandedItem>
    </Expand>
</Type>

And this is the result:

tuple .natvis result

Upvotes: 6

Related Questions