Re: [PATH 3/3] libstdc++: Add std::advance ostreambuf_iterator overload

2020-09-22 Thread Jonathan Wakely via Gcc-patches

On 14/09/20 22:36 +0200, François Dumont via Libstdc++ wrote:

On 10/09/20 5:19 pm, Jonathan Wakely wrote:

On 09/09/20 22:12 +0200, François Dumont via Libstdc++ wrote:

libstdc++: Add std::advance overload for ostreambuf_iterator

Implement std::advance overload for ostreambuf_iterator using 
basic_streambuf

pubseekof.

libstdc++-v3/ChangeLog:

        * include/bits/streambuf_iterator.h 
(ostreambuf_iterator): Add

        std::advance friend declaration.
        (advance(ostreambuf_iterator<>&, _Distance)): New.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2_neg.cc:

        New test.

Tested under Linux x85_64.

Ok to commit ?


I think relying on seeking here is a bad idea for the same reason as
in my previous email. We don't know what seek does for an arbitrary
derived streambuf, or even if it is possible at all.


After having implementing it similarly to the overload on 
istreambuf_iterator I wrote a test to compare the std;;advance 
behavior with a manual increment. And so I realized that incrementing 
a ostreambuf_iterator is a no-op and so must be the std::advance 
unless you tell otherwise.


There was a reason for this overload to be missing.


OK, good to know.




Re: [PATH 3/3] libstdc++: Add std::advance ostreambuf_iterator overload

2020-09-14 Thread François Dumont via Gcc-patches

On 10/09/20 5:19 pm, Jonathan Wakely wrote:

On 09/09/20 22:12 +0200, François Dumont via Libstdc++ wrote:

libstdc++: Add std::advance overload for ostreambuf_iterator

Implement std::advance overload for ostreambuf_iterator using 
basic_streambuf

pubseekof.

libstdc++-v3/ChangeLog:

        * include/bits/streambuf_iterator.h 
(ostreambuf_iterator): Add

        std::advance friend declaration.
        (advance(ostreambuf_iterator<>&, _Distance)): New.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2_neg.cc:

        New test.

Tested under Linux x85_64.

Ok to commit ?


I think relying on seeking here is a bad idea for the same reason as
in my previous email. We don't know what seek does for an arbitrary
derived streambuf, or even if it is possible at all.


After having implementing it similarly to the overload on 
istreambuf_iterator I wrote a test to compare the std;;advance behavior 
with a manual increment. And so I realized that incrementing a 
ostreambuf_iterator is a no-op and so must be the std::advance unless 
you tell otherwise.


There was a reason for this overload to be missing.

Thanks for the review,

François



Re: [PATH 3/3] libstdc++: Add std::advance ostreambuf_iterator overload

2020-09-10 Thread François Dumont via Gcc-patches

On 10/09/20 5:19 pm, Jonathan Wakely wrote:

On 09/09/20 22:12 +0200, François Dumont via Libstdc++ wrote:

libstdc++: Add std::advance overload for ostreambuf_iterator

Implement std::advance overload for ostreambuf_iterator using 
basic_streambuf

pubseekof.

libstdc++-v3/ChangeLog:

        * include/bits/streambuf_iterator.h 
(ostreambuf_iterator): Add

        std::advance friend declaration.
        (advance(ostreambuf_iterator<>&, _Distance)): New.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2.cc:

        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2_neg.cc:

        New test.

Tested under Linux x85_64.

Ok to commit ?


I think relying on seeking here is a bad idea for the same reason as
in my previous email. We don't know what seek does for an arbitrary
derived streambuf, or even if it is possible at all.



Ok, I'll rework this one based on the others' feedback.

Thanks



Re: [PATH 3/3] libstdc++: Add std::advance ostreambuf_iterator overload

2020-09-10 Thread Jonathan Wakely via Gcc-patches

On 09/09/20 22:12 +0200, François Dumont via Libstdc++ wrote:

libstdc++: Add std::advance overload for ostreambuf_iterator

Implement std::advance overload for ostreambuf_iterator using 
basic_streambuf

pubseekof.

