#region Copyright & License Information /* * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using System.Collections.Generic; using System.Linq; namespace OpenRA.Primitives { static class BitAllocator where T : struct { static int nextVal = 1; static Cache bits = new Cache(_ => Allocate()); static int Allocate() { if (nextVal == 0) throw new InvalidOperationException( "Too many values in BitAllocator<{0}>".F(typeof(T).Name)); var val = nextVal; nextVal <<= 1; return val; } public static int GetValue(string[] val) { return val.Select( a => bits[a] ).Aggregate( 0, (a,b) => a | b ); } public static IEnumerable GetStrings(int val) { for( var i = 0; i < 32; i++ ) { var x = 1 << i; if ((val & x) != 0) yield return bits.Single( a => a.Value == x ).Key; } } } public struct Bits : IEquatable> where T : struct { public int Value; public Bits(string[] val) { Value = BitAllocator.GetValue(val); } public Bits(Bits other) { Value = other.Value; } public override string ToString() { return BitAllocator.GetStrings(Value).JoinWith(","); } public static bool operator ==(Bits me, Bits other) { return (me.Value == other.Value); } public static bool operator !=(Bits me, Bits other) { return !(me == other); } public bool Equals(Bits other) { return other == this; } public override bool Equals(object obj) { return obj is Bits && Equals((Bits)obj); } public override int GetHashCode() { return Value.GetHashCode(); } } }