Construct set to store at most length number of bits.
Maximum number of elements in filter.
Get current capacity in number of elements (bits). If growable is Growable.yes then capacity is variable, otherwise it's constant.
Insert element e if it's present otherwise remove it.
Check if element e is stored/contained.
Insert element e.
Check if element e is stored/contained.
Remove element e.
Construct from inferred capacity and length elementMaxCount.
alias E = uint; import std.range.primitives : isOutputRange; alias Set = DenseSetFilter!(E, Growable.no); static assert(isOutputRange!(Set, E)); const set0 = Set(); assert(set0.capacity == 0); const length = 2^^6; auto set = DenseSetFilter!(E, Growable.no)(2*length); const y = set.dup; assert(y.capacity == 2*length); foreach (const ix; 0 .. length) { assert(!set.contains(ix)); assert(ix !in set); assert(!set.insert(ix)); assert(set.contains(ix)); assert(ix in set); assert(set.complement(ix)); assert(!set.contains(ix)); assert(ix !in set); assert(!set.complement(ix)); assert(set.contains(ix)); assert(ix in set); assert(!set.contains(ix + 1)); } auto z = set.dup; foreach (const ix; 0 .. length) { assert(z.contains(ix)); assert(ix in z); } foreach (const ix; 0 .. length) { assert(set.contains(ix)); assert(ix in set); } foreach (const ix; 0 .. length) { assert(set.contains(ix)); set.remove(ix); assert(!set.contains(ix)); }
alias E = uint; auto set = DenseSetFilter!(E, Growable.yes)(); assert(set._length == 0); const length = 2^^16; foreach (const ix; 0 .. length) { assert(!set.contains(ix)); assert(ix !in set); assert(!set.insert(ix)); assert(set.contains(ix)); assert(ix in set); assert(set.complement(ix)); assert(!set.contains(ix)); assert(ix !in set); assert(!set.complement(ix)); assert(set.contains(ix)); assert(ix in set); assert(!set.contains(ix + 1)); }
test RefCounted storage
import std.typecons : RefCounted; alias E = int; RefCounted!(DenseSetFilter!(E, Growable.yes)) set; assert(set._length == 0); assert(set.capacity == 0); assert(!set.insert(0)); assert(set._length == 1); assert(set.capacity == 2); const y = set; foreach (const e; 1 .. 1000) { assert(!set.insert(e)); assert(set._length == e + 1); assert(y._length == e + 1); } const set1 = RefCounted!(DenseSetFilter!(E, Growable.yes))(42); assert(set1._length == 42); assert(set1.capacity == 64);
enum E : ubyte { a, b, c, d, dAlias = d } auto set = DenseSetFilter!(E, Growable.yes)(); assert(set._length == 0); import std.traits : EnumMembers; foreach (const lang; [EnumMembers!E]) { assert(!set.contains(lang)); } foreach (const lang; [EnumMembers!E]) { set.insert(lang); assert(set.contains(lang)); }
enum E : ubyte { a, b, c, d, dAlias = d } auto set = DenseSetFilter!(E, Growable.no).withInferredLength(); // TODO use instantiator function here assert(set.capacity == typeof(set).elementMaxCount); static assert(!__traits(compiles, { assert(set.contains(0)); })); static assert(!__traits(compiles, { assert(set.insert(0)); })); static assert(!__traits(compiles, { assert(0 in set); })); import std.traits : EnumMembers; foreach (const lang; [EnumMembers!E]) { assert(!set.contains(lang)); assert(lang !in set); } foreach (const lang; [EnumMembers!E]) { set.insert(lang); assert(set.contains(lang)); assert(lang in set); }
Store presence of elements of type E in a set in the range 0 .. length.
Can be seen as a generalization of std.typecons.BitFlags to integer types.
Typically used to implement very fast membership checking. For instance in graph traversal algorithms, this filter is typically used as a temporary set node (integer) ids that checks if a node has been previously visisted or not.