diff --git a/Collection/SortComparer.mqh b/Collection/SortComparer.mqh new file mode 100644 index 0000000..4b4283f --- /dev/null +++ b/Collection/SortComparer.mqh @@ -0,0 +1,49 @@ +//+------------------------------------------------------------------+ +//| Module: Collection/SortComparer.mqh | +//| This file is part of the mql4-lib project: | +//| https://github.com/dingmaotu/mql4-lib | +//| | +//| Copyright 2017 Li Ding | +//| Copyright 2017 Yerden Zhumabekov | +//| | +//| 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. | +//+------------------------------------------------------------------+ +#include "../Lang/Hash.mqh" +#include "EqualityComparer.mqh" +#property strict +//+------------------------------------------------------------------+ +//| Sort comparer is useful for sorted sets, arrays etc. | +//+------------------------------------------------------------------+ +template +class SortComparer: public EqualityComparer + { + // Sort comparison: + // >0 if left>right + // <0 if left +class GenericSortComparer: public SortComparer + { +public: + virtual int compare(const T left,const T right) const override {return leftright;} + virtual int hash(const T value) const override {return Hash(value);} + }; +//+------------------------------------------------------------------+ diff --git a/Collection/SortedArray.mqh b/Collection/SortedArray.mqh new file mode 100644 index 0000000..07ef5b2 --- /dev/null +++ b/Collection/SortedArray.mqh @@ -0,0 +1,170 @@ +//+------------------------------------------------------------------+ +//| Module: Collection/SortedArray.mqh | +//| This file is part of the mql4-lib project: | +//| https://github.com/dingmaotu/mql4-lib | +//| | +//| Copyright 2015-2016 Li Ding | +//| Copyright 2018 Yerden Zhumabekov +class SortedArray: public Collection + { +private: + SortComparer*m_sorter; + Arraym_array; + bool m_unique; + bool bsearch(const T value,int &id) const; +public: + // owned: flag restricts destructor to delete array elements + // unique: flag allows add()-ing of identical elements + // sorter: array sorting implementation + SortedArray(bool owned=true,bool unique=true,SortComparer*sorter=NULL): + Collection(owned,sorter), + m_unique(unique), + m_sorter(sorter==NULL?new GenericSortComparer():sorter){} + ~SortedArray() {SafeDelete(m_sorter);} + + // ConstIterator interface + ConstIterator*constIterator() const {return new ConstSortedArrayIterator(GetPointer(this));} + // Iterator interface + Iterator*iterator() {return new SortedArrayIterator(GetPointer(this),m_owned);} + + // Collection interface + void clear() {m_array.clear();} + bool add(T value); + bool remove(const T value); + int size() const {return m_array.size();} + bool contains(const T value) const {return index(value)>=0;} + + // SortedArray specific + T operator[](const int index) const {return m_array[index];} + // return index of a matched element, or <0 if not contained + int index(const T value) const {int id=0;return bsearch(value,id)?id:-1;} + int removeIndices(const int &removed[]) + { + if(m_owned) + for(int i=0; i +bool SortedArray::bsearch(const T value,int &id) const + { + int cmp=1,l=0,u=m_array.size(); + + while(l0) l=idx+1; + else u=l=idx; + } + + id=u; + return cmp==0; + } +//+------------------------------------------------------------------+ +//| Add value to sorted array | +//+------------------------------------------------------------------+ +template +bool SortedArray::add(T value) + { + int id; + bool res=!bsearch(value,id); + res=res || !m_unique; + if(res) m_array.insertAt(id,value); + return res; + } +//+------------------------------------------------------------------+ +//| Remove value from sorted array | +//+------------------------------------------------------------------+ +template +bool SortedArray::remove(const T value) + { + int id; + if(!bsearch(value,id)) + return false; + T ovalue=m_array[id]; + m_array.removeAt(id); + if(m_owned) SafeDelete(ovalue); + return true; + } +//+------------------------------------------------------------------+ +//| ConstIterator implementation for SortedArray | +//+------------------------------------------------------------------+ +template +class ConstSortedArrayIterator: public ConstIterator + { +private: + int m_index; + const int m_size; + const SortedArray*m_sortedarray; +public: + ConstSortedArrayIterator(const SortedArray*v):m_index(0),m_size(v.size()),m_sortedarray(v) {} + bool end() const {return m_index>=m_size;} + void next() {if(!end()){m_index++;}} + T current() const {return m_sortedarray[m_index];} + }; +//+------------------------------------------------------------------+ +//| Iterator implementation for SortedArray | +//+------------------------------------------------------------------+ +template +class SortedArrayIterator: public Iterator + { +private: + int m_index; + const int m_size; + SortedArray*m_sortedarray; + int m_removed[]; +protected: + bool removed() const + { + int s=ArraySize(m_removed); + return (s>0 && m_removed[s-1]==m_index); + } +public: + SortedArrayIterator(SortedArray*v,bool owned):m_index(0),m_size(v.size()),m_sortedarray(v){} + ~SortedArrayIterator() {if(ArraySize(m_removed)>0) m_sortedarray.removeIndices(m_removed);} + bool end() const {return m_index>=m_size;} + void next() {if(!end()){m_index++;}} + T current() const {if(removed()) return NULL; else return m_sortedarray[m_index];} + + bool set(T value) {return false;} // unapplicable + bool remove() + { + if(end()||removed()) return false; + int s=ArraySize(m_removed); + ArrayResize(m_removed,s+1,5); + m_removed[s]=m_index; + return true; + } + }; +//+------------------------------------------------------------------+ diff --git a/Lang/Array.mqh b/Lang/Array.mqh index 762b679..ab6b6d5 100644 --- a/Lang/Array.mqh +++ b/Lang/Array.mqh @@ -21,6 +21,9 @@ #property strict //+------------------------------------------------------------------+ //| Generic array insert | +//| Inserts value at index into array. | +//| Array expands to contain new element but only in case no holes | +//| appear in new array. | //+------------------------------------------------------------------+ template void ArrayInsert(T &array[],int index,T value,int extraBuffer=10) @@ -200,6 +203,7 @@ public: void insertAt(int index,T value) {ArrayInsert(m_array,index,value,m_extraBuffer);} void removeAt(int index) {ArrayDelete(m_array,index);} int removeAll(const T value) {return ArrayDeleteAll(m_array,value);} + int removeBatch(const int &removed[]) {return ArrayBatchRemove(m_array,removed);} int index(const T value) const; };