This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
PR 58148 patch
- From: François Dumont <frs dot dumont at gmail dot com>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Date: Mon, 26 Aug 2013 21:44:37 +0200
- Subject: PR 58148 patch
- Authentication-results: sourceware.org; auth=none
Hi
The problem exposed in PR 58148 is quite trivial, std::common_type
cannot find a result when instantiated with char* and const wchar_t*.
The attached patch will fix this problem by dealing with a
std::common_type resolution failure even if the drawback is that
following call won't be detected as an invalid one anymore:
std::vector<int> v;
....
v.insert(v.begin(), reinterpret_cast<char*>(v.data() + 1),
reinterpret_cast<char*>(v.data() + 5)); // Expected failure
So I wonder why we can't simply use std::less<const volatile void*>
and std::greater_equal<const volatile void*> ? Would there be any
portability issue ? I remember that in the past a function pointer could
not be casted to void* but I don't think it is still true. And even if
it is so I can simply check that the result of the std::addressof call
can be passed transparently as const volatile void*.
François
Index: include/debug/functions.h
===================================================================
--- include/debug/functions.h (revision 201966)
+++ include/debug/functions.h (working copy)
@@ -172,17 +172,19 @@
}
#if __cplusplus >= 201103L
+ // Default implementation.
template<typename _Iterator, typename _Sequence,
typename _InputIterator,
typename _PointerType1,
- typename _PointerType2>
+ typename _PointerType2,
+ typename _PointerType
+ = typename std::common_type<_PointerType1,
+ _PointerType2>::type>
inline bool
__foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it,
_InputIterator __other,
_PointerType1, _PointerType2)
{
- typedef typename std::common_type<_PointerType1,
- _PointerType2>::type _PointerType;
constexpr std::less<_PointerType> __l{};
constexpr std::greater_equal<_PointerType> __ge{};
@@ -192,7 +194,15 @@
std::addressof(*(__it._M_get_sequence()->_M_base().end()
- 1)) + 1));
}
-
+
+ // Fallback when std::common_type fail.
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&,
+ _InputIterator, ...)
+ { return true; }
+
template<typename _Iterator, typename _Sequence, typename _InputIterator>
inline bool
__foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
@@ -223,7 +233,7 @@
std::false_type)
{ return true; }
#endif
-
+
/** Checks that iterators do not belong to the same sequence. */
template<typename _Iterator, typename _Sequence, typename _OtherIterator>
inline bool