///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
using System.Collections.Generic;
using System.Linq;
namespace wasSharp
{
public static class BitTwiddling
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
///
/// Swaps two integers passed by reference using XOR.
///
/// first integer to swap
/// second integer to swap
public static void XORSwap(ref int q, ref int p)
{
q ^= p;
p ^= q;
q ^= p;
}
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
///
/// Checks whether a flag is set for a bitmask.
///
/// a data type
/// a data type
/// the mask to check the flag for
/// the flag to check
/// true in case the flag is set
public static bool IsMaskFlagSet(this T mask, U flag) where T : struct where U : struct
{
return unchecked(mask as dynamic & flag as dynamic) != 0;
}
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
///
/// Sets a flag for a bitmask.
///
/// a data type
/// a data type
/// the mask to set the flag on
/// the flag to set
public static void SetMaskFlag(ref T mask, U flag) where T : struct where U : struct
{
mask = unchecked(mask as dynamic | flag as dynamic);
}
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
///
/// Create a bitmask from multiple flags.
///
/// a data type
/// the flags to set
/// a bitmask
public static T CreateMask(this IEnumerable flag) where T : struct
{
return flag.Aggregate((o, p) => unchecked(o as dynamic | p as dynamic));
}
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
///
/// Unset a flag for a bitmask.
///
/// a data type
/// a data type
/// the mask to unset the flag on
/// the flag to unset
public static void UnsetMaskFlag(ref T mask, U flag)
{
mask = unchecked(mask as dynamic & ~(flag as dynamic));
}
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
///
/// Toggle a flag for a bitmask.
///
/// a data type
/// a data type
/// the mask to toggle the flag on
/// the flag to toggle
public static void ToggleMaskFlag(ref T mask, U flag)
{
mask = unchecked(mask as dynamic ^ flag as dynamic);
}
///
/// Computes the previous power of two.
///
/// the integer
/// the previous power of two
/// Adapted from Hacker's Delight ISBN-10:0201914654
public static T PreviousPowerOfTwo(this T x)
{
var y = x as dynamic;
unchecked
{
y = y | (y >> 1);
y = y | (y >> 2);
y = y | (y >> 4);
y = y | (y >> 8);
y = y | (y >> 16);
return y - (y >> 1);
}
}
///
/// Determines if a number is a power of two.
///
/// the number type
/// the number
/// true of the number is a power of two
public static bool IsPowerOfTwo(this T x)
{
var y = x as dynamic;
return (y != 0) && ((y & (y - 1)) == 0);
}
}
}