re PR libstdc++/59434 ([lwg/2106] move_iterator is broken for input iterators with...
authorMarc Glisse <marc.glisse@inria.fr>
Fri, 11 Apr 2014 19:23:49 +0000 (21:23 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Fri, 11 Apr 2014 19:23:49 +0000 (19:23 +0000)
2014-04-11  Marc Glisse  <marc.glisse@inria.fr>

PR libstdc++/59434
* include/bits/stl_iterator.h (move_iterator::reference,
move_iterator::operator*): Implement LWG 2106.
* testsuite/24_iterators/move_iterator/dr2106.cc: New file.

From-SVN: r209323

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_iterator.h
libstdc++-v3/testsuite/24_iterators/move_iterator/dr2106.cc [new file with mode: 0644]

index 1af136e..1d0e19a 100644 (file)
@@ -1,5 +1,12 @@
 2014-04-11  Marc Glisse  <marc.glisse@inria.fr>
 
+       PR libstdc++/59434
+       * include/bits/stl_iterator.h (move_iterator::reference,
+       move_iterator::operator*): Implement LWG 2106.
+       * testsuite/24_iterators/move_iterator/dr2106.cc: New file.
+
+2014-04-11  Marc Glisse  <marc.glisse@inria.fr>
+
        * include/std/complex (__complex_exp, pow): Specify the template
        parameter in calls to std::polar, for expression templates.
 
index 1d2a524..16f992c 100644 (file)
@@ -965,6 +965,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Iterator _M_current;
 
       typedef iterator_traits<_Iterator>               __traits_type;
+      typedef typename __traits_type::reference                __base_ref;
 
     public:
       typedef _Iterator                                        iterator_type;
@@ -973,7 +974,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef typename __traits_type::difference_type  difference_type;
       // NB: DR 680.
       typedef _Iterator                                        pointer;
-      typedef value_type&&                             reference;
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2106. move_iterator wrapping iterators returning prvalues
+      typedef typename conditional<is_reference<__base_ref>::value,
+                        typename remove_reference<__base_ref>::type&&,
+                        __base_ref>::type              reference;
 
       move_iterator()
       : _M_current() { }
@@ -992,7 +997,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       reference
       operator*() const
-      { return std::move(*_M_current); }
+      { return static_cast<reference>(*_M_current); }
 
       pointer
       operator->() const
diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/dr2106.cc b/libstdc++-v3/testsuite/24_iterators/move_iterator/dr2106.cc
new file mode 100644 (file)
index 0000000..fc15562
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2014 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
+// <http://www.gnu.org/licenses/>.
+
+#include <iterator>
+#include <type_traits>
+#include <vector>
+
+typedef std::vector<bool>      Vec;
+typedef Vec::reference         Ref;
+typedef Vec::const_reference   CRef;
+typedef Vec::iterator          It;
+typedef Vec::const_iterator    CIt;
+typedef std::move_iterator<It> MIt;
+typedef std::move_iterator<CIt>        MCIt;
+static_assert(std::is_same<MIt::reference, Ref>::value,"");
+static_assert(std::is_same<MCIt::reference, CRef>::value,"");