1 //fixme fugly, wrong place 2 module glued.set; 3 4 import std.traits; 5 import std.conv; 6 import std.array; 7 import std.range; 8 import std.algorithm; 9 10 struct Set(T) { 11 private bool[T] backend; 12 13 bool put(T val){ 14 if (val in backend) 15 return false; 16 backend[val] = true; 17 return true; 18 } 19 20 alias add = put; 21 alias insert = put; 22 23 size_t putMany(Range)(Range data){ 24 if (isInputRange!Range && is(ElementType!Range == T)) { 25 size_t added = 0; 26 foreach (t; data) 27 if (put(t)) 28 added += 1; 29 return added; 30 } 31 } 32 33 alias addMany = putMany; 34 alias addAll = putMany; 35 36 bool contains(T val){ 37 return (val in backend) != null; 38 } 39 40 bool remove(T val){ 41 return backend.remove(val); 42 } 43 44 @property 45 size_t length(){ 46 return backend.length; 47 } 48 49 @property 50 auto asRange(){ 51 return backend.keys()[]; 52 } 53 54 Set!T2 asSetOf(T2)() {//todo if traits: isAssignable(T2, T) 55 return Set!T2.of(asRange.map!(x => cast(T2) x)); 56 } 57 58 //fixme this requires Set!T.of(...) - make Set.of!T(...) variant that is easily syntax-sugared to Set.of(...) 59 static Set!T of(Range)(Range data) if (isInputRange!Range && is(ElementType!Range == T)) { 60 Set!(T) result; 61 result.addAll(data); 62 return result; 63 } 64 }