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