CRC function duplication – differ only in pointer vs iterator signature
The obvious way is to replace the type that changes with a templated type, like this:

template&lt;typename T&gt;
static inline crc_t crc_update(crc_t          crc, 
                               T              data, 
                               long long      data_len)
{
    while (data_len--) 
    {
        crc = (crc_table[(crc ^ *data) &amp; 0xff] ^ (crc &gt;&gt; 8));
        ++data;
    }
    return crc;
}


Or in words: put template&lt;typename T&gt; in front of the function, and replace all char const * with T.

There are some details about inserting typename in some cases to help the compiler, but those do not apply in this case.

To prevent incorrect usage, one might add some checks to ensure that only 8 bit types can be used. However, that is advanced stuff and not required to answer your question.