1 /** 2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved. 3 Authors: Jacob Carlborg 4 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 5 6 Copied from DStep. 7 8 Convenient functions for a set. 9 */ 10 module dextool.set; 11 12 import std.range : ElementType; 13 14 alias Set(T) = void[0][T]; 15 16 void add(T)(ref void[0][T] self, T value) { 17 self[value] = (void[0]).init; 18 } 19 20 /// Merge set into self 21 void add(T)(ref void[0][T] self, void[0][T] set) { 22 foreach (key; set.byKey) { 23 self.add(key); 24 } 25 } 26 27 void remove(T)(ref void[0][T] self, T value) { 28 self.remove(value); 29 } 30 31 Set!T clone(T)(ref void[0][T] self) { 32 Set!T result; 33 result.add(self); 34 return result; 35 } 36 37 bool contains(T)(inout(void[0][T]) set, T value) { 38 return (value in set) !is null; 39 } 40 41 /** The set difference according to Set Theory. 42 * 43 * It is the set of all members in `self` that are not members of `set`. 44 */ 45 SetT setDifference(SetT)(ref SetT self, SetT set) { 46 import std.algorithm : filter; 47 48 SetT r; 49 foreach (k; self.byKey.filter!(a => !set.contains(a))) { 50 r.add(k); 51 } 52 53 return r; 54 } 55 56 /** The symmetric difference according to Set Theory. 57 * 58 * It is the set of all objects that are a member of exactly one of `self` and `set`. 59 */ 60 SetT symmetricDifference(SetT)(ref SetT self, SetT set) { 61 import std.algorithm : filter; 62 63 SetT r; 64 foreach (k; self.byKey.filter!(a => !set.contains(a))) { 65 r.add(k); 66 } 67 foreach (k; set.byKey.filter!(a => !self.contains(a))) { 68 r.add(k); 69 } 70 71 return r; 72 } 73 74 /** The intersection according to Set Theory. 75 * 76 * It is the set of all objects that are members of both `self` and `set`. 77 */ 78 SetT intersect(SetT)(ref SetT self, SetT set) { 79 import std.algorithm : filter; 80 81 SetT r; 82 foreach (k; self.byKey.filter!(a => set.contains(a))) { 83 r.add(k); 84 } 85 86 return r; 87 } 88 89 Set!T setFromList(T)(T[] list) { 90 import std.traits; 91 92 Set!(Unqual!T) result; 93 94 foreach (item; list) 95 result.add(item); 96 97 return result; 98 } 99 100 Set!T setFromRange(T, RangeT)(RangeT range) if (is(ElementType!RangeT == T)) { 101 import std.traits; 102 103 Set!(Unqual!T) result; 104 105 foreach (item; range) 106 result.add(item); 107 108 return result; 109 } 110 111 auto setToList(T)(ref Set!T set) { 112 import std.array : appender; 113 114 auto app = appender!(T[])(); 115 foreach (key; set.byKey) 116 app.put(key); 117 return app.data; 118 } 119 120 /// Specify the template type or it doesn't work. 121 auto setToRange(T)(ref inout Set!T set) { 122 return set.byKey; 123 }