#include <algorithm>
#include <cctype>
#include <cassert>
#include <set>
#include <string>
struct icase_less {
bool operator()(const std::string& x, const std::string& y) const {
// для однобайтных кодировок без учёта диграфов типа эсцета - сойдёт
return std::lexicographical_compare(
std::begin(x), std::end(x),
std::begin(y), std::end(y),
[](char a, char b)->bool { return std::toupper(a) < std::toupper(b); } );
}
};
template<class LESS>
struct dependent_equal {
LESS less;
template<class X, class Y>
bool operator()(X&& x, Y&& y) const {
return !less(std::forward<X>(x), std::forward<Y>(y))
&& !less(std::forward<Y>(y), std::forward<X>(x));
}
};
int main() {
using icase_multiset = std::multiset<std::string, icase_less>;
icase_multiset xx = { "alfa", "beta", "Beta", "BETA", "gamma" };
icase_multiset yy = { "alfa", "Beta", "BETA", "BeTa", "gamma" };
// <--------------------> класс эквивалентности "beta"
using icase_equal = dependent_equal<icase_less>;
// выполняем попарное сравнение
assert( std::equal(std::begin(xx), std::end(xx),
std::begin(yy), std::end(yy),
icase_equal()));
// попарное сравнение без "без учёта регистра" не прокатит
assert(!std::equal(std::begin(xx), std::end(xx),
std::begin(yy), std::end(yy)));
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGNjdHlwZT4KI2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxzZXQ+CiNpbmNsdWRlIDxzdHJpbmc+CgpzdHJ1Y3QgaWNhc2VfbGVzcyB7CiAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IHN0ZDo6c3RyaW5nJiB4LCBjb25zdCBzdGQ6OnN0cmluZyYgeSkgY29uc3QgewogICAgLy8g0LTQu9GPINC+0LTQvdC+0LHQsNC50YLQvdGL0YUg0LrQvtC00LjRgNC+0LLQvtC6INCx0LXQtyDRg9GH0ZHRgtCwINC00LjQs9GA0LDRhNC+0LIg0YLQuNC/0LAg0Y3RgdGG0LXRgtCwIC0g0YHQvtC50LTRkdGCCiAgICByZXR1cm4gc3RkOjpsZXhpY29ncmFwaGljYWxfY29tcGFyZSgKICAgICAgc3RkOjpiZWdpbih4KSwgc3RkOjplbmQoeCksCiAgICAgIHN0ZDo6YmVnaW4oeSksIHN0ZDo6ZW5kKHkpLAogICAgICBbXShjaGFyIGEsIGNoYXIgYiktPmJvb2wgeyByZXR1cm4gc3RkOjp0b3VwcGVyKGEpIDwgc3RkOjp0b3VwcGVyKGIpOyB9ICk7CiAgfQp9OwoKdGVtcGxhdGU8Y2xhc3MgTEVTUz4Kc3RydWN0IGRlcGVuZGVudF9lcXVhbCB7CiBMRVNTIGxlc3M7CiB0ZW1wbGF0ZTxjbGFzcyBYLCBjbGFzcyBZPgogYm9vbCBvcGVyYXRvcigpKFgmJiB4LCBZJiYgeSkgY29uc3QgewogICByZXR1cm4gIWxlc3Moc3RkOjpmb3J3YXJkPFg+KHgpLCBzdGQ6OmZvcndhcmQ8WT4oeSkpCiAgICAgICAmJiAhbGVzcyhzdGQ6OmZvcndhcmQ8WT4oeSksIHN0ZDo6Zm9yd2FyZDxYPih4KSk7CiB9Cn07CgppbnQgbWFpbigpIHsKICB1c2luZyBpY2FzZV9tdWx0aXNldCA9IHN0ZDo6bXVsdGlzZXQ8c3RkOjpzdHJpbmcsIGljYXNlX2xlc3M+OwogIGljYXNlX211bHRpc2V0IHh4ID0geyAiYWxmYSIsICJiZXRhIiwgIkJldGEiLCAiQkVUQSIsICJnYW1tYSIgfTsKICBpY2FzZV9tdWx0aXNldCB5eSA9IHsgImFsZmEiLCAiQmV0YSIsICJCRVRBIiwgIkJlVGEiLCAiZ2FtbWEiIH07CiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC0tLS0tLS0tLS0tLS0tLS0tLS0tPiDQutC70LDRgdGBINGN0LrQstC40LLQsNC70LXQvdGC0L3QvtGB0YLQuCAiYmV0YSIKCiAgdXNpbmcgaWNhc2VfZXF1YWwgPSBkZXBlbmRlbnRfZXF1YWw8aWNhc2VfbGVzcz47CiAgLy8g0LLRi9C/0L7Qu9C90Y/QtdC8INC/0L7Qv9Cw0YDQvdC+0LUg0YHRgNCw0LLQvdC10L3QuNC1CiAgYXNzZXJ0KCBzdGQ6OmVxdWFsKHN0ZDo6YmVnaW4oeHgpLCBzdGQ6OmVuZCh4eCksCiAgICAgICAgICAgICAgICAgICAgIHN0ZDo6YmVnaW4oeXkpLCBzdGQ6OmVuZCh5eSksCiAgICAgICAgICAgICAgICAgICAgIGljYXNlX2VxdWFsKCkpKTsKICAvLyDQv9C+0L/QsNGA0L3QvtC1INGB0YDQsNCy0L3QtdC90LjQtSDQsdC10LcgItCx0LXQtyDRg9GH0ZHRgtCwINGA0LXQs9C40YHRgtGA0LAiINC90LUg0L/RgNC+0LrQsNGC0LjRggogIGFzc2VydCghc3RkOjplcXVhbChzdGQ6OmJlZ2luKHh4KSwgc3RkOjplbmQoeHgpLAogICAgICAgICAgICAgICAgICAgICBzdGQ6OmJlZ2luKHl5KSwgc3RkOjplbmQoeXkpKSk7Cn0K