<?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 Condition="$T2 == 1"><![CDATA[{(storage & (1 << $T1)) != 0}]]></DisplayString>
    <DisplayString><![CDATA[{(storage >> $T1) & ((1 << $T2) - 1)}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>


  <!--Specialised versions for signed types-->
  <Type Name="BitField&lt;*,*,__int64&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))) != 0">
      <![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
    </DisplayString>
    <DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>

  <!-- Oh, and I can't do a generic match for all signed types, so these are identical to the __int64 case above 
       Would be nice if std::numeric_limits<$T3>::is_signed or std::is_signed<$T3>::value worked -->
  <Type Name="BitField&lt;*,*,__int32&gt;">
    <DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
      <![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
    </DisplayString>
    <DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>
  <Type Name="BitField&lt;*,*,__int16&gt;">
    <DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
      <![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
    </DisplayString>
    <DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>
  <Type Name="BitField&lt;*,*,__int8&gt;">
    <DisplayString Condition="(storage &amp; (1 &lt;&lt; ($T1 + $T2))) != 0">
      <![CDATA[{(-1 * (1 << ($T2-1))) + ((storage >> $T1) & ((1 << ($T2-1)) - 1))}]]>
    </DisplayString>
    <DisplayString><![CDATA[{(storage >> $T1) & ((1 << ($T2-1)) - 1)}]]></DisplayString>
    <Expand>
      <Item Name="Offset">$T1</Item>
      <Item Name="Size">$T2</Item>
    </Expand>
  </Type>
</AutoVisualizer>