Use CString with CAtlMap and perform case insensitive lookup

While it is convenient to use CString as key element with CAtlMap, by default it will perform case-sensitive lookup which is not desired under certain conditions, e.g. use CAtlMap<CString> to hold query result from database, where we are hoping to perform case-insensitive lookup because column names are case-insensitive to most SQL languages.

To workaround the problem, the easiest way (I can find) is to use a modified string element trait like this:


#pragma once

#include <atlstr.h>

#pragma warning(push)
#pragma warning(disable:4996)

/// Modified string element trait which does case insensitive comparison
class CStringElementTraitsX : public CStringElementTraits< CString >
    static ULONG __cdecl Hash( _In_ INARGTYPE str )
        ATLENSURE( str != NULL );
        ULONG nHash = 0;
        const CString::XCHAR* pch = str;
        while( *pch != 0 )
            CString::XCHAR ch = *pch++;
            if (_T(‘A’) <= ch && ch <= _T(‘Z’))
                ch += (TCHAR)_T(‘a’) – (TCHAR)_T(‘A’);
            nHash = (nHash<<5)+nHash+ch;

        return( nHash );

    static bool __cdecl CompareElements( _In_ INARGTYPE str1, _In_ INARGTYPE str2 )
        return( _tcsicoll( str1, str2 ) == 0 );

#pragma warning(pop)

The code is simple and straightforward. To use it with CAtlMap (assuming use _variant_t as value):

  typedef CAtlMap<CString, _variant_t, CStringElementTraitsX> CAltMapX;

Posted on February 9, 2010, in Uncategorized. Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: