1*38fd1498Szrj // Debugging support implementation -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2003-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file debug/functions.h 26*38fd1498Szrj * This file is a GNU debug extension to the Standard C++ Library. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H 30*38fd1498Szrj #define _GLIBCXX_DEBUG_FUNCTIONS_H 1 31*38fd1498Szrj 32*38fd1498Szrj #include <bits/move.h> // for __addressof 33*38fd1498Szrj #include <bits/stl_function.h> // for less 34*38fd1498Szrj #if __cplusplus >= 201103L 35*38fd1498Szrj # include <type_traits> // for is_lvalue_reference and conditional. 36*38fd1498Szrj #endif 37*38fd1498Szrj 38*38fd1498Szrj #include <debug/helper_functions.h> 39*38fd1498Szrj #include <debug/formatter.h> 40*38fd1498Szrj 41*38fd1498Szrj namespace __gnu_debug 42*38fd1498Szrj { 43*38fd1498Szrj template<typename _Iterator, typename _Sequence> 44*38fd1498Szrj class _Safe_iterator; 45*38fd1498Szrj 46*38fd1498Szrj template<typename _Sequence> 47*38fd1498Szrj struct _Insert_range_from_self_is_safe 48*38fd1498Szrj { enum { __value = 0 }; }; 49*38fd1498Szrj 50*38fd1498Szrj template<typename _Sequence> 51*38fd1498Szrj struct _Is_contiguous_sequence : std::__false_type { }; 52*38fd1498Szrj 53*38fd1498Szrj // An arbitrary iterator pointer is not singular. 54*38fd1498Szrj inline bool __check_singular_aux(const void *)55*38fd1498Szrj __check_singular_aux(const void*) { return false; } 56*38fd1498Szrj 57*38fd1498Szrj // We may have an iterator that derives from _Safe_iterator_base but isn't 58*38fd1498Szrj // a _Safe_iterator. 59*38fd1498Szrj template<typename _Iterator> 60*38fd1498Szrj inline bool __check_singular(const _Iterator & __x)61*38fd1498Szrj __check_singular(const _Iterator& __x) 62*38fd1498Szrj { return __check_singular_aux(std::__addressof(__x)); } 63*38fd1498Szrj 64*38fd1498Szrj /** Non-NULL pointers are nonsingular. */ 65*38fd1498Szrj template<typename _Tp> 66*38fd1498Szrj inline bool __check_singular(const _Tp * __ptr)67*38fd1498Szrj __check_singular(const _Tp* __ptr) 68*38fd1498Szrj { return __ptr == 0; } 69*38fd1498Szrj 70*38fd1498Szrj /** Assume that some arbitrary iterator is dereferenceable, because we 71*38fd1498Szrj can't prove that it isn't. */ 72*38fd1498Szrj template<typename _Iterator> 73*38fd1498Szrj inline bool __check_dereferenceable(const _Iterator &)74*38fd1498Szrj __check_dereferenceable(const _Iterator&) 75*38fd1498Szrj { return true; } 76*38fd1498Szrj 77*38fd1498Szrj /** Non-NULL pointers are dereferenceable. */ 78*38fd1498Szrj template<typename _Tp> 79*38fd1498Szrj inline bool __check_dereferenceable(const _Tp * __ptr)80*38fd1498Szrj __check_dereferenceable(const _Tp* __ptr) 81*38fd1498Szrj { return __ptr; } 82*38fd1498Szrj 83*38fd1498Szrj /* Checks that [first, last) is a valid range, and then returns 84*38fd1498Szrj * __first. This routine is useful when we can't use a separate 85*38fd1498Szrj * assertion statement because, e.g., we are in a constructor. 86*38fd1498Szrj */ 87*38fd1498Szrj template<typename _InputIterator> 88*38fd1498Szrj inline _InputIterator __check_valid_range(const _InputIterator & __first,const _InputIterator & __last)89*38fd1498Szrj __check_valid_range(const _InputIterator& __first, 90*38fd1498Szrj const _InputIterator& __last 91*38fd1498Szrj __attribute__((__unused__))) 92*38fd1498Szrj { 93*38fd1498Szrj __glibcxx_check_valid_range(__first, __last); 94*38fd1498Szrj return __first; 95*38fd1498Szrj } 96*38fd1498Szrj 97*38fd1498Szrj /* Handle the case where __other is a pointer to _Sequence::value_type. */ 98*38fd1498Szrj template<typename _Iterator, typename _Sequence> 99*38fd1498Szrj inline bool __foreign_iterator_aux4(const _Safe_iterator<_Iterator,_Sequence> & __it,const typename _Sequence::value_type * __other)100*38fd1498Szrj __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it, 101*38fd1498Szrj const typename _Sequence::value_type* __other) 102*38fd1498Szrj { 103*38fd1498Szrj typedef const typename _Sequence::value_type* _PointerType; 104*38fd1498Szrj typedef std::less<_PointerType> _Less; 105*38fd1498Szrj #if __cplusplus >= 201103L 106*38fd1498Szrj constexpr _Less __l{}; 107*38fd1498Szrj #else 108*38fd1498Szrj const _Less __l = _Less(); 109*38fd1498Szrj #endif 110*38fd1498Szrj const _Sequence* __seq = __it._M_get_sequence(); 111*38fd1498Szrj const _PointerType __begin = std::__addressof(*__seq->_M_base().begin()); 112*38fd1498Szrj const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1)); 113*38fd1498Szrj 114*38fd1498Szrj // Check whether __other points within the contiguous storage. 115*38fd1498Szrj return __l(__other, __begin) || __l(__end, __other); 116*38fd1498Szrj } 117*38fd1498Szrj 118*38fd1498Szrj /* Fallback overload for when we can't tell, assume it is valid. */ 119*38fd1498Szrj template<typename _Iterator, typename _Sequence> 120*38fd1498Szrj inline bool __foreign_iterator_aux4(const _Safe_iterator<_Iterator,_Sequence> &,...)121*38fd1498Szrj __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&, ...) 122*38fd1498Szrj { return true; } 123*38fd1498Szrj 124*38fd1498Szrj /* Handle sequences with contiguous storage */ 125*38fd1498Szrj template<typename _Iterator, typename _Sequence, typename _InputIterator> 126*38fd1498Szrj inline bool __foreign_iterator_aux3(const _Safe_iterator<_Iterator,_Sequence> & __it,const _InputIterator & __other,const _InputIterator & __other_end,std::__true_type)127*38fd1498Szrj __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, 128*38fd1498Szrj const _InputIterator& __other, 129*38fd1498Szrj const _InputIterator& __other_end, 130*38fd1498Szrj std::__true_type) 131*38fd1498Szrj { 132*38fd1498Szrj if (__other == __other_end) 133*38fd1498Szrj return true; // inserting nothing is safe even if not foreign iters 134*38fd1498Szrj if (__it._M_get_sequence()->begin() == __it._M_get_sequence()->end()) 135*38fd1498Szrj return true; // can't be self-inserting if self is empty 136*38fd1498Szrj return __foreign_iterator_aux4(__it, std::__addressof(*__other)); 137*38fd1498Szrj } 138*38fd1498Szrj 139*38fd1498Szrj /* Handle non-contiguous containers, assume it is valid. */ 140*38fd1498Szrj template<typename _Iterator, typename _Sequence, typename _InputIterator> 141*38fd1498Szrj inline bool __foreign_iterator_aux3(const _Safe_iterator<_Iterator,_Sequence> &,const _InputIterator &,const _InputIterator &,std::__false_type)142*38fd1498Szrj __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>&, 143*38fd1498Szrj const _InputIterator&, const _InputIterator&, 144*38fd1498Szrj std::__false_type) 145*38fd1498Szrj { return true; } 146*38fd1498Szrj 147*38fd1498Szrj /** Handle debug iterators from the same type of container. */ 148*38fd1498Szrj template<typename _Iterator, typename _Sequence, typename _OtherIterator> 149*38fd1498Szrj inline bool __foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence> & __it,const _Safe_iterator<_OtherIterator,_Sequence> & __other,const _Safe_iterator<_OtherIterator,_Sequence> &)150*38fd1498Szrj __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, 151*38fd1498Szrj const _Safe_iterator<_OtherIterator, _Sequence>& __other, 152*38fd1498Szrj const _Safe_iterator<_OtherIterator, _Sequence>&) 153*38fd1498Szrj { return __it._M_get_sequence() != __other._M_get_sequence(); } 154*38fd1498Szrj 155*38fd1498Szrj /** Handle debug iterators from different types of container. */ 156*38fd1498Szrj template<typename _Iterator, typename _Sequence, typename _OtherIterator, 157*38fd1498Szrj typename _OtherSequence> 158*38fd1498Szrj inline bool __foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence> & __it,const _Safe_iterator<_OtherIterator,_OtherSequence> &,const _Safe_iterator<_OtherIterator,_OtherSequence> &)159*38fd1498Szrj __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, 160*38fd1498Szrj const _Safe_iterator<_OtherIterator, _OtherSequence>&, 161*38fd1498Szrj const _Safe_iterator<_OtherIterator, _OtherSequence>&) 162*38fd1498Szrj { return true; } 163*38fd1498Szrj 164*38fd1498Szrj /* Handle non-debug iterators. */ 165*38fd1498Szrj template<typename _Iterator, typename _Sequence, typename _InputIterator> 166*38fd1498Szrj inline bool __foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence> & __it,const _InputIterator & __other,const _InputIterator & __other_end)167*38fd1498Szrj __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, 168*38fd1498Szrj const _InputIterator& __other, 169*38fd1498Szrj const _InputIterator& __other_end) 170*38fd1498Szrj { 171*38fd1498Szrj #if __cplusplus < 201103L 172*38fd1498Szrj typedef _Is_contiguous_sequence<_Sequence> __tag; 173*38fd1498Szrj #else 174*38fd1498Szrj using __lvalref = std::is_lvalue_reference< 175*38fd1498Szrj typename std::iterator_traits<_InputIterator>::reference>; 176*38fd1498Szrj using __contiguous = _Is_contiguous_sequence<_Sequence>; 177*38fd1498Szrj using __tag = typename std::conditional<__lvalref::value, __contiguous, 178*38fd1498Szrj std::__false_type>::type; 179*38fd1498Szrj #endif 180*38fd1498Szrj return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); 181*38fd1498Szrj } 182*38fd1498Szrj 183*38fd1498Szrj /* Handle the case where we aren't really inserting a range after all */ 184*38fd1498Szrj template<typename _Iterator, typename _Sequence, typename _Integral> 185*38fd1498Szrj inline bool __foreign_iterator_aux(const _Safe_iterator<_Iterator,_Sequence> &,_Integral,_Integral,std::__true_type)186*38fd1498Szrj __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>&, 187*38fd1498Szrj _Integral, _Integral, 188*38fd1498Szrj std::__true_type) 189*38fd1498Szrj { return true; } 190*38fd1498Szrj 191*38fd1498Szrj /* Handle all iterators. */ 192*38fd1498Szrj template<typename _Iterator, typename _Sequence, 193*38fd1498Szrj typename _InputIterator> 194*38fd1498Szrj inline bool __foreign_iterator_aux(const _Safe_iterator<_Iterator,_Sequence> & __it,_InputIterator __other,_InputIterator __other_end,std::__false_type)195*38fd1498Szrj __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, 196*38fd1498Szrj _InputIterator __other, _InputIterator __other_end, 197*38fd1498Szrj std::__false_type) 198*38fd1498Szrj { 199*38fd1498Szrj return _Insert_range_from_self_is_safe<_Sequence>::__value 200*38fd1498Szrj || __foreign_iterator_aux2(__it, std::__miter_base(__other), 201*38fd1498Szrj std::__miter_base(__other_end)); 202*38fd1498Szrj } 203*38fd1498Szrj 204*38fd1498Szrj template<typename _Iterator, typename _Sequence, 205*38fd1498Szrj typename _InputIterator> 206*38fd1498Szrj inline bool __foreign_iterator(const _Safe_iterator<_Iterator,_Sequence> & __it,_InputIterator __other,_InputIterator __other_end)207*38fd1498Szrj __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it, 208*38fd1498Szrj _InputIterator __other, _InputIterator __other_end) 209*38fd1498Szrj { 210*38fd1498Szrj typedef typename std::__is_integer<_InputIterator>::__type _Integral; 211*38fd1498Szrj return __foreign_iterator_aux(__it, __other, __other_end, _Integral()); 212*38fd1498Szrj } 213*38fd1498Szrj 214*38fd1498Szrj /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ 215*38fd1498Szrj template<typename _CharT, typename _Integer> 216*38fd1498Szrj inline const _CharT* __check_string(const _CharT * __s,const _Integer & __n)217*38fd1498Szrj __check_string(const _CharT* __s, 218*38fd1498Szrj const _Integer& __n __attribute__((__unused__))) 219*38fd1498Szrj { 220*38fd1498Szrj #ifdef _GLIBCXX_DEBUG_PEDANTIC 221*38fd1498Szrj __glibcxx_assert(__s != 0 || __n == 0); 222*38fd1498Szrj #endif 223*38fd1498Szrj return __s; 224*38fd1498Szrj } 225*38fd1498Szrj 226*38fd1498Szrj /** Checks that __s is non-NULL and then returns __s. */ 227*38fd1498Szrj template<typename _CharT> 228*38fd1498Szrj inline const _CharT* __check_string(const _CharT * __s)229*38fd1498Szrj __check_string(const _CharT* __s) 230*38fd1498Szrj { 231*38fd1498Szrj #ifdef _GLIBCXX_DEBUG_PEDANTIC 232*38fd1498Szrj __glibcxx_assert(__s != 0); 233*38fd1498Szrj #endif 234*38fd1498Szrj return __s; 235*38fd1498Szrj } 236*38fd1498Szrj 237*38fd1498Szrj // Can't check if an input iterator sequence is sorted, because we 238*38fd1498Szrj // can't step through the sequence. 239*38fd1498Szrj template<typename _InputIterator> 240*38fd1498Szrj inline bool __check_sorted_aux(const _InputIterator &,const _InputIterator &,std::input_iterator_tag)241*38fd1498Szrj __check_sorted_aux(const _InputIterator&, const _InputIterator&, 242*38fd1498Szrj std::input_iterator_tag) 243*38fd1498Szrj { return true; } 244*38fd1498Szrj 245*38fd1498Szrj // Can verify if a forward iterator sequence is in fact sorted using 246*38fd1498Szrj // std::__is_sorted 247*38fd1498Szrj template<typename _ForwardIterator> 248*38fd1498Szrj inline bool __check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)249*38fd1498Szrj __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 250*38fd1498Szrj std::forward_iterator_tag) 251*38fd1498Szrj { 252*38fd1498Szrj if (__first == __last) 253*38fd1498Szrj return true; 254*38fd1498Szrj 255*38fd1498Szrj _ForwardIterator __next = __first; 256*38fd1498Szrj for (++__next; __next != __last; __first = __next, (void)++__next) 257*38fd1498Szrj if (*__next < *__first) 258*38fd1498Szrj return false; 259*38fd1498Szrj 260*38fd1498Szrj return true; 261*38fd1498Szrj } 262*38fd1498Szrj 263*38fd1498Szrj // Can't check if an input iterator sequence is sorted, because we can't step 264*38fd1498Szrj // through the sequence. 265*38fd1498Szrj template<typename _InputIterator, typename _Predicate> 266*38fd1498Szrj inline bool __check_sorted_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::input_iterator_tag)267*38fd1498Szrj __check_sorted_aux(const _InputIterator&, const _InputIterator&, 268*38fd1498Szrj _Predicate, std::input_iterator_tag) 269*38fd1498Szrj { return true; } 270*38fd1498Szrj 271*38fd1498Szrj // Can verify if a forward iterator sequence is in fact sorted using 272*38fd1498Szrj // std::__is_sorted 273*38fd1498Szrj template<typename _ForwardIterator, typename _Predicate> 274*38fd1498Szrj inline bool __check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred,std::forward_iterator_tag)275*38fd1498Szrj __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 276*38fd1498Szrj _Predicate __pred, std::forward_iterator_tag) 277*38fd1498Szrj { 278*38fd1498Szrj if (__first == __last) 279*38fd1498Szrj return true; 280*38fd1498Szrj 281*38fd1498Szrj _ForwardIterator __next = __first; 282*38fd1498Szrj for (++__next; __next != __last; __first = __next, (void)++__next) 283*38fd1498Szrj if (__pred(*__next, *__first)) 284*38fd1498Szrj return false; 285*38fd1498Szrj 286*38fd1498Szrj return true; 287*38fd1498Szrj } 288*38fd1498Szrj 289*38fd1498Szrj // Determine if a sequence is sorted. 290*38fd1498Szrj template<typename _InputIterator> 291*38fd1498Szrj inline bool __check_sorted(const _InputIterator & __first,const _InputIterator & __last)292*38fd1498Szrj __check_sorted(const _InputIterator& __first, const _InputIterator& __last) 293*38fd1498Szrj { 294*38fd1498Szrj // Verify that the < operator for elements in the sequence is a 295*38fd1498Szrj // StrictWeakOrdering by checking that it is irreflexive. 296*38fd1498Szrj __glibcxx_assert(__first == __last || !(*__first < *__first)); 297*38fd1498Szrj 298*38fd1498Szrj return __check_sorted_aux(__first, __last, 299*38fd1498Szrj std::__iterator_category(__first)); 300*38fd1498Szrj } 301*38fd1498Szrj 302*38fd1498Szrj template<typename _InputIterator, typename _Predicate> 303*38fd1498Szrj inline bool __check_sorted(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred)304*38fd1498Szrj __check_sorted(const _InputIterator& __first, const _InputIterator& __last, 305*38fd1498Szrj _Predicate __pred) 306*38fd1498Szrj { 307*38fd1498Szrj // Verify that the predicate is StrictWeakOrdering by checking that it 308*38fd1498Szrj // is irreflexive. 309*38fd1498Szrj __glibcxx_assert(__first == __last || !__pred(*__first, *__first)); 310*38fd1498Szrj 311*38fd1498Szrj return __check_sorted_aux(__first, __last, __pred, 312*38fd1498Szrj std::__iterator_category(__first)); 313*38fd1498Szrj } 314*38fd1498Szrj 315*38fd1498Szrj template<typename _InputIterator> 316*38fd1498Szrj inline bool __check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,std::__true_type)317*38fd1498Szrj __check_sorted_set_aux(const _InputIterator& __first, 318*38fd1498Szrj const _InputIterator& __last, 319*38fd1498Szrj std::__true_type) 320*38fd1498Szrj { return __check_sorted(__first, __last); } 321*38fd1498Szrj 322*38fd1498Szrj template<typename _InputIterator> 323*38fd1498Szrj inline bool __check_sorted_set_aux(const _InputIterator &,const _InputIterator &,std::__false_type)324*38fd1498Szrj __check_sorted_set_aux(const _InputIterator&, 325*38fd1498Szrj const _InputIterator&, 326*38fd1498Szrj std::__false_type) 327*38fd1498Szrj { return true; } 328*38fd1498Szrj 329*38fd1498Szrj template<typename _InputIterator, typename _Predicate> 330*38fd1498Szrj inline bool __check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred,std::__true_type)331*38fd1498Szrj __check_sorted_set_aux(const _InputIterator& __first, 332*38fd1498Szrj const _InputIterator& __last, 333*38fd1498Szrj _Predicate __pred, std::__true_type) 334*38fd1498Szrj { return __check_sorted(__first, __last, __pred); } 335*38fd1498Szrj 336*38fd1498Szrj template<typename _InputIterator, typename _Predicate> 337*38fd1498Szrj inline bool __check_sorted_set_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::__false_type)338*38fd1498Szrj __check_sorted_set_aux(const _InputIterator&, 339*38fd1498Szrj const _InputIterator&, _Predicate, 340*38fd1498Szrj std::__false_type) 341*38fd1498Szrj { return true; } 342*38fd1498Szrj 343*38fd1498Szrj // ... special variant used in std::merge, std::includes, std::set_*. 344*38fd1498Szrj template<typename _InputIterator1, typename _InputIterator2> 345*38fd1498Szrj inline bool __check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &)346*38fd1498Szrj __check_sorted_set(const _InputIterator1& __first, 347*38fd1498Szrj const _InputIterator1& __last, 348*38fd1498Szrj const _InputIterator2&) 349*38fd1498Szrj { 350*38fd1498Szrj typedef typename std::iterator_traits<_InputIterator1>::value_type 351*38fd1498Szrj _ValueType1; 352*38fd1498Szrj typedef typename std::iterator_traits<_InputIterator2>::value_type 353*38fd1498Szrj _ValueType2; 354*38fd1498Szrj 355*38fd1498Szrj typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 356*38fd1498Szrj _SameType; 357*38fd1498Szrj return __check_sorted_set_aux(__first, __last, _SameType()); 358*38fd1498Szrj } 359*38fd1498Szrj 360*38fd1498Szrj template<typename _InputIterator1, typename _InputIterator2, 361*38fd1498Szrj typename _Predicate> 362*38fd1498Szrj inline bool __check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &,_Predicate __pred)363*38fd1498Szrj __check_sorted_set(const _InputIterator1& __first, 364*38fd1498Szrj const _InputIterator1& __last, 365*38fd1498Szrj const _InputIterator2&, _Predicate __pred) 366*38fd1498Szrj { 367*38fd1498Szrj typedef typename std::iterator_traits<_InputIterator1>::value_type 368*38fd1498Szrj _ValueType1; 369*38fd1498Szrj typedef typename std::iterator_traits<_InputIterator2>::value_type 370*38fd1498Szrj _ValueType2; 371*38fd1498Szrj 372*38fd1498Szrj typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 373*38fd1498Szrj _SameType; 374*38fd1498Szrj return __check_sorted_set_aux(__first, __last, __pred, _SameType()); 375*38fd1498Szrj } 376*38fd1498Szrj 377*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 378*38fd1498Szrj // 270. Binary search requirements overly strict 379*38fd1498Szrj // Determine if a sequence is partitioned w.r.t. this element. 380*38fd1498Szrj template<typename _ForwardIterator, typename _Tp> 381*38fd1498Szrj inline bool __check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)382*38fd1498Szrj __check_partitioned_lower(_ForwardIterator __first, 383*38fd1498Szrj _ForwardIterator __last, const _Tp& __value) 384*38fd1498Szrj { 385*38fd1498Szrj while (__first != __last && *__first < __value) 386*38fd1498Szrj ++__first; 387*38fd1498Szrj if (__first != __last) 388*38fd1498Szrj { 389*38fd1498Szrj ++__first; 390*38fd1498Szrj while (__first != __last && !(*__first < __value)) 391*38fd1498Szrj ++__first; 392*38fd1498Szrj } 393*38fd1498Szrj return __first == __last; 394*38fd1498Szrj } 395*38fd1498Szrj 396*38fd1498Szrj template<typename _ForwardIterator, typename _Tp> 397*38fd1498Szrj inline bool __check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)398*38fd1498Szrj __check_partitioned_upper(_ForwardIterator __first, 399*38fd1498Szrj _ForwardIterator __last, const _Tp& __value) 400*38fd1498Szrj { 401*38fd1498Szrj while (__first != __last && !(__value < *__first)) 402*38fd1498Szrj ++__first; 403*38fd1498Szrj if (__first != __last) 404*38fd1498Szrj { 405*38fd1498Szrj ++__first; 406*38fd1498Szrj while (__first != __last && __value < *__first) 407*38fd1498Szrj ++__first; 408*38fd1498Szrj } 409*38fd1498Szrj return __first == __last; 410*38fd1498Szrj } 411*38fd1498Szrj 412*38fd1498Szrj // Determine if a sequence is partitioned w.r.t. this element. 413*38fd1498Szrj template<typename _ForwardIterator, typename _Tp, typename _Pred> 414*38fd1498Szrj inline bool __check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)415*38fd1498Szrj __check_partitioned_lower(_ForwardIterator __first, 416*38fd1498Szrj _ForwardIterator __last, const _Tp& __value, 417*38fd1498Szrj _Pred __pred) 418*38fd1498Szrj { 419*38fd1498Szrj while (__first != __last && bool(__pred(*__first, __value))) 420*38fd1498Szrj ++__first; 421*38fd1498Szrj if (__first != __last) 422*38fd1498Szrj { 423*38fd1498Szrj ++__first; 424*38fd1498Szrj while (__first != __last && !bool(__pred(*__first, __value))) 425*38fd1498Szrj ++__first; 426*38fd1498Szrj } 427*38fd1498Szrj return __first == __last; 428*38fd1498Szrj } 429*38fd1498Szrj 430*38fd1498Szrj template<typename _ForwardIterator, typename _Tp, typename _Pred> 431*38fd1498Szrj inline bool __check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)432*38fd1498Szrj __check_partitioned_upper(_ForwardIterator __first, 433*38fd1498Szrj _ForwardIterator __last, const _Tp& __value, 434*38fd1498Szrj _Pred __pred) 435*38fd1498Szrj { 436*38fd1498Szrj while (__first != __last && !bool(__pred(__value, *__first))) 437*38fd1498Szrj ++__first; 438*38fd1498Szrj if (__first != __last) 439*38fd1498Szrj { 440*38fd1498Szrj ++__first; 441*38fd1498Szrj while (__first != __last && bool(__pred(__value, *__first))) 442*38fd1498Szrj ++__first; 443*38fd1498Szrj } 444*38fd1498Szrj return __first == __last; 445*38fd1498Szrj } 446*38fd1498Szrj 447*38fd1498Szrj #if __cplusplus >= 201103L 448*38fd1498Szrj struct _Irreflexive_checker 449*38fd1498Szrj { 450*38fd1498Szrj template<typename _It> 451*38fd1498Szrj static typename std::iterator_traits<_It>::reference 452*38fd1498Szrj __deref(); 453*38fd1498Szrj 454*38fd1498Szrj template<typename _It, 455*38fd1498Szrj typename = decltype(__deref<_It>() < __deref<_It>())> 456*38fd1498Szrj static bool _S_is_valid_Irreflexive_checker457*38fd1498Szrj _S_is_valid(_It __it) 458*38fd1498Szrj { return !(*__it < *__it); } 459*38fd1498Szrj 460*38fd1498Szrj // Fallback method if operator doesn't exist. 461*38fd1498Szrj template<typename... _Args> 462*38fd1498Szrj static bool _S_is_valid_Irreflexive_checker463*38fd1498Szrj _S_is_valid(_Args...) 464*38fd1498Szrj { return true; } 465*38fd1498Szrj 466*38fd1498Szrj template<typename _It, typename _Pred, typename 467*38fd1498Szrj = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))> 468*38fd1498Szrj static bool _S_is_valid_pred_Irreflexive_checker469*38fd1498Szrj _S_is_valid_pred(_It __it, _Pred __pred) 470*38fd1498Szrj { return !__pred(*__it, *__it); } 471*38fd1498Szrj 472*38fd1498Szrj // Fallback method if predicate can't be invoked. 473*38fd1498Szrj template<typename... _Args> 474*38fd1498Szrj static bool _S_is_valid_pred_Irreflexive_checker475*38fd1498Szrj _S_is_valid_pred(_Args...) 476*38fd1498Szrj { return true; } 477*38fd1498Szrj }; 478*38fd1498Szrj 479*38fd1498Szrj template<typename _Iterator> 480*38fd1498Szrj inline bool __is_irreflexive(_Iterator __it)481*38fd1498Szrj __is_irreflexive(_Iterator __it) 482*38fd1498Szrj { return _Irreflexive_checker::_S_is_valid(__it); } 483*38fd1498Szrj 484*38fd1498Szrj template<typename _Iterator, typename _Pred> 485*38fd1498Szrj inline bool __is_irreflexive_pred(_Iterator __it,_Pred __pred)486*38fd1498Szrj __is_irreflexive_pred(_Iterator __it, _Pred __pred) 487*38fd1498Szrj { return _Irreflexive_checker::_S_is_valid_pred(__it, __pred); } 488*38fd1498Szrj #endif 489*38fd1498Szrj 490*38fd1498Szrj } // namespace __gnu_debug 491*38fd1498Szrj 492*38fd1498Szrj #endif 493