может ли кто-нибудь просветить меня относительно того, как я могу сделать boost :: filesystem :: path нечувствительным к регистру? Обычно чувствительность к регистру - это собственное решение платформы, однако это не так просто для моего приложения, поскольку подробные сведения о пути извлекаются из двоичного файла, а требование приложения состоит в том, что независимо от того, на какой платформе я работаю. работает, я должен обрабатывать все пути нечувствительно к регистру.
До сих пор я делал это с помощью метода boost :: filesystem :: path :: generic_string () для помещения путей, которые я сравниваю, в общий строковый формат для лексикографического сравнения. Затем я преобразовываю строки в нижний регистр и использую функции std :: string для выполнения сравнений и других методов оператора. Очевидно, это неоптимально, поскольку я хотел бы иметь возможность выполнять лексикографические сравнения на путях, а не на строках. Внутренне реализация оператора ‹() пути boost использует умное лексикографическое сравнение путей с использованием итераторов пути - это отличается от строковых лексикографических сравнений.
Я думал, что есть способ предоставить специальный строковый тип, определяемый пользователем, в качестве внутреннего представления для увеличения пути в конструкторе, но я не уверен, как это сделать. Обычно нечувствительность к регистру такого рода будет выполняться через связанные классы признаков - как вы можете видеть ниже в классе символов нечувствительных к регистру строковых признаков, используемом для UtlCIString (служебная нечувствительная к регистру строка). Если бы можно было связать другой строковый тип как внутренний строковый класс, я бы использовал следующее, но я не уверен, как это сделать:
// case insensitive character traits
// inherited copy (preserves case),
// case insensitive comparison, search
struct traits_nocase : std::char_traits<char>
{
static bool eq(const char& c1, const char& c2) {
return toupper(c1) == toupper(c2);
}
static bool lt(const char& c1, const char& c2) {
return toupper(c1) < toupper(c2);
}
static int compare(const char* s1, const char* s2, size_t N) {
#if defined (_WIN32)
return _strnicmp(s1, s2, N);
#else // POSIX
return strncasecmp( s1, s2, N );
#endif
}
static const char* find(const char* s, size_t N, const char& a) {
for (size_t i = 0; i < N; ++i) {
if (toupper(s[i]) == toupper(a)) {
return s + i;
}
}
return 0;
}
static bool eq_int_type(const int_type& c1, const int_type& c2) {
return toupper(c1) == toupper(c2);
}
};
// string preserves case; comparisons are case insensitive
typedef std::basic_string<char, traits_nocase> UtlCIString;