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 }