libstdc++-v3/ChangeLog:

        * include/bits/streambuf_iterator.h (ostreambuf_iterator): Add
        std::advance friend declaration.
        (advance(ostreambuf_iterator<>&, _Distance)): New.
        * testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc:
        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc:

        New test.
        * testsuite/25_algorithms/advance/ostreambuf_iterator/char/2.cc:
        New test.
        * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2_neg.cc:

        New test.

Tested under Linux x85_64.

Ok to commit ?


I think relying on seeking here is a bad idea for the same reason as
in my previous email. We don't know what seek does for an arbitrary
derived streambuf, or even if it is possible at all.




[PATH 3/3] libstdc++: Add std::advance ostreambuf_iterator overload

2020-09-09 Thread François Dumont via Gcc-patches

libstdc++: Add std::advance overload for ostreambuf_iterator

Implement std::advance overload for ostreambuf_iterator using 
basic_streambuf

pubseekof.

libstdc++-v3/ChangeLog:

    * include/bits/streambuf_iterator.h (ostreambuf_iterator): Add
    std::advance friend declaration.
    (advance(ostreambuf_iterator<>&, _Distance)): New.
    * testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc:
    New test.
    * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc:

    New test.
    * testsuite/25_algorithms/advance/ostreambuf_iterator/char/2.cc:
    New test.
    * 
testsuite/25_algorithms/advance/ostreambuf_iterator/char/2_neg.cc:

    New test.

Tested under Linux x85_64.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h
index afe967e5f03..1f6613e9ef6 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -257,6 +257,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
 	 ostreambuf_iterator<_CharT2>);
 
+  template
+	friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
+	   void>::__type
+	advance(ostreambuf_iterator<_CharT2>&, _Distance);
+
 private:
   streambuf_type*	_M_sbuf;
   bool		_M_failed;
@@ -405,7 +410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
-		  		istreambuf_iterator<_CharT> >::__type
+istreambuf_iterator<_CharT> >::__type
 find(istreambuf_iterator<_CharT> __first,
 	 istreambuf_iterator<_CharT> __last, const _CharT& __val)
 {
@@ -475,6 +480,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 }
 
+  template
+typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
+void>::__type
+advance(ostreambuf_iterator<_CharT>& __i, _Distance __n)
+{
+  if (__n == 0)
+	return;
+
+  __glibcxx_assert(__n > 0);
+  __glibcxx_requires_cond(!__i.failed(),
+			  _M_message(__gnu_debug::__msg_advance_oob)
+			  ._M_iterator(__i)
+			  ._M_integer(__n));
+
+  typedef basic_streambuf<_CharT> __streambuf_t;
+  typedef typename __streambuf_t::pos_type __pos_t;
+  __pos_t __cur_pos
+	= __i._M_sbuf->pubseekoff(0, ios_base::cur, ios_base::out);
+  __pos_t __new_pos =
+	__i._M_sbuf->pubseekoff(__n, ios_base::cur, ios_base::out);
+
+  if (__new_pos - __cur_pos != __n)
+	{
+	  __i._M_failed = true;
+	  __glibcxx_requires_cond(!__i.failed(),
+  _M_message(__gnu_debug::__msg_advance_oob)
+  ._M_iterator(__i)
+  ._M_integer(__n));
+	}
+}
+
 // @} group iterators
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc
new file mode 100644
index 000..dd70cc67c75
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/advance/ostreambuf_iterator/char/1.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+#include 
+#include 
+#include 
+
+#include 
+
+void test01()
+{
+  using namespace std;
+
+  const char data1[] = "Drei Phantasien nach Friedrich Holderlin";
+  string str1(data1);
+  str1[17] = 'i';
+
+  ostringstream oss1(str1);
+  ostreambuf_iterator beg1(oss1);
+
+  std::advance(beg1, 17);
+  *beg1 = 'a';
+
+  VERIFY( !beg1.failed() );
+  VERIFY( oss1.str() == data1 );
+  str1 = oss1.str();
+
+  // -1 for the trailing '\0'
+  // -1 for the beg1 assignment.
+  std::advance(beg1, sizeof(data1) - 17 - 1 - 1);
+  *beg1 = '.';
+
+  str1 += '.';
+  VERIFY( oss1.str() == str1 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc
new file mode 100644
index 000..8d266256ed3
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/advance/ostreambuf_iterator/char/1_neg.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.