Message ID | 543ED3C5.4000804@gmail.com |
---|---|
State | New |
Headers | show |
On 15/10/14 22:06 +0200, François Dumont wrote: >On 15/10/2014 13:10, Jonathan Wakely wrote: >> >>I find this much easier to read: >> >>#if __cplusplus < 201103L >> typedef _Is_contiguous_sequence<_Sequence> __tag; >>#else >> using __lvalref = std::is_lvalue_reference< >> typename std::iterator_traits<_InputIterator>::reference>; >> using __contiguous = _Is_contiguous_sequence<_Sequence>; >> using __tag = typename std::conditional<__lvalref::value, >>__contiguous, >>std::__false_type>::type; >>#endif >> return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); >> >>It only has one preprocessor condition and it avoids mismatched >>parentheses caused by opening the function parameter list once but >>closing it twice in two different branches. >> >> >That's much better indeed. > > Shall we go with this ? Yes, it looks good to me, thanks. >Of course we are simply considering that >we can't check for foreign iterators when some iterator adapters comes >in-between. I hope one day to detect invalid usages even in this >context. I agree that's OK.
On 15/10/14 22:06 +0200, François Dumont wrote: >On 15/10/2014 13:10, Jonathan Wakely wrote: >> >>I find this much easier to read: >> >>#if __cplusplus < 201103L >> typedef _Is_contiguous_sequence<_Sequence> __tag; >>#else >> using __lvalref = std::is_lvalue_reference< >> typename std::iterator_traits<_InputIterator>::reference>; >> using __contiguous = _Is_contiguous_sequence<_Sequence>; >> using __tag = typename std::conditional<__lvalref::value, >>__contiguous, >>std::__false_type>::type; >>#endif >> return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); >> >>It only has one preprocessor condition and it avoids mismatched >>parentheses caused by opening the function parameter list once but >>closing it twice in two different branches. >> >> >That's much better indeed. > > Shall we go with this ? Of course we are simply considering that >we can't check for foreign iterators when some iterator adapters comes >in-between. I hope one day to detect invalid usages even in this >context. > >2014-10-16 François Dumont <fdumont@gcc.gnu.org> > > PR libstdc++/63500 > * include/debug/functions.h (__foreign_iterator_aux2): Do not check for > foreign iterators if input iterators returns rvalue reference. > * testsuite/23_containers/vector/63500.cc: New. > >François > As this is a regression it should go on the 4.9 branch too. >Index: include/debug/functions.h >=================================================================== >--- include/debug/functions.h (revision 216279) >+++ include/debug/functions.h (working copy) >@@ -34,7 +34,7 @@ > // _Iter_base > #include <bits/cpp_type_traits.h> // for __is_integer > #include <bits/move.h> // for __addressof and addressof >-# include <bits/stl_function.h> // for less >+#include <bits/stl_function.h> // for less > #if __cplusplus >= 201103L > # include <type_traits> // for is_lvalue_reference and __and_ > #endif >@@ -252,8 +252,16 @@ > const _InputIterator& __other, > const _InputIterator& __other_end) > { >- return __foreign_iterator_aux3(__it, __other, __other_end, >- _Is_contiguous_sequence<_Sequence>()); >+#if __cplusplus < 201103L >+ typedef _Is_contiguous_sequence<_Sequence> __tag; >+#else >+ using __lvalref = std::is_lvalue_reference< >+ typename std::iterator_traits<_InputIterator>::reference>; >+ using __contiguous = _Is_contiguous_sequence<_Sequence>; >+ using __tag = typename std::conditional<__lvalref::value, __contiguous, >+ std::__false_type>::type; >+#endif >+ return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); > } > > /* Handle the case where we aren't really inserting a range after all */ >Index: testsuite/23_containers/vector/63500.cc >=================================================================== >--- testsuite/23_containers/vector/63500.cc (revision 0) >+++ testsuite/23_containers/vector/63500.cc (working copy) >@@ -0,0 +1,39 @@ >+// -*- C++ -*- >+ >+// 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/>. >+ >+// { dg-options "-std=gnu++11" } >+// { dg-do compile } >+ >+#include <memory> >+#include <iterator> >+#include <debug/vector> >+ >+class Foo >+{}; >+ >+void >+test01() >+{ >+ __gnu_debug::vector<std::unique_ptr<Foo>> v; >+ __gnu_debug::vector<std::unique_ptr<Foo>> w; >+ >+ v.insert(end(v), >+ make_move_iterator(begin(w)), >+ make_move_iterator(end(w))); >+}
Index: include/debug/functions.h =================================================================== --- include/debug/functions.h (revision 216279) +++ include/debug/functions.h (working copy) @@ -34,7 +34,7 @@ // _Iter_base #include <bits/cpp_type_traits.h> // for __is_integer #include <bits/move.h> // for __addressof and addressof -# include <bits/stl_function.h> // for less +#include <bits/stl_function.h> // for less #if __cplusplus >= 201103L # include <type_traits> // for is_lvalue_reference and __and_ #endif @@ -252,8 +252,16 @@ const _InputIterator& __other, const _InputIterator& __other_end) { - return __foreign_iterator_aux3(__it, __other, __other_end, - _Is_contiguous_sequence<_Sequence>()); +#if __cplusplus < 201103L + typedef _Is_contiguous_sequence<_Sequence> __tag; +#else + using __lvalref = std::is_lvalue_reference< + typename std::iterator_traits<_InputIterator>::reference>; + using __contiguous = _Is_contiguous_sequence<_Sequence>; + using __tag = typename std::conditional<__lvalref::value, __contiguous, + std::__false_type>::type; +#endif + return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); } /* Handle the case where we aren't really inserting a range after all */ Index: testsuite/23_containers/vector/63500.cc =================================================================== --- testsuite/23_containers/vector/63500.cc (revision 0) +++ testsuite/23_containers/vector/63500.cc (working copy) @@ -0,0 +1,39 @@ +// -*- C++ -*- + +// 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/>. + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <memory> +#include <iterator> +#include <debug/vector> + +class Foo +{}; + +void +test01() +{ + __gnu_debug::vector<std::unique_ptr<Foo>> v; + __gnu_debug::vector<std::unique_ptr<Foo>> w; + + v.insert(end(v), + make_move_iterator(begin(w)), + make_move_iterator(end(w))); +}