dimanche 24 janvier 2021

C++ idiom for loop edges

Problem 1: suppose you have an array of n floats and you want to calculate an array of n running averages over three elements. The middle part would be straightforward:

for (int i=0; i<n; i++)
    b[i] = (a[i-1] + a[i] + a[i+1])/3.

But you need to have separate code to handle the cases i==0 and i==(n-1). This is often done with extra code before the loop, extra code after the loop, and adjusting the loop range, e.g.

b[0] = (a[0] + a[1])/2.
for (int i=1; i<n-1; i++)
    b[i] = (a[i-1] + a[i] + a[i+1])/3.;
b[n-1] = (a[n-1] + a[n-2])/2.

Even that is not enough, because the cases of n<3 need to be handled separately.

Problem 2. You are reading a variable-length code from an array (say implementing a UTF-8 to UTF-32 converter). The code reads a byte, and accordingly may read one or more bytes to determine the output. However, before each such step, it also needs to check if the end of the input array has been reached, and if so, perhaps load more data into a buffer, or terminate with an error.

Both of these problems are cases of loops where the interior of the loop can be expressed neatly, but the edges need special handling. I find these sort of problems the most prone to error and to messy programming. So here's my question: Are there any C++ idioms which generalize wrapping such loop patterns in a clean way?

Aucun commentaire:

Enregistrer un commentaire