Matt Austern wrote a paper on "How to do case-insensitive string comparison" that handles locales properly. It may contain the information on locales and facets that you're looking for.
Otherwise, if you're just looking to reverse the usual comparison order of a couple of characters, shouldn't using std::lexicographical_compare
with your own comparison function object do the job?
bool mycomp( char c1, char c2 )
{
// Return 0x5F < 0x30
if ( ( c1 == '_' ) && ( c2 == '0' ) )
return true;
if ( ( c1 == '0' ) && ( c2 == '_' ) )
return false;
return ( c1 < c2 );
}
std::string w1 = "word0";
std::string w2 = "word_";
bool t1 = std::lexicographical_compare( w1.begin(), w1.end(), w2.begin(), w2.end() );
bool t2 = std::lexicographical_compare( w1.begin(), w1.end(), w2.begin(), w2.end(), mycomp );
"word0"
evaluates less than "word_"
in the first case, and greater in the second, which is what you're after.
If you're already doing something similar, that's the easiest way to go.
Edit: On the subject of using char_traits
to accomplish this, Austern's article notes:
The Standard Library type std::string
uses the traits parameter for
all comparisons, so, by providing a traits parameter with equality and
less than redefined appropriately, you can instantiate basic_string in
such a way so that the <
and ==
operators do what you need. You
can do it, but it isn't worth the trouble.
You won't be able to do I/O, at least not without a lot of pain. You
won't be able use ordinary stream objects like cin
and cout
.
He goes on to list several other good reasons why modifying char_traits
to perform this comparison isn't a good idea.
I highly recommend that you read Austern's paper.