Welcome Forex EA downloads & MT4/MT5 auto-trading resources — EAs, Gold EAs, quant tools and real-world automation.
Sign In Sign Up

Object List - MetaTrader 5 Library | MT5 EA Download - MetaTrader 5 Resources

author EAcpu | 4 reads | 0 comments |
/**********************************************************************
The List class template provides a basic container for storing ordered lists of objects.
For convenience, List also provides synonyms for stack operations,
 This makes stacking code using List more explicit without having to define another class.
/**/


/************************************************************************/
template < type name > class object list { public :
//Construct, destroy, initialize, assign object list ( boolean memory delete = true ): mdelete(memdelete) {}
                    ObjectList(ObjectList&src) {mdelete=src.mdelete; copy(items, src.items); copy(mem, src.mem);}
                    ~ObjectList() {delete all(); if (mdelete) EmptyMem();}
  Object List Operator = (Object List &);
Blank memory delete ( boolean memdelete) {mdelete=memdelete;}
//Access time* operator []( integer i) { return get(i);}
  T* get( integer in) { integer c = count(); if (c> 0 && in >= 0 && in  return item[in]; } return invalid ; }
  T* first() { integer c = count(); if (c > 0 ) { return items[ 0 ]; } return void ; }
  T* last() { integer c = count(); if (c> 0 ){ return items[c- 1 ];} return void ;}
Boolean value TryGet(T*dst, integer in) { if ((dst=get(at))!= invalid ) { return true ;} else { return false ;}}
// integer count(){KillBad(); return array size (items);}
integer find(t*items) { integer c = count(); for ( integer i = 0 ; i  if (item == item[i]) { return i;}} return - 1 ;}
blank print hash() { for ( integer i = 0 ; i < array_size (item); i++) { print format ( "%d:%d(%s)" , i, hash(item[i]), typename (item[i]));}}
integer hash(T*items){ string s; string concatenation (s, s, items); return ( integer ) string to integer (s);}
integer hash( integer at) {T*p=Get(at); return (p!= invalid )?Hash(p): 0 ;}
//Add blank operator +=(T*item) {append(item);}
Blank operator ^=(T*item) {prefix(item);}
blank append(T*item) {append(item, item);}
blank prep(T*item){IncreaseAt( 0 );item[ 0 ]=item;}
//Delete blank operator -=(T*item) {Delete(item, 0 );}
Blank operator /=(T*item) {delete(item, 1 );}
blank operator ~() {delete all();}
blank delete(t*item, boolean delete= 0 ) { integer f = find(item); if (f>- 1 ) {{ss="keyword">if (del) {delete(item);} else {Append(item,mem);}}ReduceAt(f);}} blank delete last( boolean delete= 0 ) {KillBad(); if (del) {delete(first());} else {append(first(), mem);} ReduceAt( 0 );} blank delete all ( boolean delete = 0 ); //stack interface T * top() {return last();} blank push(t* item) {append( item );} T * Pop ( ) {T*top= Top (); remove last(); return to top; } protected: T* items[]; T* mem[]; boolean remove ; // service blank append(T* items, T*&dst[]) { int r = array resize (daylight saving time, array size (daylight saving time) + 1 ); dst[r- 1 ] = items; } blank clear memory() { for (integer i = 0 ; i < array size (mem); i++) { delete (mem[i]); } array free (mem); } blank delete(t*item) { if ( check pointer (item) == 1 ) delete item; } blank killBad() { for ( integer i = 0 ; i < array size (item); i++) { if (item[i] == void ) {ReduceAt(i); i - ; } } whitespace reduce( integer ); whitespace increase at( integer ); whitespace copy(T*&dst[], T*&src[]) { integer c = array_size (source); array_resize (dst, c); for ( integer i = 0 ; i  /**/


/**********************************************************************
Structural Notes By default, when a list is destroyed, it deletes all dynamic objects.
      Automatic objects will be destroyed anyway.
      This means you don't have to use the delete operator on any object you create.
      Once an object is added to the list, it won't forget it,
      and be able to access it to erase on destruction.
      Anything deleted from the list will be transferred to the Recycle Bin.
      To be on the safe side, keep the "dangling" pointer,
      This minimizes the chance of a "bad pointer access" fatal error.
      In most cases this is reasonable because today's computers have a lot of memory.
      There is no big burden on efficiency, just memory, albeit a small one.
      However, for flexibility, the Remove method can choose to permanently delete the deleted object.
      If you need to persist objects after the list is destroyed (rare),
      Use the MemDelete method to set the memdelete flag to false.
      The "del" parameter in the Remove method is a flag used to remove the object from memory.
      Access to the object will no longer be available and a fatal error will be raised.
  The list only keeps references to valid objects, removing null pointers on access/count attempts.
      However, if you use an access method with a pointer return and try to access the wrong index,
      You will get a null pointer which means wrong index.
      There is a classic workaround: the TryGet method writes to the pointer and tells you that if the returned pointer is valid, then if the method returns false, the pointer should not be used.
  The hash method returns the Mql internal object "hash code" as you can see when you try to print the object/pointer.
      I'm not sure how these codes are generated, but they seem to be pretty reliable at identifying objects with ==.
Available operators:
   [index] gets, for example. Class T* pointer=list[3];
   += Append, for example. List += pointer; //List +=& object;
   ^= prepended, for example. List^=pointer; //List+=&object;
   -= delete, eg. List -= pointer; //List +=& object;
   /= delete and delete, eg. List/= pointer; //List+=& object;
   ~Delete all, eg. ~list;
   = copy list, eg. Class list A = list B; //A-new, B-existing/**/


 /**********************************************************************
ObjectList usage example/************************************************************************/
blank start ()
  {
  object list list;
  A*o1= new B(); //dynamic A o2; //automatic A*o3=&o2; //automatic /**/ list+=&o2; //append object reference list^=o1; //prefix list+=o3; //append pointer list.PrintHash(); //view output /**/ { string s; for ( integer i = 0 ; i < 13 ; i++) {s+= "-" ;} Print (s);}
/**/ list-=&o2; //Eliminate ObjectList list2=list; //Copy list list2.PrintHash(); //View output /**/ { string s; for ( integer i = 0 ; i < 13 ; i++) {s+= “-” ;} print (s);}
/**/ ~ list; // Clean list, now empty list2.RemoveLast(); // Eliminate list2.PrintHash(); // View output /**/ { string s; for ( integer i = 0 ; i < 13 ; i++) {s+= "-" ;} print (s);}
/**/ A* o=List2[ 0 ]; //Direct access print (list2.Hash(o)); //2097152 //Same... //Using o without checking is risky, but if you are sure print (List2.Hash( 0 )); //2097152 //...Object print (list2.TryGet(o, Chapter 666 )); // false, don't use o //Safe access /**
  ...when destroyed, the list will remove dynamic object o1 from memory.
  /**/ } /**************************************************************************
Output:
/**
  0:2097152(A*)
  1:3145728(A*)
  2:3145728(A*)
  -------------
  0:2097152(A*)
  1:3145728(A*)
  -------------
  0:2097152(A*)
  -------------
  2097152
  2097152
  Fake/**/



Attachment download

📎 objectlist.mq5 (3.56 KB)

📎 objectlist.mqh (6.64 KB)

Source: MQL5 #29765

Verification code Refresh