<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright 2015 Scott Mansell
  All rights reserved.

  SPDX-License-Identifier: BSD-3-Clause
-->

<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
  <!--
    This is a re-implementation of the abstract bitfield class' algrothm (in BitField.h)
    for Visual Studio to use for pretty-printing during debugging.
  -->
  <Type Name="BitField&lt;*,*,*,*&gt;">
    <DisplayString><![CDATA[{($T3)((storage >> $T1) & ((1 << $T2) - 1))}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>

  <!-- Similar re-implementation for BitFieldArray -->
  <Type Name="BitFieldArray&lt;*,*,*,*,*&gt;">
    <Expand>
      <IndexListItems>
        <Size>$T3</Size>
        <ValueNode><![CDATA[($T4)((storage >> ($T1 + $T2*$i)) & ((1 << $T2) - 1))]]></ValueNode>
      </IndexListItems>
      <!-- Put these after the index list, so that the index list is the main thing in the unexpanded preview -->
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
      <Item Name="Count">$T3</Item>
    </Expand>
  </Type>

  <!--Specialised versions for signed types-->
  <Type Name="BitField&lt;*,*,signed char,*&gt;">
    <!-- It seems like we can't use s8/s16/s32/s64, nor can we use std::int8_t or the like; we have to use these names -->
    <AlternativeType Name="BitField&lt;*,*,short,*&gt;" />
    <AlternativeType Name="BitField&lt;*,*,int,*&gt;" />
    <AlternativeType Name="BitField&lt;*,*,long long,*&gt;" />

    <!-- This is what I have do to get a sign extension in this crappy natvis "language"
         Basically, we check the top bit, if it's one, we add the remaining
         bits to the smallest (most negative) number. -->
    <DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2 - 1))) != 0">
      <![CDATA[{($T3)((-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1)))}]]>
    </DisplayString>
    <DisplayString><![CDATA[{($T3)((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>

  <Type Name="BitFieldArray&lt;*,*,*,signed char,*&gt;">
    <AlternativeType Name="BitFieldArray&lt;*,*,*,short,*&gt;" />
    <AlternativeType Name="BitFieldArray&lt;*,*,*,int,*&gt;" />
    <AlternativeType Name="BitFieldArray&lt;*,*,*,long,*&gt;" />

    <Expand>
      <IndexListItems>
        <Size>$T3</Size>
        <ValueNode Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2 * $i + $T2 - 1))) != 0">
          <![CDATA[($T4)((-1 * (1 << ($T2-1))) + ((storage >> ($T1 + $T2*$i)) & ((1 << ($T2-1)) - 1)))]]>
        </ValueNode>
        <ValueNode><![CDATA[($T4)((storage >> ($T1 + $T2*$i)) & ((1 << ($T2-1)) - 1))]]></ValueNode>
      </IndexListItems>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
      <Item Name="Count">$T3</Item>
    </Expand>
  </Type>
</AutoVisualizer>
