Title
Off by one error in std::reverse_copy
Status
c++14
Section
[alg.reverse]
Submitter
Peter Miller

Created on 2011-08-17.00:00:00 last changed 123 months ago

Messages

Date: 2012-11-03.04:16:46

Proposed resolution:

This wording is relative to the FDIS.

Change [alg.reverse] p4 as follows:

template<class BidirectionalIterator, class OutputIterator>
  OutputIterator
    reverse_copy(BidirectionalIterator first,
                 BidirectionalIterator last, OutputIterator result);

-4- Effects: Copies the range [first,last) to the range [result,result+(last-first)) such that for any non-negative integer i < (last - first) the following assignment takes place: *(result + (last - first) - 1 - i) = *(first + i).

-5- Requires: The ranges [first,last) and [result,result+(last-first)) shall not overlap.

-6- Returns: result + (last - first).

-7- Complexity: Exactly last - first assignments.

Date: 2012-11-03.04:16:46

[ 2012, Portland: applied to WP ]

Date: 2012-02-12.18:36:43

[ 2012, Kona ]

Move to Ready.

Date: 2012-11-02.17:33:46

The output of the program below should be:

"three two one null \n"

But when std::reverse_copy is implemented as described in N3291 [alg.reverse] it's:

"null three two one \n"

because there's an off by one error in [alg.reverse]/4; the definition should read:

*(result + (last - first) - 1 - i) = *(first + i)

Test program:

#include <algorithm>
#include <iostream>

template <typename BiIterator, typename OutIterator>
auto
reverse_copy_as_described_in_N3291(
  BiIterator first, BiIterator last, OutIterator result )
-> OutIterator
{
  // 25.3.10/4 [alg.reverse]:
  // "...such that for any non-negative integer i < (last - first)..."
  for ( unsigned i = 0; i < ( last - first ); ++i )
    // "...the following assignment takes place:"
    *(result + (last - first) - i) = *(first + i);

  // 25.3.10/6
  return result + (last - first);
}

int main()
{
  using std::begin;
  using std::end;
  using std::cout;

  static const char*const in[3]  { "one", "two", "three" };
  const char*             out[4] { "null", "null", "null", "null" };

  reverse_copy_as_described_in_N3291( begin( in ), end( in ), out );

  for ( auto s : out )
    cout << s << ' ';

  cout << std::endl;

  return 0;
}
History
Date User Action Args
2014-02-20 13:20:35adminsetstatus: wp -> c++14
2012-11-03 04:16:46adminsetmessages: + msg6265
2012-10-25 12:46:45adminsetstatus: voting -> wp
2012-10-16 15:35:12adminsetstatus: ready -> voting
2012-02-12 18:36:43adminsetmessages: + msg5999
2012-02-12 18:36:43adminsetstatus: new -> ready
2011-11-22 22:51:03adminsetmessages: + msg5887
2011-08-17 00:00:00admincreate