ulfben
ulfben

Reputation: 151

How do I replace this raw loop with an STL algorithm or iterators? (avoiding unchecked subscript operator)

I'm implementing a generic clone of the Snake game in C++ as an exercise in following the C++ Recommended Guidelines. I'm currently working on the Snake's update() method, which is tiggering a Guideline-violation for using the unchecked subscript operator in a for loop:

Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).

I want to avoid the redundant range change check of gsl::at() / container::at(), and don't want to suppress the warning either. With that in mind, how can I replace this raw loop with something more Guideline-friendly? (eg. an STL algorithm, iterators, what have you)

void Snake::update() noexcept {  
  if (hasTrailingSegments()) {
    for (auto i = body_segments.size() - 1; i > 0; i--) {
      body_segments[i] = body_segments[i - 1];
    }
  }  
  head() += heading;  
}

The code explained, bottom up:

Upvotes: 1

Views: 227

Answers (1)

Caleth
Caleth

Reputation: 62686

You can std::rotate the snake so that the old tail is the front element, and then overwrite that with the new segment.

void Snake::update() noexcept {
  auto new_head = head() + heading;
  std::rotate(body_segments.begin(), body_segments.end() - 1, body_segments.end());
  head() = std::move(new_head);
}

Alternatively, you can copy_backward the body, overwriting the tail.

void Snake::update() noexcept {
  std::copy_backward(body_segments.begin(), body_segments.end() - 1, body_segments.end());
  head() += heading;
}

These are safe so long as a Snake always has at least one segment, which head() requires anyway.

Upvotes: 3

Related Questions