xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/debug/functions.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg // Debugging support implementation -*- C++ -*-
236ac495dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2003-2020 Free Software Foundation, Inc.
436ac495dSmrg //
536ac495dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
636ac495dSmrg // software; you can redistribute it and/or modify it under the
736ac495dSmrg // terms of the GNU General Public License as published by the
836ac495dSmrg // Free Software Foundation; either version 3, or (at your option)
936ac495dSmrg // any later version.
1036ac495dSmrg 
1136ac495dSmrg // This library is distributed in the hope that it will be useful,
1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1436ac495dSmrg // GNU General Public License for more details.
1536ac495dSmrg 
1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg // 3.1, as published by the Free Software Foundation.
1936ac495dSmrg 
2036ac495dSmrg // You should have received a copy of the GNU General Public License and
2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2336ac495dSmrg // <http://www.gnu.org/licenses/>.
2436ac495dSmrg 
2536ac495dSmrg /** @file debug/functions.h
2636ac495dSmrg  *  This file is a GNU debug extension to the Standard C++ Library.
2736ac495dSmrg  */
2836ac495dSmrg 
2936ac495dSmrg #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
3036ac495dSmrg #define _GLIBCXX_DEBUG_FUNCTIONS_H 1
3136ac495dSmrg 
3236ac495dSmrg #include <bits/stl_function.h>	// for less
33c0a68be4Smrg 
3436ac495dSmrg #if __cplusplus >= 201103L
35c0a68be4Smrg # include <bits/stl_iterator.h>	// for __miter_base
3636ac495dSmrg # include <type_traits>		// for is_lvalue_reference and conditional.
3736ac495dSmrg #endif
3836ac495dSmrg 
3936ac495dSmrg #include <debug/helper_functions.h>
4036ac495dSmrg #include <debug/formatter.h>
4136ac495dSmrg 
4236ac495dSmrg namespace __gnu_debug
4336ac495dSmrg {
4436ac495dSmrg   template<typename _Sequence>
4536ac495dSmrg     struct _Insert_range_from_self_is_safe
4636ac495dSmrg     { enum { __value = 0 }; };
4736ac495dSmrg 
4836ac495dSmrg   template<typename _Sequence>
4936ac495dSmrg     struct _Is_contiguous_sequence : std::__false_type { };
5036ac495dSmrg 
5136ac495dSmrg   /* Checks that [first, last) is a valid range, and then returns
5236ac495dSmrg    * __first. This routine is useful when we can't use a separate
5336ac495dSmrg    * assertion statement because, e.g., we are in a constructor.
5436ac495dSmrg   */
5536ac495dSmrg   template<typename _InputIterator>
5636ac495dSmrg     inline _InputIterator
__check_valid_range(const _InputIterator & __first,const _InputIterator & __last,const char * __file,unsigned int __line,const char * __function)5736ac495dSmrg     __check_valid_range(const _InputIterator& __first,
58c0a68be4Smrg 			const _InputIterator& __last,
59c0a68be4Smrg 			const char* __file,
60c0a68be4Smrg 			unsigned int __line,
61c0a68be4Smrg 			const char* __function)
6236ac495dSmrg     {
63c0a68be4Smrg       __glibcxx_check_valid_range_at(__first, __last,
64c0a68be4Smrg 				     __file, __line, __function);
6536ac495dSmrg       return __first;
6636ac495dSmrg     }
6736ac495dSmrg 
6836ac495dSmrg   /* Handle the case where __other is a pointer to _Sequence::value_type. */
69c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category>
7036ac495dSmrg     inline bool
__foreign_iterator_aux4(const _Safe_iterator<_Iterator,_Sequence,_Category> & __it,const typename _Sequence::value_type * __other)71c0a68be4Smrg     __foreign_iterator_aux4(
72c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
7336ac495dSmrg 	const typename _Sequence::value_type* __other)
7436ac495dSmrg     {
7536ac495dSmrg       typedef const typename _Sequence::value_type* _PointerType;
7636ac495dSmrg       typedef std::less<_PointerType> _Less;
7736ac495dSmrg #if __cplusplus >= 201103L
7836ac495dSmrg       constexpr _Less __l{};
7936ac495dSmrg #else
8036ac495dSmrg       const _Less __l = _Less();
8136ac495dSmrg #endif
8236ac495dSmrg       const _Sequence* __seq = __it._M_get_sequence();
8336ac495dSmrg       const _PointerType __begin = std::__addressof(*__seq->_M_base().begin());
8436ac495dSmrg       const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1));
8536ac495dSmrg 
8636ac495dSmrg       // Check whether __other points within the contiguous storage.
8736ac495dSmrg       return __l(__other, __begin) || __l(__end, __other);
8836ac495dSmrg     }
8936ac495dSmrg 
9036ac495dSmrg   /* Fallback overload for when we can't tell, assume it is valid. */
91c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category>
9236ac495dSmrg     inline bool
__foreign_iterator_aux4(const _Safe_iterator<_Iterator,_Sequence,_Category> &,...)93c0a68be4Smrg     __foreign_iterator_aux4(
94c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>&, ...)
9536ac495dSmrg     { return true; }
9636ac495dSmrg 
9736ac495dSmrg   /* Handle sequences with contiguous storage */
98c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
99c0a68be4Smrg 	   typename _InputIterator>
10036ac495dSmrg     inline bool
__foreign_iterator_aux3(const _Safe_iterator<_Iterator,_Sequence,_Category> & __it,const _InputIterator & __other,const _InputIterator & __other_end,std::__true_type)101c0a68be4Smrg     __foreign_iterator_aux3(
102c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
103c0a68be4Smrg 	const _InputIterator& __other, const _InputIterator& __other_end,
10436ac495dSmrg 	std::__true_type)
10536ac495dSmrg     {
10636ac495dSmrg       if (__other == __other_end)
10736ac495dSmrg 	return true;  // inserting nothing is safe even if not foreign iters
108c0a68be4Smrg       if (__it._M_get_sequence()->empty())
10936ac495dSmrg 	return true;  // can't be self-inserting if self is empty
11036ac495dSmrg       return __foreign_iterator_aux4(__it, std::__addressof(*__other));
11136ac495dSmrg     }
11236ac495dSmrg 
11336ac495dSmrg   /* Handle non-contiguous containers, assume it is valid. */
114c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
115c0a68be4Smrg 	   typename _InputIterator>
11636ac495dSmrg     inline bool
__foreign_iterator_aux3(const _Safe_iterator<_Iterator,_Sequence,_Category> &,const _InputIterator &,const _InputIterator &,std::__false_type)117c0a68be4Smrg     __foreign_iterator_aux3(
118c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>&,
11936ac495dSmrg 	const _InputIterator&, const _InputIterator&,
12036ac495dSmrg 	std::__false_type)
12136ac495dSmrg     { return true; }
12236ac495dSmrg 
12336ac495dSmrg   /** Handle debug iterators from the same type of container. */
124c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
125c0a68be4Smrg 	   typename _OtherIterator>
12636ac495dSmrg     inline bool
__foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence,_Category> & __it,const _Safe_iterator<_OtherIterator,_Sequence,_Category> & __other,const _Safe_iterator<_OtherIterator,_Sequence,_Category> &)127c0a68be4Smrg     __foreign_iterator_aux2(
128c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
129c0a68be4Smrg 	const _Safe_iterator<_OtherIterator, _Sequence, _Category>& __other,
130c0a68be4Smrg 	const _Safe_iterator<_OtherIterator, _Sequence, _Category>&)
13136ac495dSmrg     { return __it._M_get_sequence() != __other._M_get_sequence(); }
13236ac495dSmrg 
13336ac495dSmrg   /** Handle debug iterators from different types of container. */
134c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
135c0a68be4Smrg 	   typename _OtherIterator, typename _OtherSequence,
136c0a68be4Smrg 	   typename _OtherCategory>
13736ac495dSmrg     inline bool
__foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence,_Category> &,const _Safe_iterator<_OtherIterator,_OtherSequence,_OtherCategory> &,const _Safe_iterator<_OtherIterator,_OtherSequence,_OtherCategory> &)138c0a68be4Smrg     __foreign_iterator_aux2(
139c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>&,
140c0a68be4Smrg 	const _Safe_iterator<_OtherIterator, _OtherSequence,
141c0a68be4Smrg 			     _OtherCategory>&,
142c0a68be4Smrg 	const _Safe_iterator<_OtherIterator, _OtherSequence,
143c0a68be4Smrg 			     _OtherCategory>&)
14436ac495dSmrg     { return true; }
14536ac495dSmrg 
14636ac495dSmrg   /* Handle non-debug iterators. */
147c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
148c0a68be4Smrg 	   typename _InputIterator>
14936ac495dSmrg     inline bool
__foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence,_Category> & __it,const _InputIterator & __other,const _InputIterator & __other_end)150c0a68be4Smrg     __foreign_iterator_aux2(
151c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
15236ac495dSmrg 	const _InputIterator& __other,
15336ac495dSmrg 	const _InputIterator& __other_end)
15436ac495dSmrg     {
15536ac495dSmrg #if __cplusplus < 201103L
15636ac495dSmrg       typedef _Is_contiguous_sequence<_Sequence> __tag;
15736ac495dSmrg #else
15836ac495dSmrg       using __lvalref = std::is_lvalue_reference<
15936ac495dSmrg 	typename std::iterator_traits<_InputIterator>::reference>;
16036ac495dSmrg       using __contiguous = _Is_contiguous_sequence<_Sequence>;
16136ac495dSmrg       using __tag = typename std::conditional<__lvalref::value, __contiguous,
16236ac495dSmrg 					      std::__false_type>::type;
16336ac495dSmrg #endif
16436ac495dSmrg       return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
16536ac495dSmrg     }
16636ac495dSmrg 
16736ac495dSmrg   /* Handle the case where we aren't really inserting a range after all */
168c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
169c0a68be4Smrg 	   typename _Integral>
17036ac495dSmrg     inline bool
__foreign_iterator_aux(const _Safe_iterator<_Iterator,_Sequence,_Category> &,_Integral,_Integral,std::__true_type)171c0a68be4Smrg     __foreign_iterator_aux(
172c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>&,
173c0a68be4Smrg 	_Integral, _Integral, std::__true_type)
17436ac495dSmrg     { return true; }
17536ac495dSmrg 
17636ac495dSmrg   /* Handle all iterators. */
177c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
17836ac495dSmrg 	   typename _InputIterator>
17936ac495dSmrg     inline bool
__foreign_iterator_aux(const _Safe_iterator<_Iterator,_Sequence,_Category> & __it,_InputIterator __other,_InputIterator __other_end,std::__false_type)180c0a68be4Smrg     __foreign_iterator_aux(
181c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
18236ac495dSmrg 	_InputIterator __other, _InputIterator __other_end,
18336ac495dSmrg 	std::__false_type)
18436ac495dSmrg     {
18536ac495dSmrg       return _Insert_range_from_self_is_safe<_Sequence>::__value
18636ac495dSmrg 	|| __foreign_iterator_aux2(__it, std::__miter_base(__other),
18736ac495dSmrg 				   std::__miter_base(__other_end));
18836ac495dSmrg     }
18936ac495dSmrg 
190c0a68be4Smrg   template<typename _Iterator, typename _Sequence, typename _Category,
19136ac495dSmrg 	   typename _InputIterator>
19236ac495dSmrg     inline bool
__foreign_iterator(const _Safe_iterator<_Iterator,_Sequence,_Category> & __it,_InputIterator __other,_InputIterator __other_end)193c0a68be4Smrg     __foreign_iterator(
194c0a68be4Smrg 	const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
19536ac495dSmrg 	_InputIterator __other, _InputIterator __other_end)
19636ac495dSmrg     {
19736ac495dSmrg       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
19836ac495dSmrg       return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
19936ac495dSmrg     }
20036ac495dSmrg 
20136ac495dSmrg   // Can't check if an input iterator sequence is sorted, because we
20236ac495dSmrg   // can't step through the sequence.
20336ac495dSmrg   template<typename _InputIterator>
204*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
20536ac495dSmrg     inline bool
__check_sorted_aux(const _InputIterator &,const _InputIterator &,std::input_iterator_tag)20636ac495dSmrg     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
20736ac495dSmrg                        std::input_iterator_tag)
20836ac495dSmrg     { return true; }
20936ac495dSmrg 
21036ac495dSmrg   // Can verify if a forward iterator sequence is in fact sorted using
21136ac495dSmrg   // std::__is_sorted
21236ac495dSmrg   template<typename _ForwardIterator>
213*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
21436ac495dSmrg     inline bool
__check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)21536ac495dSmrg     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
21636ac495dSmrg                        std::forward_iterator_tag)
21736ac495dSmrg     {
21836ac495dSmrg       if (__first == __last)
21936ac495dSmrg         return true;
22036ac495dSmrg 
22136ac495dSmrg       _ForwardIterator __next = __first;
22236ac495dSmrg       for (++__next; __next != __last; __first = __next, (void)++__next)
22336ac495dSmrg         if (*__next < *__first)
22436ac495dSmrg           return false;
22536ac495dSmrg 
22636ac495dSmrg       return true;
22736ac495dSmrg     }
22836ac495dSmrg 
22936ac495dSmrg   // Can't check if an input iterator sequence is sorted, because we can't step
23036ac495dSmrg   // through the sequence.
23136ac495dSmrg   template<typename _InputIterator, typename _Predicate>
232*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
23336ac495dSmrg     inline bool
__check_sorted_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::input_iterator_tag)23436ac495dSmrg     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
23536ac495dSmrg                        _Predicate, std::input_iterator_tag)
23636ac495dSmrg     { return true; }
23736ac495dSmrg 
23836ac495dSmrg   // Can verify if a forward iterator sequence is in fact sorted using
23936ac495dSmrg   // std::__is_sorted
24036ac495dSmrg   template<typename _ForwardIterator, typename _Predicate>
241*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
24236ac495dSmrg     inline bool
__check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred,std::forward_iterator_tag)24336ac495dSmrg     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
24436ac495dSmrg                        _Predicate __pred, std::forward_iterator_tag)
24536ac495dSmrg     {
24636ac495dSmrg       if (__first == __last)
24736ac495dSmrg         return true;
24836ac495dSmrg 
24936ac495dSmrg       _ForwardIterator __next = __first;
25036ac495dSmrg       for (++__next; __next != __last; __first = __next, (void)++__next)
25136ac495dSmrg         if (__pred(*__next, *__first))
25236ac495dSmrg           return false;
25336ac495dSmrg 
25436ac495dSmrg       return true;
25536ac495dSmrg     }
25636ac495dSmrg 
25736ac495dSmrg   // Determine if a sequence is sorted.
25836ac495dSmrg   template<typename _InputIterator>
259*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
26036ac495dSmrg     inline bool
__check_sorted(const _InputIterator & __first,const _InputIterator & __last)26136ac495dSmrg     __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
26236ac495dSmrg     {
26336ac495dSmrg       return __check_sorted_aux(__first, __last,
26436ac495dSmrg 				std::__iterator_category(__first));
26536ac495dSmrg     }
26636ac495dSmrg 
26736ac495dSmrg   template<typename _InputIterator, typename _Predicate>
268*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
26936ac495dSmrg     inline bool
__check_sorted(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred)27036ac495dSmrg     __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
27136ac495dSmrg                    _Predicate __pred)
27236ac495dSmrg     {
27336ac495dSmrg       return __check_sorted_aux(__first, __last, __pred,
27436ac495dSmrg 				std::__iterator_category(__first));
27536ac495dSmrg     }
27636ac495dSmrg 
27736ac495dSmrg   template<typename _InputIterator>
278*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
27936ac495dSmrg     inline bool
__check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,std::__true_type)28036ac495dSmrg     __check_sorted_set_aux(const _InputIterator& __first,
28136ac495dSmrg 			   const _InputIterator& __last,
28236ac495dSmrg 			   std::__true_type)
28336ac495dSmrg     { return __check_sorted(__first, __last); }
28436ac495dSmrg 
28536ac495dSmrg   template<typename _InputIterator>
286*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
28736ac495dSmrg     inline bool
__check_sorted_set_aux(const _InputIterator &,const _InputIterator &,std::__false_type)28836ac495dSmrg     __check_sorted_set_aux(const _InputIterator&,
28936ac495dSmrg 			   const _InputIterator&,
29036ac495dSmrg 			   std::__false_type)
29136ac495dSmrg     { return true; }
29236ac495dSmrg 
29336ac495dSmrg   template<typename _InputIterator, typename _Predicate>
294*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
29536ac495dSmrg     inline bool
__check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred,std::__true_type)29636ac495dSmrg     __check_sorted_set_aux(const _InputIterator& __first,
29736ac495dSmrg 			   const _InputIterator& __last,
29836ac495dSmrg 			   _Predicate __pred, std::__true_type)
29936ac495dSmrg     { return __check_sorted(__first, __last, __pred); }
30036ac495dSmrg 
30136ac495dSmrg   template<typename _InputIterator, typename _Predicate>
302*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
30336ac495dSmrg     inline bool
__check_sorted_set_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::__false_type)30436ac495dSmrg     __check_sorted_set_aux(const _InputIterator&,
30536ac495dSmrg 			   const _InputIterator&, _Predicate,
30636ac495dSmrg 			   std::__false_type)
30736ac495dSmrg     { return true; }
30836ac495dSmrg 
30936ac495dSmrg   // ... special variant used in std::merge, std::includes, std::set_*.
31036ac495dSmrg   template<typename _InputIterator1, typename _InputIterator2>
311*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
31236ac495dSmrg     inline bool
__check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &)31336ac495dSmrg     __check_sorted_set(const _InputIterator1& __first,
31436ac495dSmrg 		       const _InputIterator1& __last,
31536ac495dSmrg 		       const _InputIterator2&)
31636ac495dSmrg     {
31736ac495dSmrg       typedef typename std::iterator_traits<_InputIterator1>::value_type
31836ac495dSmrg 	_ValueType1;
31936ac495dSmrg       typedef typename std::iterator_traits<_InputIterator2>::value_type
32036ac495dSmrg 	_ValueType2;
32136ac495dSmrg 
32236ac495dSmrg       typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
32336ac495dSmrg 	_SameType;
32436ac495dSmrg       return __check_sorted_set_aux(__first, __last, _SameType());
32536ac495dSmrg     }
32636ac495dSmrg 
32736ac495dSmrg   template<typename _InputIterator1, typename _InputIterator2,
32836ac495dSmrg 	   typename _Predicate>
329*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
33036ac495dSmrg     inline bool
__check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &,_Predicate __pred)33136ac495dSmrg     __check_sorted_set(const _InputIterator1& __first,
33236ac495dSmrg 		       const _InputIterator1& __last,
33336ac495dSmrg 		       const _InputIterator2&, _Predicate __pred)
33436ac495dSmrg     {
33536ac495dSmrg       typedef typename std::iterator_traits<_InputIterator1>::value_type
33636ac495dSmrg 	_ValueType1;
33736ac495dSmrg       typedef typename std::iterator_traits<_InputIterator2>::value_type
33836ac495dSmrg 	_ValueType2;
33936ac495dSmrg 
34036ac495dSmrg       typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
34136ac495dSmrg 	_SameType;
34236ac495dSmrg       return __check_sorted_set_aux(__first, __last, __pred, _SameType());
34336ac495dSmrg    }
34436ac495dSmrg 
34536ac495dSmrg   // _GLIBCXX_RESOLVE_LIB_DEFECTS
34636ac495dSmrg   // 270. Binary search requirements overly strict
34736ac495dSmrg   // Determine if a sequence is partitioned w.r.t. this element.
34836ac495dSmrg   template<typename _ForwardIterator, typename _Tp>
349*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
35036ac495dSmrg     inline bool
__check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)35136ac495dSmrg     __check_partitioned_lower(_ForwardIterator __first,
35236ac495dSmrg 			      _ForwardIterator __last, const _Tp& __value)
35336ac495dSmrg     {
35436ac495dSmrg       while (__first != __last && *__first < __value)
35536ac495dSmrg 	++__first;
35636ac495dSmrg       if (__first != __last)
35736ac495dSmrg 	{
35836ac495dSmrg 	  ++__first;
35936ac495dSmrg 	  while (__first != __last && !(*__first < __value))
36036ac495dSmrg 	    ++__first;
36136ac495dSmrg 	}
36236ac495dSmrg       return __first == __last;
36336ac495dSmrg     }
36436ac495dSmrg 
36536ac495dSmrg   template<typename _ForwardIterator, typename _Tp>
366*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
36736ac495dSmrg     inline bool
__check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)36836ac495dSmrg     __check_partitioned_upper(_ForwardIterator __first,
36936ac495dSmrg 			      _ForwardIterator __last, const _Tp& __value)
37036ac495dSmrg     {
37136ac495dSmrg       while (__first != __last && !(__value < *__first))
37236ac495dSmrg 	++__first;
37336ac495dSmrg       if (__first != __last)
37436ac495dSmrg 	{
37536ac495dSmrg 	  ++__first;
37636ac495dSmrg 	  while (__first != __last && __value < *__first)
37736ac495dSmrg 	    ++__first;
37836ac495dSmrg 	}
37936ac495dSmrg       return __first == __last;
38036ac495dSmrg     }
38136ac495dSmrg 
38236ac495dSmrg   // Determine if a sequence is partitioned w.r.t. this element.
38336ac495dSmrg   template<typename _ForwardIterator, typename _Tp, typename _Pred>
384*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
38536ac495dSmrg     inline bool
__check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)38636ac495dSmrg     __check_partitioned_lower(_ForwardIterator __first,
38736ac495dSmrg 			      _ForwardIterator __last, const _Tp& __value,
38836ac495dSmrg 			      _Pred __pred)
38936ac495dSmrg     {
39036ac495dSmrg       while (__first != __last && bool(__pred(*__first, __value)))
39136ac495dSmrg 	++__first;
39236ac495dSmrg       if (__first != __last)
39336ac495dSmrg 	{
39436ac495dSmrg 	  ++__first;
39536ac495dSmrg 	  while (__first != __last && !bool(__pred(*__first, __value)))
39636ac495dSmrg 	    ++__first;
39736ac495dSmrg 	}
39836ac495dSmrg       return __first == __last;
39936ac495dSmrg     }
40036ac495dSmrg 
40136ac495dSmrg   template<typename _ForwardIterator, typename _Tp, typename _Pred>
402*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
40336ac495dSmrg     inline bool
__check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)40436ac495dSmrg     __check_partitioned_upper(_ForwardIterator __first,
40536ac495dSmrg 			      _ForwardIterator __last, const _Tp& __value,
40636ac495dSmrg 			      _Pred __pred)
40736ac495dSmrg     {
40836ac495dSmrg       while (__first != __last && !bool(__pred(__value, *__first)))
40936ac495dSmrg 	++__first;
41036ac495dSmrg       if (__first != __last)
41136ac495dSmrg 	{
41236ac495dSmrg 	  ++__first;
41336ac495dSmrg 	  while (__first != __last && bool(__pred(__value, *__first)))
41436ac495dSmrg 	    ++__first;
41536ac495dSmrg 	}
41636ac495dSmrg       return __first == __last;
41736ac495dSmrg     }
41836ac495dSmrg 
41936ac495dSmrg #if __cplusplus >= 201103L
42036ac495dSmrg   struct _Irreflexive_checker
42136ac495dSmrg   {
42236ac495dSmrg     template<typename _It>
42336ac495dSmrg       static typename std::iterator_traits<_It>::reference
424*8feb0f0bSmrg       __ref();
42536ac495dSmrg 
42636ac495dSmrg     template<typename _It,
427*8feb0f0bSmrg 	     typename = decltype(__ref<_It>() < __ref<_It>())>
428*8feb0f0bSmrg       _GLIBCXX20_CONSTEXPR
42936ac495dSmrg       static bool
_S_is_valid_Irreflexive_checker43036ac495dSmrg       _S_is_valid(_It __it)
43136ac495dSmrg       { return !(*__it < *__it); }
43236ac495dSmrg 
43336ac495dSmrg     // Fallback method if operator doesn't exist.
43436ac495dSmrg     template<typename... _Args>
435*8feb0f0bSmrg       _GLIBCXX20_CONSTEXPR
43636ac495dSmrg       static bool
_S_is_valid_Irreflexive_checker43736ac495dSmrg       _S_is_valid(_Args...)
43836ac495dSmrg       { return true; }
43936ac495dSmrg 
44036ac495dSmrg     template<typename _It, typename _Pred, typename
441*8feb0f0bSmrg 	= decltype(std::declval<_Pred>()(__ref<_It>(), __ref<_It>()))>
442*8feb0f0bSmrg       _GLIBCXX20_CONSTEXPR
44336ac495dSmrg       static bool
_S_is_valid_pred_Irreflexive_checker44436ac495dSmrg       _S_is_valid_pred(_It __it, _Pred __pred)
44536ac495dSmrg       { return !__pred(*__it, *__it); }
44636ac495dSmrg 
44736ac495dSmrg     // Fallback method if predicate can't be invoked.
44836ac495dSmrg     template<typename... _Args>
449*8feb0f0bSmrg       _GLIBCXX20_CONSTEXPR
45036ac495dSmrg       static bool
_S_is_valid_pred_Irreflexive_checker45136ac495dSmrg       _S_is_valid_pred(_Args...)
45236ac495dSmrg       { return true; }
45336ac495dSmrg   };
45436ac495dSmrg 
45536ac495dSmrg   template<typename _Iterator>
456*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
45736ac495dSmrg     inline bool
__is_irreflexive(_Iterator __it)45836ac495dSmrg     __is_irreflexive(_Iterator __it)
45936ac495dSmrg     { return _Irreflexive_checker::_S_is_valid(__it); }
46036ac495dSmrg 
46136ac495dSmrg   template<typename _Iterator, typename _Pred>
462*8feb0f0bSmrg     _GLIBCXX20_CONSTEXPR
46336ac495dSmrg     inline bool
__is_irreflexive_pred(_Iterator __it,_Pred __pred)46436ac495dSmrg     __is_irreflexive_pred(_Iterator __it, _Pred __pred)
46536ac495dSmrg     { return _Irreflexive_checker::_S_is_valid_pred(__it, __pred); }
46636ac495dSmrg #endif
46736ac495dSmrg 
46836ac495dSmrg } // namespace __gnu_debug
46936ac495dSmrg 
47036ac495dSmrg #endif
471