Вы можете использовать std :: find_if.
bool not_0(char c)
{
return c != 0;
}
char *next = std::find_if(ptr + 100, ptr + 200, not_0);
if (next == ptr + 200)
// all 0's
Вы также можете использовать связыватели для удаления функции free (хотя я думаю, что связующие трудно читать):
char *next = std::find_if(ptr + 100, ptr + 200,
std::bind2nd(std::not_equal_to<char>(), 0));
Черт, я просто замечаю просьбу не делать этот байт за байтом. find_if все равно будет делать побайтово, хотя он и скрыт. Вы должны будете сделать это 1 на 1, хотя использование более крупного типа поможет. Вот мой окончательный вариант.
template <class T>
bool all_0(const char *begin, const char *end, ssize_t cutoff = 10)
{
if (end - begin < cutoff)
{
const char *next = std::find_if(begin, end,
std::bind2nd(std::not_equal_to<char>(), 0));
return (next == end);
}
else
{
while ((begin < end) && ((reinterpret_cast<uintptr_t>(begin) % sizeof(T)) != 0))
{
if (*begin != '\0')
return false;
++begin;
}
while ((end > begin) && ((reinterpret_cast<uintptr_t>(end) % sizeof(T)) != 0))
{
--end;
if (*end != '\0')
return false;
}
const T *nbegin = reinterpret_cast<const T *>(begin);
const T *nend = reinterpret_cast<const T *>(end);
const T *next = std::find_if(nbegin, nend,
std::bind2nd(std::not_equal_to<T>(), 0));
return (next == nend);
}
}
Сначала он проверяет, достаточно ли длинны данные, чтобы оправдать более сложный алгоритм. Я не уверен на 100%, что это необходимо, но вы можете настроить необходимый минимум.
Предполагая, что данные достаточно длинные, они сначала выравнивают начальный и конечный указатели, чтобы соответствовать выравниванию типа, используемого для сравнения. Затем он использует новый тип для проверки объема данных.
Я бы порекомендовал использовать:
all_0<int>(); // 32 bit platforms
all_0<long>(); // 64 bit LP64 platforms (most (all?) Unix platforms)
all_0<long long>() // 64 bit LLP64 platforms (Windows)