aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/include/bits/cpp_type_traits.h28
-rw-r--r--libstdc++-v3/include/bits/stl_iterator_base_funcs.h19
-rw-r--r--libstdc++-v3/testsuite/24_iterators/operations/40497.cc41
4 files changed, 92 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 82d13da..0af8ae6 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2010-05-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40497
+ * include/bits/cpp_type_traits.h (__is_iterator): Add.
+ * include/bits/stl_iterator_base_funcs.h (next, prev): Use it.
+ * testsuite/24_iterators/operations/40497.cc: New.
+
2010-05-21 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/25306
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h
index 0d7b9ff..8c5d8e9 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -414,6 +414,34 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
};
#endif
+ template<typename _Tp>
+ class __is_iterator_helper
+ {
+ typedef char __one;
+ typedef struct { char __arr[2]; } __two;
+
+ template<typename _Up>
+ struct _Wrap_type
+ { };
+
+ template<typename _Up>
+ static __one __test(_Wrap_type<typename _Up::iterator_category>*);
+
+ template<typename _Up>
+ static __two __test(...);
+
+ public:
+ static const bool __value = (sizeof(__test<_Tp>(0)) == 1
+ || __is_pointer<_Tp>::__value);
+ };
+
+ template<typename _Tp>
+ struct __is_iterator
+ {
+ enum { __value = __is_iterator_helper<_Tp>::__value };
+ typedef typename __truth_type<__value>::__type __type;
+ };
+
_GLIBCXX_END_NAMESPACE
#endif //_CPP_TYPE_TRAITS_H
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
index 627fbe9..50e0bca 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
@@ -61,6 +61,7 @@
#define _STL_ITERATOR_BASE_FUNCS_H 1
#pragma GCC system_header
+
#include <bits/concept_check.h>
_GLIBCXX_BEGIN_NAMESPACE(std)
@@ -172,9 +173,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
std::__advance(__i, __d, std::__iterator_category(__i));
}
+_GLIBCXX_END_NAMESPACE
+
#ifdef __GXX_EXPERIMENTAL_CXX0X__
+
+#include <ext/type_traits.h> // For __enable_if and __is_iterator
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
template<typename _ForwardIterator>
- inline _ForwardIterator
+ inline typename
+ __gnu_cxx::__enable_if<__is_iterator<_ForwardIterator>::__value,
+ _ForwardIterator>::__type
next(_ForwardIterator __x, typename
iterator_traits<_ForwardIterator>::difference_type __n = 1)
{
@@ -183,15 +193,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
template<typename _BidirectionalIterator>
- inline _BidirectionalIterator
+ inline typename
+ __gnu_cxx::__enable_if<__is_iterator<_BidirectionalIterator>::__value,
+ _BidirectionalIterator>::__type
prev(_BidirectionalIterator __x, typename
iterator_traits<_BidirectionalIterator>::difference_type __n = 1)
{
std::advance(__x, -__n);
return __x;
}
-#endif
_GLIBCXX_END_NAMESPACE
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
#endif /* _STL_ITERATOR_BASE_FUNCS_H */
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/40497.cc b/libstdc++-v3/testsuite/24_iterators/operations/40497.cc
new file mode 100644
index 0000000..59a64fb
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/operations/40497.cc
@@ -0,0 +1,41 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2010 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/>.
+
+namespace X
+{
+ class C { };
+
+ template<class T> void next(T) { }
+ template<class T> void prev(T) { }
+}
+
+using namespace X;
+
+#include <iterator>
+
+using namespace std;
+
+// libstdc++/40497
+void test01()
+{
+ C c;
+ next(c);
+ prev(c);
+}