Visual C++ and Hashmap

This is my first entry on "Programming Tips" which I think there will be more on this, cause I think I more expert on this than anything else in computer science.
 
Anyway, today I tired to use some of MFC classes to build some Hashtable & List & Pair just equal to the C#. I has lots of problem which MFX so I tried to use the STD counterparts. The most problemy thing about Hashmap (std::hash_map) is that you cannot have a hash_map<CString> I mean having a Hashmap/ hashtable which key is CString, so this is how I wrote it (It is not all by me!):
 
    //—————————————————————————
    template <class KEY, class ARG_KEY = KEY, class TRAITS = std::less<KEY> >
    class HashCompare
      : public stdext::hash_compare<KEY, TRAITS>
    {
    public:
      using stdext::hash_compare<KEY, TRAITS>::operator();
      size_t operator()(const KEY& Key) const
      {
        return static_cast<size_t>(HashKey<ARG_KEY>(Key));
      }
    };
    //—————————————————————————
    template <class KEY, class VALUE, class HashCompareARG_KEY = KEY>
    class HashMap
      : public stdext::hash_map<KEY, VALUE, HashCompare<KEY, HashCompareARG_KEY> >
    {
    public:
      HashMap() : hash_map() { }
      virtual bool Add(KEY key, VALUE value)
      {
        std::pair<iterator, bool> pr;
        pr = insert(value_type(key, value));
        return pr.second;
      }
       // Be aware of that you have to delete the replaced value by yourself
      virtual bool Replace(KEY key, VALUE newValue)
      {
        iterator iter = find(key);
        if (iter != end()) // key found
        {
          iter->second = newValue;
          return true;
        }
        else
          return false;
      }
      virtual value_type *Find(KEY key)
      {
        iterator iter = find(key);
        if (iter != end()) // key found
          return &(*iter);
        else
          return NULL;
      }
    };
    //—————————————————————————
    template <class VALUE>
    class StringHashMap
      : public HashMap<CString, VALUE, LPCTSTR>
    {
    public:
      StringHashMap() : HashMap() { }
      virtual value_type *FindCaseInsensitive(CString key)
      {
        iterator iter = begin();
        while (iter != end())
        {
          if (!iter->first.CompareNoCase(key))
            return &(*iter);
          iter++;
        }
        return NULL;
      }
    };
    //—————————————————————————
    typedef StringHashMap<CString> StringStringHashMap;
    //—————————————————————————
After that I create the my own list which is something betwean std:list and CList:
 
    //—————————————————————————
    template<class _Ty, class FindKey = _Ty, class _Ax = std::allocator<_Ty>>
    class List
      : public std::list<_Ty, _Ax>
    {
    public:
      List() : list() { }
      virtual _Ty *Find(FindKey findKey)
      {
        for (iterator iter = begin(); iter != end(); iter++)
          if ((*iter) == findKey)
            return &(*iter);
        return NULL;
      }
      virtual _Ty *operator[](const unsigned int& index)
      {
        if (index < size())
        {
          int cnt = 0;
          for (iterator iter = begin(); iter != end(); iter++, cnt++)
            if (cnt == index)
              return &(*iter);
        }
        return NULL;
      }
      virtual iterator Add(const _Ty &element)
      {
        push_back(element);
        return –end();
      }
      virtual iterator Add(const List<_Ty, FindKey, _Ax> &list)
      {
        insert(end(), list.begin(), list.end());
        return –end();
      }
      virtual bool Remove(FindKey findKey, bool removeAllInstances = false)
      {
        bool retVal = false;
        iterator iterEnd = end();
        for (iterator iter = begin(); iter != iterEnd; iter++)
          if ((*iter) == findKey)
          {
            erase(iter);
            retVal = true;
            if (!removeAllInstances)
              break;
          }
        return retVal;
      }
    };
    //—————————————————————————
    template<class _Ty, class FindKey = _Ty, class _Ax = std::allocator<_Ty>>
    class SortedList
      : public List<_Ty, FindKey, _Ax>
    {
    public:
      iterator Add(const _Ty &element) override
      {
        iterator iterEnd = end();
        for (iterator iter = begin(); iter != iterEnd; iter++)
          if ((*iter) < element)
            return insert(iter, element);
        return List::Add(element);
      }
    };
    //—————————————————————————
    class StringList
      : public List<CString>
    {
    public:
      StringList() : List() { }
      virtual CString *FindCaseInsensitive(CString findKey)
      {
        iterator iterEnd = end();
        for (iterator iter = begin(); iter != iterEnd; iter++)
          if ((*iter).CompareNoCase(findKey))
            return &(*iter);
        return NULL;
      }
    };
    //—————————————————————————
    class SortedStringList
      : public SortedList<CString>
    {
    public:
      SortedStringList() : SortedList() { }
      virtual CString *FindCaseInsensitive(CString findKey)
      {
        iterator iterEnd = end();
        for (iterator iter = begin(); iter != iterEnd; iter++)
          if ((*iter).CompareNoCase(findKey))
            return &(*iter);
        return NULL;
      }
    };
    //—————————————————————————
 
