//+------------------------------------------------------------------+ //| ArrayChar.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "Array.mqh" //+------------------------------------------------------------------+ //| Class CArrayChar. | //| Purpose: Class of dynamic array of char type values. | //| Derives from class CArray. | //+------------------------------------------------------------------+ class CArrayChar : public CArray { protected: char m_data[]; // data array public: CArrayChar(void); ~CArrayChar(void); //--- method of identifying the object virtual int Type(void) const { return(TYPE_CHAR); } //--- methods for working with files virtual bool Save(const int file_handle); virtual bool Load(const int file_handle); //--- methods of managing dynamic memory bool Reserve(const int size); bool Resize(const int size); bool Shutdown(void); //--- methods of filling the array bool Add(const char element); bool AddArray(const char &src[]); bool AddArray(const CArrayChar *src); bool Insert(const char element,const int pos); bool InsertArray(const char &src[],const int pos); bool InsertArray(const CArrayChar *src,const int pos); bool AssignArray(const char &src[]); bool AssignArray(const CArrayChar *src); //--- method of access to the array char At(const int index) const; char operator[](const int index) const { return(At(index)); } //--- methods of searching for minimum and maximum int Minimum(const int start,const int count) const { return(CArray::Minimum(m_data,start,count)); } int Maximum(const int start,const int count) const { return(CArray::Maximum(m_data,start,count)); } //--- methods of changing bool Update(const int index,const char element); bool Shift(const int index,const int shift); //--- methods of deleting bool Delete(const int index); bool DeleteRange(int from,int to); //--- methods for comparing arrays bool CompareArray(const char &array[]) const; bool CompareArray(const CArrayChar *array) const; //--- methods for working with the sorted array bool InsertSort(const char element); int Search(const char element) const; int SearchGreat(const char element) const; int SearchLess(const char element) const; int SearchGreatOrEqual(const char element) const; int SearchLessOrEqual(const char element) const; int SearchFirst(const char element) const; int SearchLast(const char element) const; int SearchLinear(const char element) const; protected: virtual void QuickSort(int beg,int end,const int mode=0); int QuickSearch(const char element) const; int MemMove(const int dest,const int src,int count); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CArrayChar::CArrayChar(void) { //--- initialize protected data m_data_max=ArraySize(m_data); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CArrayChar::~CArrayChar(void) { if(m_data_max!=0) Shutdown(); } //+------------------------------------------------------------------+ //| Moving the memory within a single array | //+------------------------------------------------------------------+ int CArrayChar::MemMove(const int dest,const int src,int count) { int i; //--- check parameters if(dest<0 || src<0 || count<0) return(-1); //--- check count if(src+count>m_data_total) count=m_data_total-src; if(count<0) return(-1); //--- no need to copy if(dest==src || count==0) return(dest); //--- check data total if(dest+count>m_data_total) { if(m_data_max=0;i--) m_data[dest+i]=m_data[src+i]; } //--- successful return(dest); } //+------------------------------------------------------------------+ //| Request for more memory in an array. Checks if the requested | //| number of free elements already exists; allocates additional | //| memory with a given step | //+------------------------------------------------------------------+ bool CArrayChar::Reserve(const int size) { int new_size; //--- check if(size<=0) return(false); //--- resize array if(Available()=size); } //+------------------------------------------------------------------+ //| Resizing (with removal of elements on the right) | //+------------------------------------------------------------------+ bool CArrayChar::Resize(const int size) { int new_size; //--- check if(size<0) return(false); //--- resize array new_size=m_step_resize*(1+size/m_step_resize); if(m_data_max!=new_size) { if((m_data_max=ArrayResize(m_data,new_size))==-1) { m_data_max=ArraySize(m_data); return(false); } } if(m_data_total>size) m_data_total=size; //--- result return(m_data_max==new_size); } //+------------------------------------------------------------------+ //| Complete cleaning of the array with the release of memory | //+------------------------------------------------------------------+ bool CArrayChar::Shutdown(void) { //--- check if(m_data_max==0) return(true); //--- clean if(ArrayResize(m_data,0)==-1) return(false); m_data_total=0; m_data_max=0; //--- successful return(true); } //+------------------------------------------------------------------+ //| Adding an element to the end of the array | //+------------------------------------------------------------------+ bool CArrayChar::Add(const char element) { //--- check/reserve elements of array if(!Reserve(1)) return(false); //--- add m_data[m_data_total++]=element; m_sort_mode=-1; //--- successful return(true); } //+------------------------------------------------------------------+ //| Adding an element to the end of the array from another array | //+------------------------------------------------------------------+ bool CArrayChar::AddArray(const char &src[]) { int num=ArraySize(src); //--- check/reserve elements of array if(!Reserve(num)) return(false); //--- add for(int i=0;i=m_data_total) return(CHAR_MAX); //--- result return(m_data[index]); } //+------------------------------------------------------------------+ //| Updating element in the specified position | //+------------------------------------------------------------------+ bool CArrayChar::Update(const int index,const char element) { //--- check if(index<0 || index>=m_data_total) return(false); //--- update m_data[index]=element; m_sort_mode=-1; //--- successful return(true); } //+------------------------------------------------------------------+ //| Moving element from the specified position | //| on the specified shift | //+------------------------------------------------------------------+ bool CArrayChar::Shift(const int index,const int shift) { char tmp_char; //--- check if(index<0 || index+shift<0 || index+shift>=m_data_total) return(false); if(shift==0) return(true); //--- move tmp_char=m_data[index]; if(shift>0) { if(MemMove(index,index+1,shift)<0) return(false); } else { if(MemMove(index+shift+1,index+shift,-shift)<0) return(false); } m_data[index+shift]=tmp_char; m_sort_mode=-1; //--- successful return(true); } //+------------------------------------------------------------------+ //| Deleting element from the specified position | //+------------------------------------------------------------------+ bool CArrayChar::Delete(const int index) { //--- check if(index<0 || index>=m_data_total) return(false); //--- delete if(indexto || from>=m_data_total) return(false); //--- delete if(to>=m_data_total-1) to=m_data_total-1; if(MemMove(from,to+1,m_data_total-to-1)<0) return(false); m_data_total-=to-from+1; //--- successful return(true); } //+------------------------------------------------------------------+ //| Equality comparison of two arrays | //+------------------------------------------------------------------+ bool CArrayChar::CompareArray(const char &array[]) const { //--- compare if(m_data_total!=ArraySize(array)) return(false); for(int i=0;i>1" is quick division by 2 p_char=m_data[(beg+end)>>1]; while(ip_char) { //--- control the output of the array bounds if(j==0) break; j--; } if(i<=j) { t_char=m_data[i]; m_data[i++]=m_data[j]; m_data[j]=t_char; //--- control the output of the array bounds if(j==0) break; j--; } } if(begelement) Insert(element,pos); else Insert(element,pos+1); //--- restore the sorting flag after Insert(...) m_sort_mode=0; //--- successful return(true); } //+------------------------------------------------------------------+ //| Search of position of element in a array | //+------------------------------------------------------------------+ int CArrayChar::SearchLinear(const char element) const { //--- check if(m_data_total==0) return(-1); //--- for(int i=0;i=i) { //--- ">>1" is quick division by 2 m=(j+i)>>1; if(m<0 || m>=m_data_total) break; t_char=m_data[m]; if(t_char==element) break; if(t_char>element) j=m-1; else i=m+1; } //--- position return(m); } //+------------------------------------------------------------------+ //| Search of position of element in a sorted array | //+------------------------------------------------------------------+ int CArrayChar::Search(const char element) const { int pos; //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search pos=QuickSearch(element); if(m_data[pos]==element) return(pos); //--- not found return(-1); } //+------------------------------------------------------------------+ //| Search position of the first element which is greater than | //| specified in a sorted array | //+------------------------------------------------------------------+ int CArrayChar::SearchGreat(const char element) const { int pos; //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search pos=QuickSearch(element); while(m_data[pos]<=element) if(++pos==m_data_total) return(-1); //--- position return(pos); } //+------------------------------------------------------------------+ //| Search position of the first element which is less than | //| specified in the sorted array | //+------------------------------------------------------------------+ int CArrayChar::SearchLess(const char element) const { int pos; //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search pos=QuickSearch(element); while(m_data[pos]>=element) if(pos--==0) return(-1); //--- position return(pos); } //+------------------------------------------------------------------+ //| Search position of the first element which is greater than or | //| equal to the specified in a sorted array | //+------------------------------------------------------------------+ int CArrayChar::SearchGreatOrEqual(const char element) const { //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search for(int pos=QuickSearch(element);pos=element) return(pos); //--- not found return(-1); } //+------------------------------------------------------------------+ //| Search position of the first element which is less than or equal | //| to the specified in a sorted array | //+------------------------------------------------------------------+ int CArrayChar::SearchLessOrEqual(const char element) const { //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search for(int pos=QuickSearch(element);pos>=0;pos--) if(m_data[pos]<=element) return(pos); //--- not found return(-1); } //+------------------------------------------------------------------+ //| Find position of first appearance of element in a sorted array | //+------------------------------------------------------------------+ int CArrayChar::SearchFirst(const char element) const { int pos; //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search pos=QuickSearch(element); if(m_data[pos]==element) { while(m_data[pos]==element) if(pos--==0) break; return(pos+1); } //--- not found return(-1); } //+------------------------------------------------------------------+ //| Find position of last appearance of element in a sorted array | //+------------------------------------------------------------------+ int CArrayChar::SearchLast(const char element) const { int pos; //--- check if(m_data_total==0 || !IsSorted()) return(-1); //--- search pos=QuickSearch(element); if(m_data[pos]==element) { while(m_data[pos]==element) if(++pos==m_data_total) break; return(pos-1); } //--- not found return(-1); } //+------------------------------------------------------------------+ //| Writing array to file | //+------------------------------------------------------------------+ bool CArrayChar::Save(const int file_handle) { int i=0; //--- check if(!CArray::Save(file_handle)) return(false); //--- write array length if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE) return(false); //--- write array for(i=0;i