Generic Class Library - bugs, description, questions, usage and suggestions - page 24

 
fxsaber:

Question about getting a value from a key. In the library code, this method looks like this

//+------------------------------------------------------------------+
//| Find index of entry with specified key.                          |
//+------------------------------------------------------------------+
template<typename TKey,typename TValue>
int CHashMap::FindEntry(TKey key)
  {
   if(m_capacity!=NULL)
     {
      //--- get hash code from key
      int hash_code=m_comparer.HashCode(key)&0x7FFFFFFF;
      //--- search pair with specified key
      for(int i=m_buckets[hash_code%m_capacity]; i>=0; i=m_entries[i].next)
         if(m_entries[i].hash_code==hash_code && m_comparer.Equals(m_entries[i].key,key))
            return(i);
     }
   return(-1);
  }

Yes, this code can be misleading because of the non-standard reassignment of i in for.

First we access the sub-array by its index, which may contain our value:i=m_buckets[hash_code%m_capacity];(i.e. i index of the sub-array or value bin).

Then, in the same for, the bin index is turned into the bin item index:i=m_entries[i].next

In fact, the code is written correctly, because in a typical case each sub-array will have on average one item and the loop will again on average be executed only once.

 
Vasiliy Sokolov:

Yes, this code can be misleading because of the non-standard reassignment of i in for.

First, we access a sub-array by its index, which may contain our value:i=m_buckets[hash_code%m_capacity];(i.e. i index of the sub-array or basket of values).

Then, in the same for, the bin index is turned into the bin item index:i=m_entries[i].next

In fact, the code is written correctly because in a typical case each sub-array will contain on average one item and the loop will on average execute only once.

I understand that the loop is made for collisions: to go through the mini-list.

 
fxsaber:

I take it that the loop is made for collisions: to go through a mini-list.

Yes, absolutely right.

 

Used the template library(CArrayList) to store custom types. The impression is not great. For some convenience I've written macros

#define  CLEANUP   do {                                      \
   for(int i_cln = 0;  i_cln < segs.Count();  ++ i_cln) {   \
      Wave_end *cln_el;                                     \
      if(  segs.TryGetValue(i_cln, cln_el) )                \
         delete cln_el;                                     \
   }}while(false)
#define  SSEG(IND)  do {                \
if( ! segs.TryGetValue(IND, we) ) {    \
   CLEANUP;                            \
   continue;                           \
}}while(false)

Excessive foolproofing in TryGetValue + impossibility to pass classes by value makes use painful.

 
Comments not related to this topic have been moved to "Questions from MQL5 MT5 MetaTrader 5 beginners".
 

Tell me, maybe I don't understand something, but if I try to use a construction of this type:

#include <Generic\\ArrayList.mqh>

struct Option {
   string name;
   color  clr;
};

...

CArrayList<Option> _options;

I get an error:

'Option' - objects are passed by reference only ICollection.mqh 14 18

And then there's a whole stack of errors...
 
Andrey Pogoreltsev:

Tell me, maybe I don't understand something, but if I try to use a construction of this type:

I get an error:

'Option' - objects are passed by reference only ICollection.mqh 14 18

and there's a full stack of errors next...

Try it like this:

#include <Generic\\ArrayList.mqh>

class Option {
   string name;
   color  clr;
};

...

CArrayList<Option*> _options;
 
Sergey Eremin:

Try it this way:

Passing/storing pointers to a collection is wrong conceptually.

 
Andrey Pogoreltsev:

Passing/storing pointers to a collection is wrong conceptually.

there is no generic for MQL that is even marginally suitable. all of them have serious bugs. use a built-in array, it will give you less headaches.

 
TheXpert:

there is no generic for MQL that is even slightly suitable. all of them have serious bugs. use an embedded array, it will give you less headache.

Well, yes, I've used an array. Why create collections and put them into kodobase if they are only suitable for built-in types?)