aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-09-30 11:25:15 +0100
committerJonathan Wakely <jwakely@redhat.com>2021-10-01 15:04:02 +0100
commitc67339d12653c33f85f8141789d7a7cf38831cbd (patch)
tree302b3b263e2b706df3a165a2e1a75344b121ce0f
parentb8d42cfa84fb31e592411e6cea41bdde980c51d7 (diff)
downloadgcc-c67339d12653c33f85f8141789d7a7cf38831cbd.zip
gcc-c67339d12653c33f85f8141789d7a7cf38831cbd.tar.gz
gcc-c67339d12653c33f85f8141789d7a7cf38831cbd.tar.bz2
libstdc++: Fix _ForwardIteratorConcept for __gnu_debug::vector<bool>
The recent changes to the _GLIBCXX_CONCEPT_CHECKS checks for forward iterators don't work for vector<bool> iterators in debug mode, because the _Safe_iterator specializations don't match the special cases I added for _Bit_iterator and _Bit_const_iterator. This refactors the _ForwardIteratorReferenceConcept class template to identify vector<bool> iterators using a new trait, which also works for debug iterators. libstdc++-v3/ChangeLog: * include/bits/boost_concept_check.h (_Is_vector_bool_iterator): New trait to identify vector<bool> iterators, including debug ones. (_ForwardIteratorReferenceConcept): Add default template argument using _Is_vector_bool_iterator and use it in partial specialization for the vector<bool> cases. (_Mutable_ForwardIteratorReferenceConcept): Likewise. * testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error line number.
-rw-r--r--libstdc++-v3/include/bits/boost_concept_check.h58
-rw-r--r--libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc2
2 files changed, 43 insertions, 17 deletions
diff --git a/libstdc++-v3/include/bits/boost_concept_check.h b/libstdc++-v3/include/bits/boost_concept_check.h
index 71c99c1..8135251 100644
--- a/libstdc++-v3/include/bits/boost_concept_check.h
+++ b/libstdc++-v3/include/bits/boost_concept_check.h
@@ -47,11 +47,19 @@
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Bit_iterator;
struct _Bit_const_iterator;
+_GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_END_NAMESPACE_VERSION
}
+namespace __gnu_debug
+{
+ template<typename _Iterator, typename _Sequence, typename _Category>
+ class _Safe_iterator;
+}
+
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -478,10 +486,32 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
_ValueT __val() const;
};
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-variable"
+ template<typename _Tp>
+ struct _Is_vector_bool_iterator
+ { static const bool __value = false; };
- template <class _Tp>
+#ifdef _GLIBCXX_DEBUG
+ namespace __cont = ::std::_GLIBCXX_STD_C;
+#else
+ namespace __cont = ::std;
+#endif
+
+ // Trait to identify vector<bool>::iterator
+ template <>
+ struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
+ { static const bool __value = true; };
+
+ // And for vector<bool>::const_iterator.
+ template <>
+ struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
+ { static const bool __value = true; };
+
+ // And for __gnu_debug::vector<bool> iterators too.
+ template <typename _It, typename _Seq, typename _Tag>
+ struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> >
+ : _Is_vector_bool_iterator<_It> { };
+
+ template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
struct _ForwardIteratorReferenceConcept
{
void __constraints() {
@@ -493,7 +523,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
}
};
- template <class _Tp>
+ template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
struct _Mutable_ForwardIteratorReferenceConcept
{
void __constraints() {
@@ -503,26 +533,22 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
}
};
- // vector<bool>::iterator is not a real forward reference, but pretend it is.
- template <>
- struct _ForwardIteratorReferenceConcept<std::_Bit_iterator>
+ // vector<bool> iterators are not real forward iterators, but we ignore that.
+ template <class _Tp>
+ struct _ForwardIteratorReferenceConcept<_Tp, true>
{
void __constraints() { }
};
- // vector<bool>::iterator is not a real forward reference, but pretend it is.
- template <>
- struct _Mutable_ForwardIteratorReferenceConcept<std::_Bit_iterator>
+ // vector<bool> iterators are not real forward iterators, but we ignore that.
+ template <class _Tp>
+ struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
{
void __constraints() { }
};
- // And vector<bool>::const iterator too.
- template <>
- struct _ForwardIteratorReferenceConcept<std::_Bit_const_iterator>
- {
- void __constraints() { }
- };
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
template <class _Tp>
struct _ForwardIteratorConcept
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc b/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
index d224919..cc64854 100644
--- a/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
+++ b/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
@@ -38,5 +38,5 @@ test02()
{
const Y array[1] = { };
(void) std::prev(array + 1);
- // { dg-error "forward_iterator" "" { target *-*-* } 231 }
+ // { dg-error "forward_iterator" "" { target *-*-* } 239 }
}