![](/style/images/good.png)
![](/style/images/bad.png)
Case insensitive string, etc
source link: https://vorbrodt.blog/2021/04/10/case-insensitive-string-etc/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Case insensitive string, etc
The question of case insensitive strings has been, and continues to be asked a lot, and equally many answers can be found all over the internet. The go-to solution is to create a char_traits policy class with eq, lt, and compare methods implemented using std::toupper before comparing characters, then instantiate std::basic_string with it using istring = std::basic_string<char,char_itraits<char>> This works well until you try to use your new type anywhere near code designed with std::string in mind. Then what?
I guess what I am trying to say is that I never found a complete solution to this, so I decided to create one myself. I wanted the case insensitive string to play nicely and seamlessly with its standard counterpart. I wanted the ability to pass it as a parameter anywhere
std::string is accepted; to convert between
istring and
std::string in both directions; push it to output stream; read it from input stream; compare it using all six operators,
==,
!=,
<,
<=,
>,
>=, with
std::string whether it appeared on the left or right side of the operation; and to declare literals of its type:
"std::string literal"s.
In other words have it be indistinguishable from
std::string except when comparisons are needed, like this:
The starting point was the character traits policy class mentioned earlier, but instead of using it with std::basic_string I inherited publicly from std::basic_string template configured with case insensitive traits policy; this pulled all its methods into the derived class scope, I only had to pull base class constructors:
All this derived class needed now was a constructor which would allow it to be created from any other type of std::basic_string as long as the character type was the same; implicit type cast operator to seamlessly convert it to std::string, and 4 comparison operators: == and <=> declared twice with istring as the first or second parameter. The constructor and comparison operators needed to be selectively enabled only for strings with different character traits policy, otherwise they would cause ambiguity and compilation errors. Final step was declaring operator >>, operator <<, and operator""_is.
P.S. Everything I just described also applies to wchar_t aka std::wstring.
The implementation on my GitHub page: istring.hpp, example program: istring.cpp.
Like this:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK