Re: CMAP under vs2005+
And the attachment is a compilable example.
Giovanni
"Giovanni Dicanio" <giovanniDOTdicanio@REMOVEMEgmail.com> ha scritto nel
messaggio news:eim9xfONJHA.5692@TK2MSFTNGP02.phx.gbl...
"Tommy" <tommy767@gmail.com> ha scritto nel messaggio
news:%23XGVnJLNJHA.5060@TK2MSFTNGP02.phx.gbl...
Under VC6, I had a wrapper CMAP template, which I called CMapEx which
I used for many years as a way to map case insensitive key strings to
objects.
[...]
If is possible to use CMap with an unique HashKey function unique to
CMapEx wrapper for CMAP so I can make the hash case insensitive?
Hi,
I learned that MFC CMap class is not very good, I would suggest you to use
std::map.
Note that you can mix std::map with CString class (from MFC/ATL).
So, if you want a case insensitive map from string to string, using
CString
class for strings, and std::map for mapping, you may consider providing a
custom key comparer for std::map.
The custom key comparer is responsible to do the case *in*sensitive
comparison. For that purpose, CString offers a CompareNoCase() method,
that
you can use.
CString::CompareNoCase()
http://msdn.microsoft.com/en-us/library/aa314315.aspx
The custom comparer is a class with a public method overloading
operator(),
in this form:
bool operator()( const CString & left, const CString & right ) const;
It is a predicate, that returns true if 'left < right'; of course, inside
the implementation of this operator(), you can define your own custom
comparison relation, in this case using CString::CompareNoCase():
<code>
struct CaseInsensitiveStringComparer
{
// functor for operator <
bool operator()(const CString & left, const CString & right) const
{
// Case insensitive comparison
return ( left.CompareNoCase( right ) < 0 );
}
};
</code>
You can pass this custom comparer as third template parameter of std::map
(the first template parameter is the key type, the second template
parameter
is the "destination" value type):
<code>
//
// Map string --> string, using case insensitive comparison of string keys
//
typedef std::map< CString, CString, CaseInsensitiveStringComparer >
StringDictionaryCaseInsensitive;
</code>
You can test like this (#include <map> for std::map class)
<code>
StringDictionaryCaseInsensitive test;
test[ _T("Bob") ] = _T("123");
test[ _T("Jeff") ] = _T("456");
test[ _T("BOB") ] = _T("000"); // override first Bob
ASSERT( test[ _T("Bob") ] == _T("000") );
</code>
HTH,
Giovanni
begin 666 TestCaseInsensitiveMap.cpp
M+R\@5&5S=$-A<V5);G-E;G-I=&EV94UA<"YC<' -"@T*#0HC:6YC;'5D92 \
M871L8F%S92YH/B @(" @(" @+R\@051,05-315)4#0HC:6YC;'5D92 \871L
M<W1R+F@^(" @(" @(" @+R\@0U-T<FEN9PT*(VEN8VQU9&4@/&UA<#X@(" @
M(" @(" @(" @("\O(%-43"!M87 -"@T*#0HO+R!#;VUP87)E('-T<FEN9W,@
M:6X@82!C87-E(&EN<V5N<VET:79E('=A>0T*<W1R=6-T($-A<V5);G-E;G-I
M=&EV95-T<FEN9T-O;7!A<F5R#0I["0T*(" @("\O(&9U;F-T;W(@9F]R(&]P
M97)A=&]R(#P-"B @("!B;V]L(&]P97)A=&]R*"DH8V]N<W0@0U-T<FEN9R F
M(&QE9G0L(&-O;G-T($-3=')I;F<@)B!R:6=H="D@8V]N<W0-"B @("!["0T*
M(" @(" @(" O+R!#87-E(&EN<V5N<VET:79E(&-O;7!A<FES;VX-"B @(" @
M(" @<F5T=7)N("@@;&5F="Y#;VUP87)E3F]#87-E*"!R:6=H=" I(#P@," I
M.PT*(" @('T-"GT[#0H-"@T*:6YT(&UA:6XH*0T*>PT*(" @('1Y<&5D968@
M<W1D.CIM87 \($-3=')I;F<L($-3=')I;F<L($-A<V5);G-E;G-I=&EV95-T
M<FEN9T-O;7!A<F5R(#X@4W1R:6YG1&EC=&EO;F%R>4-A<V5);G-E;G-I=&EV
M93L-"@T*(" @(%-T<FEN9T1I8W1I;VYA<GE#87-E26YS96YS:71I=F4@=&5S
M=#L-"B @("!T97-T6R!?5"@B0F]B(BD@72 ](%]4*"(Q,C,B*3L-"B @("!T
M97-T6R!?5"@B2F5F9B(I(%T@/2!?5"@B-#4V(BD[#0H@(" @=&5S=%L@7U0H
M(D)/0B(I(%T@/2!?5"@B,# P(BD[("\O(&]V97)R:61E(&9I<G-T($)O8@T*
M#0H@(" @051,05-315)4*"!T97-T6R!?5"@B0F]B(BD@72 ]/2!?5"@B,# P
M(BD@*3L-"B @("!!5$Q!4U-%4E0H('1E<W1;(%]4*")*969F(B I(%T@/3T@
B7U0H(C0U-B(I("D[#0H-"B @("!R971U<FX@,#L-"GT-"@``
`
end