1*e4b17023SJohn Marino // Debugging support implementation -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 4*e4b17023SJohn Marino // Free Software Foundation, Inc. 5*e4b17023SJohn Marino // 6*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 7*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 8*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 9*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 10*e4b17023SJohn Marino // any later version. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 13*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 14*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*e4b17023SJohn Marino // GNU General Public License for more details. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 18*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 19*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 20*e4b17023SJohn Marino 21*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 22*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 23*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 25*e4b17023SJohn Marino 26*e4b17023SJohn Marino /** @file debug/functions.h 27*e4b17023SJohn Marino * This file is a GNU debug extension to the Standard C++ Library. 28*e4b17023SJohn Marino */ 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H 31*e4b17023SJohn Marino #define _GLIBCXX_DEBUG_FUNCTIONS_H 1 32*e4b17023SJohn Marino 33*e4b17023SJohn Marino #include <bits/c++config.h> 34*e4b17023SJohn Marino #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories 35*e4b17023SJohn Marino #include <bits/cpp_type_traits.h> // for __is_integer 36*e4b17023SJohn Marino #include <debug/formatter.h> 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino namespace __gnu_debug 39*e4b17023SJohn Marino { 40*e4b17023SJohn Marino template<typename _Iterator, typename _Sequence> 41*e4b17023SJohn Marino class _Safe_iterator; 42*e4b17023SJohn Marino 43*e4b17023SJohn Marino // An arbitrary iterator pointer is not singular. 44*e4b17023SJohn Marino inline bool __check_singular_aux(const void *)45*e4b17023SJohn Marino __check_singular_aux(const void*) { return false; } 46*e4b17023SJohn Marino 47*e4b17023SJohn Marino // We may have an iterator that derives from _Safe_iterator_base but isn't 48*e4b17023SJohn Marino // a _Safe_iterator. 49*e4b17023SJohn Marino template<typename _Iterator> 50*e4b17023SJohn Marino inline bool __check_singular(_Iterator & __x)51*e4b17023SJohn Marino __check_singular(_Iterator& __x) 52*e4b17023SJohn Marino { return __check_singular_aux(&__x); } 53*e4b17023SJohn Marino 54*e4b17023SJohn Marino /** Non-NULL pointers are nonsingular. */ 55*e4b17023SJohn Marino template<typename _Tp> 56*e4b17023SJohn Marino inline bool __check_singular(const _Tp * __ptr)57*e4b17023SJohn Marino __check_singular(const _Tp* __ptr) 58*e4b17023SJohn Marino { return __ptr == 0; } 59*e4b17023SJohn Marino 60*e4b17023SJohn Marino /** Safe iterators know if they are singular. */ 61*e4b17023SJohn Marino template<typename _Iterator, typename _Sequence> 62*e4b17023SJohn Marino inline bool __check_singular(const _Safe_iterator<_Iterator,_Sequence> & __x)63*e4b17023SJohn Marino __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) 64*e4b17023SJohn Marino { return __x._M_singular(); } 65*e4b17023SJohn Marino 66*e4b17023SJohn Marino /** Assume that some arbitrary iterator is dereferenceable, because we 67*e4b17023SJohn Marino can't prove that it isn't. */ 68*e4b17023SJohn Marino template<typename _Iterator> 69*e4b17023SJohn Marino inline bool __check_dereferenceable(_Iterator &)70*e4b17023SJohn Marino __check_dereferenceable(_Iterator&) 71*e4b17023SJohn Marino { return true; } 72*e4b17023SJohn Marino 73*e4b17023SJohn Marino /** Non-NULL pointers are dereferenceable. */ 74*e4b17023SJohn Marino template<typename _Tp> 75*e4b17023SJohn Marino inline bool __check_dereferenceable(const _Tp * __ptr)76*e4b17023SJohn Marino __check_dereferenceable(const _Tp* __ptr) 77*e4b17023SJohn Marino { return __ptr; } 78*e4b17023SJohn Marino 79*e4b17023SJohn Marino /** Safe iterators know if they are singular. */ 80*e4b17023SJohn Marino template<typename _Iterator, typename _Sequence> 81*e4b17023SJohn Marino inline bool __check_dereferenceable(const _Safe_iterator<_Iterator,_Sequence> & __x)82*e4b17023SJohn Marino __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) 83*e4b17023SJohn Marino { return __x._M_dereferenceable(); } 84*e4b17023SJohn Marino 85*e4b17023SJohn Marino /** If the distance between two random access iterators is 86*e4b17023SJohn Marino * nonnegative, assume the range is valid. 87*e4b17023SJohn Marino */ 88*e4b17023SJohn Marino template<typename _RandomAccessIterator> 89*e4b17023SJohn Marino inline bool __valid_range_aux2(const _RandomAccessIterator & __first,const _RandomAccessIterator & __last,std::random_access_iterator_tag)90*e4b17023SJohn Marino __valid_range_aux2(const _RandomAccessIterator& __first, 91*e4b17023SJohn Marino const _RandomAccessIterator& __last, 92*e4b17023SJohn Marino std::random_access_iterator_tag) 93*e4b17023SJohn Marino { return __last - __first >= 0; } 94*e4b17023SJohn Marino 95*e4b17023SJohn Marino /** Can't test for a valid range with input iterators, because 96*e4b17023SJohn Marino * iteration may be destructive. So we just assume that the range 97*e4b17023SJohn Marino * is valid. 98*e4b17023SJohn Marino */ 99*e4b17023SJohn Marino template<typename _InputIterator> 100*e4b17023SJohn Marino inline bool __valid_range_aux2(const _InputIterator &,const _InputIterator &,std::input_iterator_tag)101*e4b17023SJohn Marino __valid_range_aux2(const _InputIterator&, const _InputIterator&, 102*e4b17023SJohn Marino std::input_iterator_tag) 103*e4b17023SJohn Marino { return true; } 104*e4b17023SJohn Marino 105*e4b17023SJohn Marino /** We say that integral types for a valid range, and defer to other 106*e4b17023SJohn Marino * routines to realize what to do with integral types instead of 107*e4b17023SJohn Marino * iterators. 108*e4b17023SJohn Marino */ 109*e4b17023SJohn Marino template<typename _Integral> 110*e4b17023SJohn Marino inline bool __valid_range_aux(const _Integral &,const _Integral &,std::__true_type)111*e4b17023SJohn Marino __valid_range_aux(const _Integral&, const _Integral&, std::__true_type) 112*e4b17023SJohn Marino { return true; } 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino /** We have iterators, so figure out what kind of iterators that are 115*e4b17023SJohn Marino * to see if we can check the range ahead of time. 116*e4b17023SJohn Marino */ 117*e4b17023SJohn Marino template<typename _InputIterator> 118*e4b17023SJohn Marino inline bool __valid_range_aux(const _InputIterator & __first,const _InputIterator & __last,std::__false_type)119*e4b17023SJohn Marino __valid_range_aux(const _InputIterator& __first, 120*e4b17023SJohn Marino const _InputIterator& __last, std::__false_type) 121*e4b17023SJohn Marino { 122*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator>::iterator_category 123*e4b17023SJohn Marino _Category; 124*e4b17023SJohn Marino return __valid_range_aux2(__first, __last, _Category()); 125*e4b17023SJohn Marino } 126*e4b17023SJohn Marino 127*e4b17023SJohn Marino /** Don't know what these iterators are, or if they are even 128*e4b17023SJohn Marino * iterators (we may get an integral type for InputIterator), so 129*e4b17023SJohn Marino * see if they are integral and pass them on to the next phase 130*e4b17023SJohn Marino * otherwise. 131*e4b17023SJohn Marino */ 132*e4b17023SJohn Marino template<typename _InputIterator> 133*e4b17023SJohn Marino inline bool __valid_range(const _InputIterator & __first,const _InputIterator & __last)134*e4b17023SJohn Marino __valid_range(const _InputIterator& __first, const _InputIterator& __last) 135*e4b17023SJohn Marino { 136*e4b17023SJohn Marino typedef typename std::__is_integer<_InputIterator>::__type _Integral; 137*e4b17023SJohn Marino return __valid_range_aux(__first, __last, _Integral()); 138*e4b17023SJohn Marino } 139*e4b17023SJohn Marino 140*e4b17023SJohn Marino /** Safe iterators know how to check if they form a valid range. */ 141*e4b17023SJohn Marino template<typename _Iterator, typename _Sequence> 142*e4b17023SJohn Marino inline bool __valid_range(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last)143*e4b17023SJohn Marino __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, 144*e4b17023SJohn Marino const _Safe_iterator<_Iterator, _Sequence>& __last) 145*e4b17023SJohn Marino { return __first._M_valid_range(__last); } 146*e4b17023SJohn Marino 147*e4b17023SJohn Marino /** Safe local iterators know how to check if they form a valid range. */ 148*e4b17023SJohn Marino template<typename _Iterator, typename _Sequence> 149*e4b17023SJohn Marino inline bool __valid_range(const _Safe_local_iterator<_Iterator,_Sequence> & __first,const _Safe_local_iterator<_Iterator,_Sequence> & __last)150*e4b17023SJohn Marino __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, 151*e4b17023SJohn Marino const _Safe_local_iterator<_Iterator, _Sequence>& __last) 152*e4b17023SJohn Marino { return __first._M_valid_range(__last); } 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino /* Checks that [first, last) is a valid range, and then returns 155*e4b17023SJohn Marino * __first. This routine is useful when we can't use a separate 156*e4b17023SJohn Marino * assertion statement because, e.g., we are in a constructor. 157*e4b17023SJohn Marino */ 158*e4b17023SJohn Marino template<typename _InputIterator> 159*e4b17023SJohn Marino inline _InputIterator __check_valid_range(const _InputIterator & __first,const _InputIterator & __last)160*e4b17023SJohn Marino __check_valid_range(const _InputIterator& __first, 161*e4b17023SJohn Marino const _InputIterator& __last 162*e4b17023SJohn Marino __attribute__((__unused__))) 163*e4b17023SJohn Marino { 164*e4b17023SJohn Marino __glibcxx_check_valid_range(__first, __last); 165*e4b17023SJohn Marino return __first; 166*e4b17023SJohn Marino } 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ 169*e4b17023SJohn Marino template<typename _CharT, typename _Integer> 170*e4b17023SJohn Marino inline const _CharT* __check_string(const _CharT * __s,const _Integer & __n)171*e4b17023SJohn Marino __check_string(const _CharT* __s, 172*e4b17023SJohn Marino const _Integer& __n __attribute__((__unused__))) 173*e4b17023SJohn Marino { 174*e4b17023SJohn Marino #ifdef _GLIBCXX_DEBUG_PEDANTIC 175*e4b17023SJohn Marino __glibcxx_assert(__s != 0 || __n == 0); 176*e4b17023SJohn Marino #endif 177*e4b17023SJohn Marino return __s; 178*e4b17023SJohn Marino } 179*e4b17023SJohn Marino 180*e4b17023SJohn Marino /** Checks that __s is non-NULL and then returns __s. */ 181*e4b17023SJohn Marino template<typename _CharT> 182*e4b17023SJohn Marino inline const _CharT* __check_string(const _CharT * __s)183*e4b17023SJohn Marino __check_string(const _CharT* __s) 184*e4b17023SJohn Marino { 185*e4b17023SJohn Marino #ifdef _GLIBCXX_DEBUG_PEDANTIC 186*e4b17023SJohn Marino __glibcxx_assert(__s != 0); 187*e4b17023SJohn Marino #endif 188*e4b17023SJohn Marino return __s; 189*e4b17023SJohn Marino } 190*e4b17023SJohn Marino 191*e4b17023SJohn Marino // Can't check if an input iterator sequence is sorted, because we 192*e4b17023SJohn Marino // can't step through the sequence. 193*e4b17023SJohn Marino template<typename _InputIterator> 194*e4b17023SJohn Marino inline bool __check_sorted_aux(const _InputIterator &,const _InputIterator &,std::input_iterator_tag)195*e4b17023SJohn Marino __check_sorted_aux(const _InputIterator&, const _InputIterator&, 196*e4b17023SJohn Marino std::input_iterator_tag) 197*e4b17023SJohn Marino { return true; } 198*e4b17023SJohn Marino 199*e4b17023SJohn Marino // Can verify if a forward iterator sequence is in fact sorted using 200*e4b17023SJohn Marino // std::__is_sorted 201*e4b17023SJohn Marino template<typename _ForwardIterator> 202*e4b17023SJohn Marino inline bool __check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)203*e4b17023SJohn Marino __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 204*e4b17023SJohn Marino std::forward_iterator_tag) 205*e4b17023SJohn Marino { 206*e4b17023SJohn Marino if (__first == __last) 207*e4b17023SJohn Marino return true; 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino _ForwardIterator __next = __first; 210*e4b17023SJohn Marino for (++__next; __next != __last; __first = __next, ++__next) 211*e4b17023SJohn Marino if (*__next < *__first) 212*e4b17023SJohn Marino return false; 213*e4b17023SJohn Marino 214*e4b17023SJohn Marino return true; 215*e4b17023SJohn Marino } 216*e4b17023SJohn Marino 217*e4b17023SJohn Marino // Can't check if an input iterator sequence is sorted, because we can't step 218*e4b17023SJohn Marino // through the sequence. 219*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 220*e4b17023SJohn Marino inline bool __check_sorted_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::input_iterator_tag)221*e4b17023SJohn Marino __check_sorted_aux(const _InputIterator&, const _InputIterator&, 222*e4b17023SJohn Marino _Predicate, std::input_iterator_tag) 223*e4b17023SJohn Marino { return true; } 224*e4b17023SJohn Marino 225*e4b17023SJohn Marino // Can verify if a forward iterator sequence is in fact sorted using 226*e4b17023SJohn Marino // std::__is_sorted 227*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate> 228*e4b17023SJohn Marino inline bool __check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred,std::forward_iterator_tag)229*e4b17023SJohn Marino __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 230*e4b17023SJohn Marino _Predicate __pred, std::forward_iterator_tag) 231*e4b17023SJohn Marino { 232*e4b17023SJohn Marino if (__first == __last) 233*e4b17023SJohn Marino return true; 234*e4b17023SJohn Marino 235*e4b17023SJohn Marino _ForwardIterator __next = __first; 236*e4b17023SJohn Marino for (++__next; __next != __last; __first = __next, ++__next) 237*e4b17023SJohn Marino if (__pred(*__next, *__first)) 238*e4b17023SJohn Marino return false; 239*e4b17023SJohn Marino 240*e4b17023SJohn Marino return true; 241*e4b17023SJohn Marino } 242*e4b17023SJohn Marino 243*e4b17023SJohn Marino // Determine if a sequence is sorted. 244*e4b17023SJohn Marino template<typename _InputIterator> 245*e4b17023SJohn Marino inline bool __check_sorted(const _InputIterator & __first,const _InputIterator & __last)246*e4b17023SJohn Marino __check_sorted(const _InputIterator& __first, const _InputIterator& __last) 247*e4b17023SJohn Marino { 248*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator>::iterator_category 249*e4b17023SJohn Marino _Category; 250*e4b17023SJohn Marino 251*e4b17023SJohn Marino // Verify that the < operator for elements in the sequence is a 252*e4b17023SJohn Marino // StrictWeakOrdering by checking that it is irreflexive. 253*e4b17023SJohn Marino __glibcxx_assert(__first == __last || !(*__first < *__first)); 254*e4b17023SJohn Marino 255*e4b17023SJohn Marino return __check_sorted_aux(__first, __last, _Category()); 256*e4b17023SJohn Marino } 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 259*e4b17023SJohn Marino inline bool __check_sorted(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred)260*e4b17023SJohn Marino __check_sorted(const _InputIterator& __first, const _InputIterator& __last, 261*e4b17023SJohn Marino _Predicate __pred) 262*e4b17023SJohn Marino { 263*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator>::iterator_category 264*e4b17023SJohn Marino _Category; 265*e4b17023SJohn Marino 266*e4b17023SJohn Marino // Verify that the predicate is StrictWeakOrdering by checking that it 267*e4b17023SJohn Marino // is irreflexive. 268*e4b17023SJohn Marino __glibcxx_assert(__first == __last || !__pred(*__first, *__first)); 269*e4b17023SJohn Marino 270*e4b17023SJohn Marino return __check_sorted_aux(__first, __last, __pred, _Category()); 271*e4b17023SJohn Marino } 272*e4b17023SJohn Marino 273*e4b17023SJohn Marino template<typename _InputIterator> 274*e4b17023SJohn Marino inline bool __check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,std::__true_type)275*e4b17023SJohn Marino __check_sorted_set_aux(const _InputIterator& __first, 276*e4b17023SJohn Marino const _InputIterator& __last, 277*e4b17023SJohn Marino std::__true_type) 278*e4b17023SJohn Marino { return __check_sorted(__first, __last); } 279*e4b17023SJohn Marino 280*e4b17023SJohn Marino template<typename _InputIterator> 281*e4b17023SJohn Marino inline bool __check_sorted_set_aux(const _InputIterator &,const _InputIterator &,std::__false_type)282*e4b17023SJohn Marino __check_sorted_set_aux(const _InputIterator&, 283*e4b17023SJohn Marino const _InputIterator&, 284*e4b17023SJohn Marino std::__false_type) 285*e4b17023SJohn Marino { return true; } 286*e4b17023SJohn Marino 287*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 288*e4b17023SJohn Marino inline bool __check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred,std::__true_type)289*e4b17023SJohn Marino __check_sorted_set_aux(const _InputIterator& __first, 290*e4b17023SJohn Marino const _InputIterator& __last, 291*e4b17023SJohn Marino _Predicate __pred, std::__true_type) 292*e4b17023SJohn Marino { return __check_sorted(__first, __last, __pred); } 293*e4b17023SJohn Marino 294*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 295*e4b17023SJohn Marino inline bool __check_sorted_set_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::__false_type)296*e4b17023SJohn Marino __check_sorted_set_aux(const _InputIterator&, 297*e4b17023SJohn Marino const _InputIterator&, _Predicate, 298*e4b17023SJohn Marino std::__false_type) 299*e4b17023SJohn Marino { return true; } 300*e4b17023SJohn Marino 301*e4b17023SJohn Marino // ... special variant used in std::merge, std::includes, std::set_*. 302*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2> 303*e4b17023SJohn Marino inline bool __check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &)304*e4b17023SJohn Marino __check_sorted_set(const _InputIterator1& __first, 305*e4b17023SJohn Marino const _InputIterator1& __last, 306*e4b17023SJohn Marino const _InputIterator2&) 307*e4b17023SJohn Marino { 308*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator1>::value_type 309*e4b17023SJohn Marino _ValueType1; 310*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator2>::value_type 311*e4b17023SJohn Marino _ValueType2; 312*e4b17023SJohn Marino 313*e4b17023SJohn Marino typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 314*e4b17023SJohn Marino _SameType; 315*e4b17023SJohn Marino return __check_sorted_set_aux(__first, __last, _SameType()); 316*e4b17023SJohn Marino } 317*e4b17023SJohn Marino 318*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 319*e4b17023SJohn Marino typename _Predicate> 320*e4b17023SJohn Marino inline bool __check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &,_Predicate __pred)321*e4b17023SJohn Marino __check_sorted_set(const _InputIterator1& __first, 322*e4b17023SJohn Marino const _InputIterator1& __last, 323*e4b17023SJohn Marino const _InputIterator2&, _Predicate __pred) 324*e4b17023SJohn Marino { 325*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator1>::value_type 326*e4b17023SJohn Marino _ValueType1; 327*e4b17023SJohn Marino typedef typename std::iterator_traits<_InputIterator2>::value_type 328*e4b17023SJohn Marino _ValueType2; 329*e4b17023SJohn Marino 330*e4b17023SJohn Marino typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 331*e4b17023SJohn Marino _SameType; 332*e4b17023SJohn Marino return __check_sorted_set_aux(__first, __last, __pred, _SameType()); 333*e4b17023SJohn Marino } 334*e4b17023SJohn Marino 335*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 336*e4b17023SJohn Marino // 270. Binary search requirements overly strict 337*e4b17023SJohn Marino // Determine if a sequence is partitioned w.r.t. this element. 338*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 339*e4b17023SJohn Marino inline bool __check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)340*e4b17023SJohn Marino __check_partitioned_lower(_ForwardIterator __first, 341*e4b17023SJohn Marino _ForwardIterator __last, const _Tp& __value) 342*e4b17023SJohn Marino { 343*e4b17023SJohn Marino while (__first != __last && *__first < __value) 344*e4b17023SJohn Marino ++__first; 345*e4b17023SJohn Marino while (__first != __last && !(*__first < __value)) 346*e4b17023SJohn Marino ++__first; 347*e4b17023SJohn Marino return __first == __last; 348*e4b17023SJohn Marino } 349*e4b17023SJohn Marino 350*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 351*e4b17023SJohn Marino inline bool __check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)352*e4b17023SJohn Marino __check_partitioned_upper(_ForwardIterator __first, 353*e4b17023SJohn Marino _ForwardIterator __last, const _Tp& __value) 354*e4b17023SJohn Marino { 355*e4b17023SJohn Marino while (__first != __last && !(__value < *__first)) 356*e4b17023SJohn Marino ++__first; 357*e4b17023SJohn Marino while (__first != __last && __value < *__first) 358*e4b17023SJohn Marino ++__first; 359*e4b17023SJohn Marino return __first == __last; 360*e4b17023SJohn Marino } 361*e4b17023SJohn Marino 362*e4b17023SJohn Marino // Determine if a sequence is partitioned w.r.t. this element. 363*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Pred> 364*e4b17023SJohn Marino inline bool __check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)365*e4b17023SJohn Marino __check_partitioned_lower(_ForwardIterator __first, 366*e4b17023SJohn Marino _ForwardIterator __last, const _Tp& __value, 367*e4b17023SJohn Marino _Pred __pred) 368*e4b17023SJohn Marino { 369*e4b17023SJohn Marino while (__first != __last && bool(__pred(*__first, __value))) 370*e4b17023SJohn Marino ++__first; 371*e4b17023SJohn Marino while (__first != __last && !bool(__pred(*__first, __value))) 372*e4b17023SJohn Marino ++__first; 373*e4b17023SJohn Marino return __first == __last; 374*e4b17023SJohn Marino } 375*e4b17023SJohn Marino 376*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Pred> 377*e4b17023SJohn Marino inline bool __check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)378*e4b17023SJohn Marino __check_partitioned_upper(_ForwardIterator __first, 379*e4b17023SJohn Marino _ForwardIterator __last, const _Tp& __value, 380*e4b17023SJohn Marino _Pred __pred) 381*e4b17023SJohn Marino { 382*e4b17023SJohn Marino while (__first != __last && !bool(__pred(__value, *__first))) 383*e4b17023SJohn Marino ++__first; 384*e4b17023SJohn Marino while (__first != __last && bool(__pred(__value, *__first))) 385*e4b17023SJohn Marino ++__first; 386*e4b17023SJohn Marino return __first == __last; 387*e4b17023SJohn Marino } 388*e4b17023SJohn Marino } // namespace __gnu_debug 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino #endif 391