HiveBrain v1.2.0
Get Started
← Back to all entries
principlecppMinor

CRC function duplication – differ only in pointer vs iterator signature

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
iteratorcrcduplicationsignaturefunctionpointerdifferonly

Problem

This is a CRC function generated by pyCRC and changed by me:

static inline crc_t crc_update(crc_t          crc, 
                               char const *   data, 
                               long long      data_len)
{
    while (data_len--) 
    {
        crc = (crc_table[(crc ^ *data) & 0xff] ^ (crc >> 8));
        ++data;
    }
    return crc;
}


I made an iterator version of it:

static inline crc_t crc_update(crc_t                          crc, 
                               std::istreambuf_iterator data, 
                               long long                      data_len)
{
   /* body identical to the above */
}


Is there a way I can avoid duplication? (The main purpose of the code is to be fast.)

Solution

The obvious way is to replace the type that changes with a templated type, like this:

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


Or in words: put template 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.

Code Snippets

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

Context

StackExchange Code Review Q#6525, answer score: 5

Revisions (0)

No revisions yet.