// Mike Linford, 2012
module mml.sets;
version(useInterface) interface Set(T)
{
// add value to the set
bool add(in T value)
out { assert(contains(value)); }
// remove value from the set
bool remove(in T value)
out { assert(!contains(value)); }
// return whether or not the value is in the set
bool contains(in T value) const;
// return the number of items in the set
@property size_t count() const;
// iterate through the elements of the set
int opApply(int delegate(ref T) dg) const;
}
version(useAbstractClass) abstract class Set(T)
{
// add value to the set
bool add(in T value)
out { assert(contains(value)); }
body { return false; }
// remove value from the set
bool remove(in T value)
out { assert(!contains(value)); }
body { return false; }
// return whether or not the value is in the set
bool contains(in T value) const;
// return the number of items in the set
@property size_t count() const;
// iterate through the elements of the set
int opApply(int delegate(ref T) dg) const;
}
class ArraySet(T) : Set!T
{
// fields
private T[] _array;
// methods
override bool add(in T value)
{
if(contains(value))
return false;
_array ~= value;
return true;
}
override bool remove(in T value)
{
if(!contains(value))
return false;
size_t index;
for(index = 0; index < _array.length; index++)
if(_array[index] == value)
break;
assert(index < _array.length);
assert(_array[index] == value);
_array = _array[0..index] ~ _array[index + 1..$];
return true;
}
override bool contains(in T value) const
{
foreach(arrayElement; _array)
if(arrayElement == value)
return true;
return false;
}
override @property size_t count() const
{
return _array.length;
}
override int opApply(int delegate(ref T) dg) const
{
foreach(arrayElement; _array)
{
T temp = arrayElement;
int result = dg(temp);
if(result != 0)
return result;
}
return 0;
}
}
unittest
{
Set!int arraySet = new ArraySet!int();
arraySet.add(5);
}