and then Pair:
 
    //—————————————————————————
    template<class Type1, class Type2>
    class Pair
      : public std::pair<Type1, Type2>
    {
    public:
     Pair() : pair() { }
      Pair(const Type1& _Val1, const Type2& _Val2) : pair(_Val1, _Val2) { }
      virtual bool operator==(const Type1 &other) const
      {
        return (first == other);
      }
      virtual bool operator < (const Type1& other) const
      {
        return (first < other);
      }
    };
    //—————————————————————————
    class StringPair
      : public Pair<CString, CString>
    {
    public:
      StringPair() : Pair() { }
      StringPair(CString first, CString second) : Pair(first, second) { }
      virtual int CompareNoCase(CString psz)
      {
        return first.CompareNoCase(psz);
      }
    };
    //—————————————————————————
and the Pair list:
 
    //—————————————————————————
    class StringPairList
      : public List<StringPair, CString>
    {
    public:
      StringPairList() : List() { }
      virtual StringPair *FindCaseInsensitive(CString findKey)
      {
        iterator iterEnd = end();
        for (iterator iter = begin(); iter != iterEnd; iter++)
          if ((*iter).CompareNoCase(findKey))
            return &(*iter);
        return NULL;
      }
    };
    //—————————————————————————
 
 
with some more attention you’ll find out how to make a struct in the list to be sorted on one key (That’s way I use the findkey).
 
And the last but not the least my best String (which is 1500% faster than CString):
 
    //—————————————————————————
    class String
//      : public std::basic_string<wchar_t>
      : public std::basic_string<char>
    {
    protected:
      enum { _MAX_CHARS = 256 };
      value_type buffer[_MAX_CHARS + 1];
    public:
      String() : basic_string() { }
     
      String(const String& arg) : basic_string(arg) { }
      String(const value_type arg) : basic_string() { (*this) = arg;  }
      String(const value_type* arg) : basic_string(arg) { }
/*     String& operator=(const String& arg)     { assign(arg.c_str()); return (*this); }
      String& operator=(const value_type pArg) { assign(pArg); return (*this); }
      String& operator=(const value_type* pArg) { assign(pArg); return (*this); }*/
      //—————————————————————————
      virtual bool operator==(const String &other)     { return (this->compare(other) == 0); }
      virtual bool operator==(const value_type *other) { return (this->compare(other) == 0); }
      virtual bool operator> (const String &other)     { return (this->compare(other) >  0); }
      virtual bool operator> (const value_type *other) { return (this->compare(other) >  0); }
      virtual bool operator>=(const String &other)     { return (this->compare(other) >= 0); }
      virtual bool operator>=(const value_type *other) { return (this->compare(other) >= 0); }
      virtual bool operator< (const String &other)     { return (this->compare(other) <  0); }
      virtual bool operator< (const value_type *other) { return (this->compare(other) <  0); }
      virtual bool operator<=(const String &other)     { return (this->compare(other) <= 0); }
      virtual bool operator<=(const value_type *other) { return (this->compare(other) <= 0); }
      virtual operator const value_type *()            { return c_str(); }
      virtual String &operator+=(const String &other)     { append(other); return (*this); }
      virtual String &operator+=(const value_type other) { append(1, other); return (*this); }
      virtual String &operator+=(const value_type *other) { append(other); return (*this); }
      virtual String &operator+=(const int &other)        { AppendFormat("%d", other); return (*this); }
      //—————————————————————————
      virtual void ToUpper()                        { transform(begin(), end(), begin(), toupper); }
     virtual void ToLower()                        { transform(begin(), end(), begin(), tolower); }
      virtual bool IsEmpty() { return (this->compare(_T("")) == 0); }
      virtual void Format(const value_type *szFormat, …)
     {
      va_list argList;
      va_start(argList, szFormat); // Initialize variable arguments.
//        int ret = _vsnwprintf_s(buffer, _MAX_CHARS, _MAX_CHARS, szFormat, argList);
      int ret = _vsnprintf_s(buffer, _MAX_CHARS, _MAX_CHARS, szFormat, argList);
        if (ret > 0)
        assign(buffer, ret);
      va_end(argList); // Reset variable arguments.
     }
      //—————————————————————————
      virtual void AppendFormat(const value_type* szFormat, …)
     {
      va_list argList;
      va_start(argList, szFormat); // Initialize variable arguments.
//      int ret = _vsnwprintf_s(buffer, _MAX_CHARS, _MAX_CHARS, szFormat, argList);
      int ret = _vsnprintf_s(buffer, _MAX_CHARS, _MAX_CHARS, szFormat, argList);
        if (ret > 0)
          append(buffer, ret);
        va_end(argList); // Reset variable arguments.
     }
      //—————————————————————————
    };
    //—————————————————————————
    inline String operator+(const String& s1, const String& s2)
    {
      String retVal(s1);
      retVal += s2;
      return retVal;
    }
    inline String operator+(const String& s1, const String::value_type s2)
    {
      String retVal(s1);
      retVal += s2;
      return retVal;
    }
    inline String operator+(const String& s1, const String::value_type *s2)
    {
      String retVal(s1);
      retVal += s2;
      return retVal;
    }
    inline String operator+(const String::value_type s1, const String& s2)
    {
      String retVal(s1);
      retVal += s2;
      return retVal;
    }
    inline String operator+(const String::value_type *s1, const String& s2)
    {
      String retVal(s1);
      retVal += s2;
      return retVal;
    }
    //—————————————————————————
 
Hope these are will help,
just leave a message if you need help on those,
 
Sadjad Bahmanpour

Leave a Reply