-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
В C++23 в std::string добавили очень удобный метод resize_and_overwrite.
Однако не всегда при его вызове нам известен нужный размер, и узнать мы его сможем только уже внутри функтора.
Например, так работают многие функции WinAPI - если им передать недостаточный буфер, они вернут нужный размер.
Предлагаю в методе resize_and_overwrite, если функтор вернул размер больше, чем текущая ёмкость строки, резервировать нужный размер и вызывать функтор повторно.
Пример, в Windows:
std::wstring p;
p.resize_and_overwrite(MAX_PATH, [](wchar_t* ptr, size_t capacity) -> size_t {
DWORD len = GetCurrentDirectoryW(capacity + 1, ptr);
if (len <= capacity) {
return len;
}
return len - 1;
});Обычно длина пути в Windows не превышает MAX_PATH, и такого буфера достаточно. Но бывают возможны и более длинные пути.
Пример в Linux
std::string p;
p.resize_and_overwrite(DEFAULT_PATH_LEN, [](char* p, size_t s) {
const char* res = getcwd(p, s + 1);
if (res) {
return strlen(res); // Возвращаем длину строки
}
if (errno == ERANGE) // Не влезло в буфер, попробуем в два раза больше
return s * 2;
return 0ul;
});
И вообще, такую бы штуку хорошо было добавить в конструктор.
Реализация подобного есть в simstr.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels