Marco Leise:

  return s.chunks(2).map!(
    c => [cast(char)c.dropOne.front, cast(char)c.front]
  ).join;

So I would use the second version offered by bearophile:

  auto result = new char[s.length];
  foreach (immutable i, ref c; result)
    c = s[i + (i & 1 ? -1 : 1)];
  return result;

I can easily reason about it from looking at it. It makes one
allocation "new char[s.length]" and does no UTF-8 decoding.

But the first version with dropOne and two fronts is for me simper to see as correct, while in the second code I need a bit of thinking to prove there are no out of bounds accesses.

Perhaps for/foreach are becoming a code smell, they are becoming an optimization over the more common and safer functional code (or an alternative solution where the functional code is a problem).

To avoid the conditional (I have not benchmarked them):

c = s[i + (2 * !(i & 1) - 1)];

Bye,
bearophile

Reply via email to