Skip to content

Instantly share code, notes, and snippets.

@airbreather
Last active August 29, 2015 14:07
Show Gist options
  • Save airbreather/dbabd1c8799d0594eebf to your computer and use it in GitHub Desktop.
Save airbreather/dbabd1c8799d0594eebf to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace HelperTypes
{
public sealed class BitList : IReadOnlyList<bool>
{
private readonly List<int> values = new List<int>();
private int version;
public int Count { get; private set; }
public bool this[int index]
{
get
{
if (this.Count <= index)
{
throw new ArgumentOutOfRangeException("index", index, "Too big.");
}
return (this.values[index / 32] & (1u << (index % 32))) > 0;
}
}
public void Add(bool value)
{
int offset = this.Count % 32;
if (offset == 0)
{
this.values.Add(0);
}
if (value)
{
this.values[this.values.Count - 1] |= (1 << offset);
}
this.Count++;
this.version++;
}
public void Clear()
{
this.values.Clear();
this.Count = 0;
this.version++;
}
public bool Contains(bool item)
{
return item ?
this.values.Any(x => x != 0) :
this.values.All(x => x != 0);
}
public BitArray ToBitArray()
{
return new BitArray(this.values.ToArray())
{
Length = this.Count
};
}
public void TrimExcess()
{
this.values.TrimExcess();
}
public IEnumerator<bool> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
private sealed class Enumerator : IEnumerator<bool>
{
private readonly BitList lst;
private readonly int version;
private int currIndex;
private bool curr;
internal Enumerator(BitList lst)
{
this.lst = lst;
this.version = lst.version;
this.currIndex = 0;
this.curr = false;
}
public bool Current
{
get { return this.curr; }
}
object IEnumerator.Current
{
get { return this.Current; }
}
public bool MoveNext()
{
if (this.version != this.lst.version)
{
throw new InvalidOperationException("Collection was modified during enumeration.");
}
if (this.lst.Count <= this.currIndex)
{
return false;
}
this.curr = this.lst[this.currIndex++];
return true;
}
public void Reset()
{
if (this.version != this.lst.version)
{
throw new InvalidOperationException("Collection was modified during enumeration.");
}
this.currIndex = 0;
}
public void Dispose()
{
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment