STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
functions.h
Go to the documentation of this file.
1 // Debugging support implementation -*- C++ -*-
2 
3 // Copyright (C) 2003-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
29 #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
30 #define _GLIBCXX_DEBUG_FUNCTIONS_H 1
31 
32 #include <bits/c++config.h>
33 #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and
34  // _Iter_base
35 #include <bits/cpp_type_traits.h> // for __is_integer
36 #include <debug/formatter.h>
37 
38 namespace __gnu_debug
39 {
40  template<typename _Iterator, typename _Sequence>
41  class _Safe_iterator;
42 
43  // An arbitrary iterator pointer is not singular.
44  inline bool
45  __check_singular_aux(const void*) { return false; }
46 
47  // We may have an iterator that derives from _Safe_iterator_base but isn't
48  // a _Safe_iterator.
49  template<typename _Iterator>
50  inline bool
51  __check_singular(_Iterator& __x)
52  { return __check_singular_aux(&__x); }
53 
55  template<typename _Tp>
56  inline bool
57  __check_singular(const _Tp* __ptr)
58  { return __ptr == 0; }
59 
61  template<typename _Iterator, typename _Sequence>
62  inline bool
64  { return __x._M_singular(); }
65 
68  template<typename _Iterator>
69  inline bool
71  { return true; }
72 
74  template<typename _Tp>
75  inline bool
76  __check_dereferenceable(const _Tp* __ptr)
77  { return __ptr; }
78 
80  template<typename _Iterator, typename _Sequence>
81  inline bool
83  { return __x._M_dereferenceable(); }
84 
88  template<typename _RandomAccessIterator>
89  inline bool
90  __valid_range_aux2(const _RandomAccessIterator& __first,
91  const _RandomAccessIterator& __last,
92  std::random_access_iterator_tag)
93  { return __last - __first >= 0; }
94 
99  template<typename _InputIterator>
100  inline bool
101  __valid_range_aux2(const _InputIterator&, const _InputIterator&,
102  std::input_iterator_tag)
103  { return true; }
104 
109  template<typename _Integral>
110  inline bool
111  __valid_range_aux(const _Integral&, const _Integral&, std::__true_type)
112  { return true; }
113 
117  template<typename _InputIterator>
118  inline bool
119  __valid_range_aux(const _InputIterator& __first,
120  const _InputIterator& __last, std::__false_type)
121  { return __valid_range_aux2(__first, __last,
122  std::__iterator_category(__first)); }
123 
129  template<typename _InputIterator>
130  inline bool
131  __valid_range(const _InputIterator& __first, const _InputIterator& __last)
132  {
133  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
134  return __valid_range_aux(__first, __last, _Integral());
135  }
136 
138  template<typename _Iterator, typename _Sequence>
139  inline bool
142  { return __first._M_valid_range(__last); }
143 
145  template<typename _Iterator, typename _Sequence>
146  inline bool
149  { return __first._M_valid_range(__last); }
150 
151  /* Checks that [first, last) is a valid range, and then returns
152  * __first. This routine is useful when we can't use a separate
153  * assertion statement because, e.g., we are in a constructor.
154  */
155  template<typename _InputIterator>
156  inline _InputIterator
157  __check_valid_range(const _InputIterator& __first,
158  const _InputIterator& __last
159  __attribute__((__unused__)))
160  {
161  __glibcxx_check_valid_range(__first, __last);
162  return __first;
163  }
164 
166  template<typename _CharT, typename _Integer>
167  inline const _CharT*
168  __check_string(const _CharT* __s,
169  const _Integer& __n __attribute__((__unused__)))
170  {
171 #ifdef _GLIBCXX_DEBUG_PEDANTIC
172  __glibcxx_assert(__s != 0 || __n == 0);
173 #endif
174  return __s;
175  }
176 
178  template<typename _CharT>
179  inline const _CharT*
180  __check_string(const _CharT* __s)
181  {
182 #ifdef _GLIBCXX_DEBUG_PEDANTIC
183  __glibcxx_assert(__s != 0);
184 #endif
185  return __s;
186  }
187 
188  // Can't check if an input iterator sequence is sorted, because we
189  // can't step through the sequence.
190  template<typename _InputIterator>
191  inline bool
192  __check_sorted_aux(const _InputIterator&, const _InputIterator&,
193  std::input_iterator_tag)
194  { return true; }
195 
196  // Can verify if a forward iterator sequence is in fact sorted using
197  // std::__is_sorted
198  template<typename _ForwardIterator>
199  inline bool
200  __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
201  std::forward_iterator_tag)
202  {
203  if (__first == __last)
204  return true;
205 
206  _ForwardIterator __next = __first;
207  for (++__next; __next != __last; __first = __next, ++__next)
208  if (*__next < *__first)
209  return false;
210 
211  return true;
212  }
213 
214  // For performance reason, as the iterator range has been validated, check on
215  // random access safe iterators is done using the base iterator.
216  template<typename _Iterator, typename _Sequence>
217  inline bool
220  std::random_access_iterator_tag __tag)
221  { return __check_sorted_aux(__first.base(), __last.base(), __tag); }
222 
223  // Can't check if an input iterator sequence is sorted, because we can't step
224  // through the sequence.
225  template<typename _InputIterator, typename _Predicate>
226  inline bool
227  __check_sorted_aux(const _InputIterator&, const _InputIterator&,
228  _Predicate, std::input_iterator_tag)
229  { return true; }
230 
231  // Can verify if a forward iterator sequence is in fact sorted using
232  // std::__is_sorted
233  template<typename _ForwardIterator, typename _Predicate>
234  inline bool
235  __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
236  _Predicate __pred, std::forward_iterator_tag)
237  {
238  if (__first == __last)
239  return true;
240 
241  _ForwardIterator __next = __first;
242  for (++__next; __next != __last; __first = __next, ++__next)
243  if (__pred(*__next, *__first))
244  return false;
245 
246  return true;
247  }
248 
249  // For performance reason, as the iterator range has been validated, check on
250  // random access safe iterators is done using the base iterator.
251  template<typename _Iterator, typename _Sequence,
252  typename _Predicate>
253  inline bool
256  _Predicate __pred,
257  std::random_access_iterator_tag __tag)
258  { return __check_sorted_aux(__first.base(), __last.base(), __pred, __tag); }
259 
260  // Determine if a sequence is sorted.
261  template<typename _InputIterator>
262  inline bool
263  __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
264  {
265  // Verify that the < operator for elements in the sequence is a
266  // StrictWeakOrdering by checking that it is irreflexive.
267  __glibcxx_assert(__first == __last || !(*__first < *__first));
268 
269  return __check_sorted_aux(__first, __last,
270  std::__iterator_category(__first));
271  }
272 
273  template<typename _InputIterator, typename _Predicate>
274  inline bool
275  __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
276  _Predicate __pred)
277  {
278  // Verify that the predicate is StrictWeakOrdering by checking that it
279  // is irreflexive.
280  __glibcxx_assert(__first == __last || !__pred(*__first, *__first));
281 
282  return __check_sorted_aux(__first, __last, __pred,
283  std::__iterator_category(__first));
284  }
285 
286  template<typename _InputIterator>
287  inline bool
288  __check_sorted_set_aux(const _InputIterator& __first,
289  const _InputIterator& __last,
290  std::__true_type)
291  { return __check_sorted(__first, __last); }
292 
293  template<typename _InputIterator>
294  inline bool
295  __check_sorted_set_aux(const _InputIterator&,
296  const _InputIterator&,
297  std::__false_type)
298  { return true; }
299 
300  template<typename _InputIterator, typename _Predicate>
301  inline bool
302  __check_sorted_set_aux(const _InputIterator& __first,
303  const _InputIterator& __last,
304  _Predicate __pred, std::__true_type)
305  { return __check_sorted(__first, __last, __pred); }
306 
307  template<typename _InputIterator, typename _Predicate>
308  inline bool
309  __check_sorted_set_aux(const _InputIterator&,
310  const _InputIterator&, _Predicate,
311  std::__false_type)
312  { return true; }
313 
314  // ... special variant used in std::merge, std::includes, std::set_*.
315  template<typename _InputIterator1, typename _InputIterator2>
316  inline bool
317  __check_sorted_set(const _InputIterator1& __first,
318  const _InputIterator1& __last,
319  const _InputIterator2&)
320  {
321  typedef typename std::iterator_traits<_InputIterator1>::value_type
322  _ValueType1;
323  typedef typename std::iterator_traits<_InputIterator2>::value_type
324  _ValueType2;
325 
326  typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
327  _SameType;
328  return __check_sorted_set_aux(__first, __last, _SameType());
329  }
330 
331  template<typename _InputIterator1, typename _InputIterator2,
332  typename _Predicate>
333  inline bool
334  __check_sorted_set(const _InputIterator1& __first,
335  const _InputIterator1& __last,
336  const _InputIterator2&, _Predicate __pred)
337  {
338  typedef typename std::iterator_traits<_InputIterator1>::value_type
339  _ValueType1;
340  typedef typename std::iterator_traits<_InputIterator2>::value_type
341  _ValueType2;
342 
343  typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
344  _SameType;
345  return __check_sorted_set_aux(__first, __last, __pred, _SameType());
346  }
347 
348  // _GLIBCXX_RESOLVE_LIB_DEFECTS
349  // 270. Binary search requirements overly strict
350  // Determine if a sequence is partitioned w.r.t. this element.
351  template<typename _ForwardIterator, typename _Tp>
352  inline bool
353  __check_partitioned_lower(_ForwardIterator __first,
354  _ForwardIterator __last, const _Tp& __value)
355  {
356  while (__first != __last && *__first < __value)
357  ++__first;
358  if (__first != __last)
359  {
360  ++__first;
361  while (__first != __last && !(*__first < __value))
362  ++__first;
363  }
364  return __first == __last;
365  }
366 
367  template<typename _ForwardIterator, typename _Tp>
368  inline bool
369  __check_partitioned_upper(_ForwardIterator __first,
370  _ForwardIterator __last, const _Tp& __value)
371  {
372  while (__first != __last && !(__value < *__first))
373  ++__first;
374  if (__first != __last)
375  {
376  ++__first;
377  while (__first != __last && __value < *__first)
378  ++__first;
379  }
380  return __first == __last;
381  }
382 
383  // Determine if a sequence is partitioned w.r.t. this element.
384  template<typename _ForwardIterator, typename _Tp, typename _Pred>
385  inline bool
386  __check_partitioned_lower(_ForwardIterator __first,
387  _ForwardIterator __last, const _Tp& __value,
388  _Pred __pred)
389  {
390  while (__first != __last && bool(__pred(*__first, __value)))
391  ++__first;
392  if (__first != __last)
393  {
394  ++__first;
395  while (__first != __last && !bool(__pred(*__first, __value)))
396  ++__first;
397  }
398  return __first == __last;
399  }
400 
401  template<typename _ForwardIterator, typename _Tp, typename _Pred>
402  inline bool
403  __check_partitioned_upper(_ForwardIterator __first,
404  _ForwardIterator __last, const _Tp& __value,
405  _Pred __pred)
406  {
407  while (__first != __last && !bool(__pred(__value, *__first)))
408  ++__first;
409  if (__first != __last)
410  {
411  ++__first;
412  while (__first != __last && bool(__pred(__value, *__first)))
413  ++__first;
414  }
415  return __first == __last;
416  }
417 
418  // Helper struct to detect random access safe iterators.
419  template<typename _Iterator>
421  {
422  enum { __value = 0 };
423  typedef std::__false_type __type;
424  };
425 
426  template<typename _Iterator, typename _Sequence>
427  struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
428  : std::__are_same<std::random_access_iterator_tag,
429  typename std::iterator_traits<_Iterator>::
430  iterator_category>
431  { };
432 
433  template<typename _Iterator>
434  struct _Siter_base
435  : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value>
436  { };
437 
444  template<typename _Iterator>
446  __base(_Iterator __it)
447  { return _Siter_base<_Iterator>::_S_base(__it); }
448 } // namespace __gnu_debug
449 
450 #endif
bool __check_singular(_Iterator &)
Definition: functions.h:51
bool __check_sorted(const _InputIterator &__first, const _InputIterator &__last)
Definition: functions.h:263
bool __valid_range_aux(const _Integral &, const _Integral &, std::__true_type)
Definition: functions.h:111
bool __check_sorted_aux(const _InputIterator &, const _InputIterator &, std::input_iterator_tag)
Definition: functions.h:192
const _CharT * __check_string(const _CharT *__s, const _Integer &__n __attribute__((__unused__)))
Definition: functions.h:168
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
Definition: functions.h:446
bool __check_dereferenceable(_Iterator &)
Definition: functions.h:70
bool __check_partitioned_upper(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
Definition: functions.h:369
double __v4df __attribute__((__vector_size__(32)))
Definition: avxintrin.h:32
bool __check_partitioned_lower(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
Definition: functions.h:353
bool __valid_range_aux2(const _RandomAccessIterator &__first, const _RandomAccessIterator &__last, std::random_access_iterator_tag)
Definition: functions.h:90
bool _M_dereferenceable() const
Is the iterator dereferenceable?
Definition: safe_iterator.h:420
#define __glibcxx_check_valid_range(_First, _Last)
Definition: macros.h:53
_InputIterator __check_valid_range(const _InputIterator &__first, const _InputIterator &__last __attribute__((__unused__)))
Definition: functions.h:157
bool __valid_range(const _InputIterator &__first, const _InputIterator &__last)
Definition: functions.h:131
bool __check_sorted_set_aux(const _InputIterator &__first, const _InputIterator &__last, std::__true_type)
Definition: functions.h:288
_GLIBCXX_PURE bool _M_singular() const
Definition: functions.h:434
bool _M_valid_range(const _Safe_iterator< _Other, _Sequence > &__rhs) const
Definition: safe_iterator.tcc:70
bool __check_singular_aux(const void *)
Definition: functions.h:45
std::__false_type __type
Definition: functions.h:423
bool __check_sorted_set(const _InputIterator1 &__first, const _InputIterator1 &__last, const _InputIterator2 &)
Definition: functions.h:317
Safe iterator wrapper.
Definition: formatter.h:46
bool _M_valid_range(const _Safe_local_iterator< _Other, _Sequence > &__rhs) const
Definition: safe_local_iterator.tcc:38
Safe iterator wrapper.
Definition: formatter.h:49
Definition: functions.h:420
_Iterator base() const
Return the underlying iterator.
Definition: safe_iterator.h:396