/*
gcc -Wall -Wextra -std=c++11 copy_n_vs_copy.cpp -lstdc++ -o copy_n_vs_copy

One Past the End
https://gcc.gnu.org/onlinedocs/libstdc++/manual/iterators.html#iterators.predefined.end

BUG location:
/usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h

*/

#include <assert.h>
#include <iostream>
#include <sstream>
#include <algorithm>

int main()
 {
  std::string i("abc");
  std::string o;
  std::istringstream t;

  t=std::istringstream(i);
  o.clear();
  assert(3==t.rdbuf()->in_avail());
  std::copy(std::istreambuf_iterator<char>(t.rdbuf()),
   std::istreambuf_iterator<char>(),back_inserter(o));
  std::cout<<"Test1(copy):\tResult_size:"<<o.size()<<"\tResult:\""<<o
   <<"\"\tin_avail:"<<t.rdbuf()->in_avail()<<std::endl;
  assert(0==t.rdbuf()->in_avail()); /* OK! */

  t=std::istringstream(i);
  o.clear();
  assert(3==t.rdbuf()->in_avail());
  std::copy_n(std::istreambuf_iterator<char>(t.rdbuf()),
   3,back_inserter(o));
  std::cout<<"Test2(copy_n):\tResult_size:"<<o.size()<<"\tResult:\""<<o
   <<"\"\tin_avail:"<<t.rdbuf()->in_avail()<<std::endl;
  assert(1==t.rdbuf()->in_avail()); /* WHY? */

  return(0);
 }

/*
Test1(copy):  Result_size:3   Result:"abc"    in_avail:0
Test2(copy_n):  Result_size:3   Result:"abc"    in_avail:1
*/
--- /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h       
2015-02-19 20:57:40.000000000 +0000
+++ /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h       
2015-02-19 20:57:40.000000000 +0000
@@ -762,9 +762,8 @@
            {
              *__result = *__first;
              ++__result;
-             if (--__n > 0)
-               ++__first;
-             else
+             ++__first;
+             if (--__n <= 0)
                break;
            }
        }

Reply via email to