diff --git a/Collection/ArraySet.mqh b/Collection/ArraySet.mqh new file mode 100644 index 0000000..346b8e8 --- /dev/null +++ b/Collection/ArraySet.mqh @@ -0,0 +1,66 @@ +//+------------------------------------------------------------------+ +//| Module: Collection/ArraySet.mqh | +//| This file is part of the mql4-lib project: | +//| https://github.com/dingmaotu/mql4-lib | +//| | +//| Copyright 2015-2018 Li Ding | +//| | +//| Licensed under the Apache License, Version 2.0 (the "License"); | +//| you may not use this file except in compliance with the License. | +//| You may obtain a copy of the License at | +//| | +//| http://www.apache.org/licenses/LICENSE-2.0 | +//| | +//| Unless required by applicable law or agreed to in writing, | +//| software distributed under the License is distributed on an | +//| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | +//| either express or implied. | +//| See the License for the specific language governing permissions | +//| and limitations under the License. | +//+------------------------------------------------------------------+ +#property strict + +#include "Vector.mqh" +#include "Set.mqh" +//+------------------------------------------------------------------+ +//| Simple Set implementation using an vector (no repeated elements) | +//+------------------------------------------------------------------+ +template +class ArraySet: public Set + { +private: + Vectorm_vector; +public: + ArraySet(bool owned=false,EqualityComparer*comparer=NULL):Set(owned,comparer),m_vector(owned,10,comparer){} + ~ArraySet() {} + + // CosntIterator interface + ConstIterator*constIterator() const {return m_vector.constIterator();} + // Iterator interface + Iterator*iterator() {return new ArraySetIterator(GetPointer(m_vector),m_owned);} + + // Collection interface + void clear() {m_vector.clear();} + int size() const {return m_vector.size();} + bool add(T value) + { + if(m_vector.contains(value)) return false; + else return m_vector.add(value); + } + bool remove(const T value) {return m_vector.remove(value);} + bool contains(const T value) const {return m_vector.contains(value);} + }; +//+------------------------------------------------------------------+ +//| Iterator implementation for ArraySet | +//| Overrides VectorIterator.add: ensure no repeated elements can | +//| be added to the ArraySet | +//+------------------------------------------------------------------+ +template +class ArraySetIterator: public VectorIterator + { +public: + ArraySetIterator(Vector*v,bool owned):VectorIterator(v,owned) {} + // you can not set a value during Set iteration + virtual bool set(T value) {return false;} + }; +//+------------------------------------------------------------------+ diff --git a/Collection/HashSet.mqh b/Collection/HashSet.mqh index 90416e7..a13ae1c 100644 --- a/Collection/HashSet.mqh +++ b/Collection/HashSet.mqh @@ -22,7 +22,7 @@ #include "HashEntries.mqh" #include "HashSlots.mqh" -#include "Collection.mqh" +#include "Set.mqh" //+------------------------------------------------------------------+ //| storage for actual entries | //+------------------------------------------------------------------+ @@ -61,7 +61,7 @@ public: //| Set based on open addressing hash table | //+------------------------------------------------------------------+ template -class HashSet: public Collection +class HashSet: public Set { private: HashSetEntriesm_entries; @@ -72,7 +72,7 @@ public: //--- by default the HashSet do not own its elements //--- if the hash elements are pointers and the real owner wants to //--- transfer the ownership to this collection, then she need to explicitly `new HashSet(NULL,true)` - HashSet(EqualityComparer*comparer=NULL,bool owned=false):Collection(owned,comparer),m_slots(m_comparer,GetPointer(m_entries)) {} + HashSet(EqualityComparer*comparer=NULL,bool owned=false):Set(owned,comparer),m_slots(m_comparer,GetPointer(m_entries)) {} ~HashSet() { if(m_owned) diff --git a/Collection/Set.mqh b/Collection/Set.mqh index efe3ee0..75cd92a 100644 --- a/Collection/Set.mqh +++ b/Collection/Set.mqh @@ -3,7 +3,7 @@ //| This file is part of the mql4-lib project: | //| https://github.com/dingmaotu/mql4-lib | //| | -//| Copyright 2015-2016 Li Ding | +//| Copyright 2015-2018 Li Ding | //| | //| Licensed under the Apache License, Version 2.0 (the "License"); | //| you may not use this file except in compliance with the License. | @@ -20,74 +20,71 @@ //+------------------------------------------------------------------+ #property strict -#include "../Lang/Array.mqh" #include "Collection.mqh" //+------------------------------------------------------------------+ -//| Simple Set implementation using an array | +//| The Set interface | +//| A set does not allow duplicates | //+------------------------------------------------------------------+ template class Set: public Collection { -private: - Arraym_array; public: - // Iterator interface - Iterator*iterator() const {return new SetIterator(m_array);} - // for Set initial buffer set to zero - Set(int buffer=0):m_array(buffer){} - // Collection interface - void clear() {m_array.clear();} - int size() const {return m_array.size();} - bool add(T value); - bool remove(const T value); + Set(bool owned,EqualityComparer*comparer):Collection(owned,comparer){} - bool contains(const T value) {return m_array.index(value)>=0;} - }; -//+------------------------------------------------------------------+ -//| Add the element if the element is not in this set | -//+------------------------------------------------------------------+ -template -bool Set::add(T value) - { - int index=m_array.index(value); - if(index>=0) - return false; - else + virtual bool setByIntersection(const Collection&left,const Collection&right) { - m_array.insertAt(size(),value); - return true; + if(!isEmpty()) + { + clear(); + } + + for(ConstIterit(left); !it.end(); it.next()) + { + T value=it.current(); + if(right.contains(value)) + // Notice if elements of left or right are owned by their container and they are pointers + // and this Set is also owned, + // you should deal with the owning problem on your own + add(it.current()); + } + return size() > 0; } - } -//+------------------------------------------------------------------+ -//| Remove the element that is equal to value | -//+------------------------------------------------------------------+ -template -bool Set::remove(const T value) - { - int index=m_array.index(value); - if(index>=0) + + virtual bool setByUnion(const Collection&left,const Collection&right) { - m_array.removeAt(index); - return true; + if(!isEmpty()) + { + clear(); + } + for(ConstIterit(left); !it.end(); it.next()) + { + add(it.current()); + } + + for(ConstIterit(right); !it.end(); it.next()) + { + add(it.current()); + } + return size() > 0; + } + + virtual bool setByComplement(const Collection&left,const Collection&right) + { + if(!isEmpty()) + { + clear(); + } + + if(left.isEmpty()) return false; + + for(ConstIterit(left); !it.end(); it.next()) + { + T value=it.current(); + if(!right.contains(value)) + add(it.current()); + } + + return size() > 0; } - else - return false; - } -//+------------------------------------------------------------------+ -//| Iterator implementation for Set | -//+------------------------------------------------------------------+ -template -class SetIterator: public Iterator - { -private: - int m_index; - const int m_size; - Array*m_a; -public: - SetIterator(const Array&v):m_index(0),m_size(v.size()),m_a((Array*)GetPointer(v)) {} - bool end() const {return m_index>=m_size;} - void next() {if(!end()){m_index++;}} - T current() const {return m_a[m_index];} - bool set(T value) {m_a.set(m_index,value);return true;} }; //+------------------------------------------------------------------+ diff --git a/Collection/Vector.mqh b/Collection/Vector.mqh index 783efd8..a5f339c 100644 --- a/Collection/Vector.mqh +++ b/Collection/Vector.mqh @@ -188,7 +188,7 @@ public: void next() {if(!end()){m_index++;}} T current() const {if(removed()) return NULL; else return m_vector[m_index];} - bool set(T value) {if(removed()) return false; m_vector.set(m_index,value);return true;} + virtual bool set(T value) {if(removed()) return false; m_vector.set(m_index,value); return true;} bool remove() { if(end()) return false;