#region Copyright & License Information /* * Copyright 2007-2015 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(); } } }