xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/debug/functions.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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