summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/debug/functions.h
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/debug/functions.h')
-rw-r--r--libstdc++-v3/include/debug/functions.h127
1 files changed, 126 insertions, 1 deletions
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index 3f16098185c..87478c6fbc1 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -32,7 +32,11 @@
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and
// _Iter_base
-#include <bits/cpp_type_traits.h> // for __is_integer
+#include <bits/cpp_type_traits.h> // for __is_integer
+#if __cplusplus >= 201103L
+# include <bits/stl_function.h> // for less and greater_equal
+# include <type_traits> // for common_type
+#endif
#include <debug/formatter.h>
namespace __gnu_debug
@@ -40,6 +44,10 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
class _Safe_iterator;
+ template<typename _Sequence>
+ struct _Insert_range_from_self_is_safe
+ { enum { __value = 0 }; };
+
// An arbitrary iterator pointer is not singular.
inline bool
__check_singular_aux(const void*) { return false; }
@@ -162,6 +170,123 @@ namespace __gnu_debug
return __first;
}
+#if __cplusplus >= 201103L
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator,
+ typename _PointerType1,
+ typename _PointerType2>
+ inline bool
+ __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ _PointerType1, _PointerType2)
+ {
+ typedef typename std::common_type<_PointerType1,
+ _PointerType2>::type _PointerType;
+ std::less<_PointerType> __l;
+ std::greater_equal<_PointerType> __ge;
+
+ return
+ __l(std::addressof(*__other),
+ std::addressof(*(__it._M_get_sequence()->_M_base().begin())))
+ || __ge(std::addressof(*__other),
+ std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + 1);
+
+ }
+
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::true_type)
+ {
+ // Only containers with all elements in contiguous memory can have their
+ // elements passed through pointers.
+ // Arithmetics is here just to make sure we are not dereferencing
+ // past-the-end iterator.
+ if (__it._M_get_sequence()->_M_base().begin()
+ != __it._M_get_sequence()->_M_base().end())
+ if (std::__addressof(*(__it._M_get_sequence()->_M_base().end() - 1))
+ - std::__addressof(*(__it._M_get_sequence()->_M_base().begin()))
+ == __it._M_get_sequence()->size() - 1)
+ return __foreign_iterator_aux4(__it, __other,
+ std::addressof(*(__it._M_get_sequence()->_M_base().begin())),
+ std::addressof(*__other));
+ return true;
+ }
+
+ /* Fallback overload for which we can't say, assume it is valid. */
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ 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
+ __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ const _Safe_iterator<_OtherIterator, _Sequence>& __other,
+ std::input_iterator_tag)
+ { return __it._M_get_sequence() != __other._M_get_sequence(); }
+
+#if __cplusplus >= 201103L
+ /* This overload detects when passing pointers to the contained elements rather
+ than using iterators.
+ */
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::random_access_iterator_tag)
+ {
+ typedef typename _Sequence::const_iterator _ItType;
+ typedef typename std::iterator_traits<_ItType>::reference _Ref;
+ return __foreign_iterator_aux3(__it, __other,
+ std::is_lvalue_reference<_Ref>());
+ }
+#endif
+
+ /* Fallback overload for which we can't say, assume it is valid. */
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>&,
+ _InputIterator,
+ std::input_iterator_tag)
+ { return true; }
+
+ template<typename _Iterator, typename _Sequence,
+ typename _Integral>
+ inline bool
+ __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _Integral __other,
+ std::__true_type)
+ { return true; }
+
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::__false_type)
+ {
+ return
+ _Insert_range_from_self_is_safe<_Sequence>::__value
+ || __foreign_iterator_aux2(__it, __other,
+ std::__iterator_category(__it));
+ }
+
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other)
+ {
+ typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+ return __foreign_iterator_aux(__it, __other, _Integral());
+ }
+
/** Checks that __s is non-NULL or __n == 0, and then returns __s. */
template<typename _CharT, typename _Integer>
inline const _CharT*