137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// Debugging support implementation -*- C++ -*-
237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// Free Software Foundation, Inc.
537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh//
637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// This file is part of the GNU ISO C++ Library.  This library is free
737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// software; you can redistribute it and/or modify it under the
837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// terms of the GNU General Public License as published by the
937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// Free Software Foundation; either version 3, or (at your option)
1037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// any later version.
1137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
1237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// This library is distributed in the hope that it will be useful,
1337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// but WITHOUT ANY WARRANTY; without even the implied warranty of
1437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// GNU General Public License for more details.
1637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
1737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// Under Section 7 of GPL version 3, you are granted additional
1837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// permissions described in the GCC Runtime Library Exception, version
1937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// 3.1, as published by the Free Software Foundation.
2037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
2137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// You should have received a copy of the GNU General Public License and
2237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// a copy of the GCC Runtime Library Exception along with this program;
2337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh// <http://www.gnu.org/licenses/>.
2537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
2637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh/** @file debug/functions.h
2737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh *  This file is a GNU debug extension to the Standard C++ Library.
2837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh */
2937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
3037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
3137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#define _GLIBCXX_DEBUG_FUNCTIONS_H 1
3237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
3337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#include <bits/c++config.h>
3437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories
3537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#include <bits/cpp_type_traits.h>         // for __is_integer
3637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#include <debug/formatter.h>
3737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
3837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsiehnamespace __gnu_debug
3937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh{
4037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator, typename _Sequence>
4137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    class _Safe_iterator;
4237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
4337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // An arbitrary iterator pointer is not singular.
4437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  inline bool
4537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  __check_singular_aux(const void*) { return false; }
4637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
4737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // We may have an iterator that derives from _Safe_iterator_base but isn't
4837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // a _Safe_iterator.
4937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator>
5037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
5137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_singular(_Iterator& __x)
5237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __check_singular_aux(&__x); }
5337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
5437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Non-NULL pointers are nonsingular. */
5537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Tp>
5637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
5737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_singular(const _Tp* __ptr)
5837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __ptr == 0; }
5937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
6037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Safe iterators know if they are singular. */
6137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator, typename _Sequence>
6237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
6337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
6437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __x._M_singular(); }
6537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
6637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Assume that some arbitrary iterator is dereferenceable, because we
6737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      can't prove that it isn't. */
6837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator>
6937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
7037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_dereferenceable(_Iterator&)
7137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
7237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
7337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Non-NULL pointers are dereferenceable. */
7437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Tp>
7537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
7637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_dereferenceable(const _Tp* __ptr)
7737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __ptr; }
7837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
7937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Safe iterators know if they are singular. */
8037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator, typename _Sequence>
8137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
8237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
8337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __x._M_dereferenceable(); }
8437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
8537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** If the distance between two random access iterators is
8637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  nonnegative, assume the range is valid.
8737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  */
8837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _RandomAccessIterator>
8937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
9037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range_aux2(const _RandomAccessIterator& __first,
9137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       const _RandomAccessIterator& __last,
9237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       std::random_access_iterator_tag)
9337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __last - __first >= 0; }
9437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
9537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Can't test for a valid range with input iterators, because
9637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  iteration may be destructive. So we just assume that the range
9737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  is valid.
9837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  */
9937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
10037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
10137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range_aux2(const _InputIterator&, const _InputIterator&,
10237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       std::input_iterator_tag)
10337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
10437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
10537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** We say that integral types for a valid range, and defer to other
10637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  routines to realize what to do with integral types instead of
10737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  iterators.
10837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  */
10937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Integral>
11037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
11137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range_aux(const _Integral&, const _Integral&, std::__true_type)
11237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
11337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
11437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** We have iterators, so figure out what kind of iterators that are
11537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  to see if we can check the range ahead of time.
11637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  */
11737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
11837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
11937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range_aux(const _InputIterator& __first,
12037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		      const _InputIterator& __last, std::__false_type)
12137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  {
12237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    typedef typename std::iterator_traits<_InputIterator>::iterator_category
12337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      _Category;
12437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    return __valid_range_aux2(__first, __last, _Category());
12537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  }
12637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
12737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Don't know what these iterators are, or if they are even
12837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  iterators (we may get an integral type for InputIterator), so
12937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  see if they are integral and pass them on to the next phase
13037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   *  otherwise.
13137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  */
13237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
13337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
13437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range(const _InputIterator& __first, const _InputIterator& __last)
13537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
13637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::__is_integer<_InputIterator>::__type _Integral;
13737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __valid_range_aux(__first, __last, _Integral());
13837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
13937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
14037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Safe iterators know how to check if they form a valid range. */
14137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator, typename _Sequence>
14237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
14337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
14437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		  const _Safe_iterator<_Iterator, _Sequence>& __last)
14537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __first._M_valid_range(__last); }
14637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
14737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Safe local iterators know how to check if they form a valid range. */
14837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _Iterator, typename _Sequence>
14937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
15037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first,
15137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		  const _Safe_local_iterator<_Iterator, _Sequence>& __last)
15237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __first._M_valid_range(__last); }
15337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
15437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /* Checks that [first, last) is a valid range, and then returns
15537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   * __first. This routine is useful when we can't use a separate
15637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   * assertion statement because, e.g., we are in a constructor.
15737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  */
15837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
15937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline _InputIterator
16037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_valid_range(const _InputIterator& __first,
16137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			const _InputIterator& __last
16237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			__attribute__((__unused__)))
16337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
16437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      __glibcxx_check_valid_range(__first, __last);
16537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __first;
16637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
16737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
16837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
16937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _CharT, typename _Integer>
17037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline const _CharT*
17137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_string(const _CharT* __s,
17237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		   const _Integer& __n __attribute__((__unused__)))
17337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
17437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#ifdef _GLIBCXX_DEBUG_PEDANTIC
17537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      __glibcxx_assert(__s != 0 || __n == 0);
17637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#endif
17737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __s;
17837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
17937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
18037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  /** Checks that __s is non-NULL and then returns __s. */
18137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _CharT>
18237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline const _CharT*
18337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_string(const _CharT* __s)
18437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
18537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#ifdef _GLIBCXX_DEBUG_PEDANTIC
18637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      __glibcxx_assert(__s != 0);
18737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#endif
18837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __s;
18937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
19037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
19137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Can't check if an input iterator sequence is sorted, because we
19237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // can't step through the sequence.
19337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
19437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
19537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_aux(const _InputIterator&, const _InputIterator&,
19637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh                       std::input_iterator_tag)
19737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
19837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
19937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Can verify if a forward iterator sequence is in fact sorted using
20037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // std::__is_sorted
20137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _ForwardIterator>
20237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
20337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
20437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh                       std::forward_iterator_tag)
20537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
20637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      if (__first == __last)
20737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh        return true;
20837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
20937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      _ForwardIterator __next = __first;
21037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      for (++__next; __next != __last; __first = __next, ++__next)
21137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh        if (*__next < *__first)
21237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh          return false;
21337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
21437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return true;
21537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
21637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
21737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Can't check if an input iterator sequence is sorted, because we can't step
21837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // through the sequence.
21937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator, typename _Predicate>
22037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
22137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_aux(const _InputIterator&, const _InputIterator&,
22237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh                       _Predicate, std::input_iterator_tag)
22337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
22437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
22537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Can verify if a forward iterator sequence is in fact sorted using
22637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // std::__is_sorted
22737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _ForwardIterator, typename _Predicate>
22837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
22937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
23037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh                       _Predicate __pred, std::forward_iterator_tag)
23137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
23237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      if (__first == __last)
23337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh        return true;
23437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
23537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      _ForwardIterator __next = __first;
23637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      for (++__next; __next != __last; __first = __next, ++__next)
23737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh        if (__pred(*__next, *__first))
23837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh          return false;
23937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
24037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return true;
24137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
24237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
24337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Determine if a sequence is sorted.
24437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
24537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
24637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
24737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
24837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::iterator_traits<_InputIterator>::iterator_category
24937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh        _Category;
25037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
25137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      // Verify that the < operator for elements in the sequence is a
25237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      // StrictWeakOrdering by checking that it is irreflexive.
25337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      __glibcxx_assert(__first == __last || !(*__first < *__first));
25437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
25537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __check_sorted_aux(__first, __last, _Category());
25637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
25737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
25837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator, typename _Predicate>
25937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
26037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
26137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh                   _Predicate __pred)
26237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
26337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::iterator_traits<_InputIterator>::iterator_category
26437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh        _Category;
26537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
26637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      // Verify that the predicate is StrictWeakOrdering by checking that it
26737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      // is irreflexive.
26837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      __glibcxx_assert(__first == __last || !__pred(*__first, *__first));
26937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
27037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __check_sorted_aux(__first, __last, __pred, _Category());
27137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
27237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
27337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
27437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
27537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_set_aux(const _InputIterator& __first,
27637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   const _InputIterator& __last,
27737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   std::__true_type)
27837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __check_sorted(__first, __last); }
27937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
28037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator>
28137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
28237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_set_aux(const _InputIterator&,
28337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   const _InputIterator&,
28437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   std::__false_type)
28537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
28637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
28737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator, typename _Predicate>
28837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
28937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_set_aux(const _InputIterator& __first,
29037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   const _InputIterator& __last,
29137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   _Predicate __pred, std::__true_type)
29237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return __check_sorted(__first, __last, __pred); }
29337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
29437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator, typename _Predicate>
29537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
29637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_set_aux(const _InputIterator&,
29737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   const _InputIterator&, _Predicate,
29837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			   std::__false_type)
29937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    { return true; }
30037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
30137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // ... special variant used in std::merge, std::includes, std::set_*.
30237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator1, typename _InputIterator2>
30337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
30437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_set(const _InputIterator1& __first,
30537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       const _InputIterator1& __last,
30637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       const _InputIterator2&)
30737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
30837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::iterator_traits<_InputIterator1>::value_type
30937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	_ValueType1;
31037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::iterator_traits<_InputIterator2>::value_type
31137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	_ValueType2;
31237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
31337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
31437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	_SameType;
31537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __check_sorted_set_aux(__first, __last, _SameType());
31637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
31737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
31837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _InputIterator1, typename _InputIterator2,
31937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	   typename _Predicate>
32037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
32137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_sorted_set(const _InputIterator1& __first,
32237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       const _InputIterator1& __last,
32337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh		       const _InputIterator2&, _Predicate __pred)
32437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
32537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::iterator_traits<_InputIterator1>::value_type
32637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	_ValueType1;
32737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::iterator_traits<_InputIterator2>::value_type
32837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	_ValueType2;
32937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
33037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
33137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	_SameType;
33237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __check_sorted_set_aux(__first, __last, __pred, _SameType());
33337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh   }
33437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
33537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // _GLIBCXX_RESOLVE_LIB_DEFECTS
33637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // 270. Binary search requirements overly strict
33737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Determine if a sequence is partitioned w.r.t. this element.
33837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _ForwardIterator, typename _Tp>
33937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
34037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_partitioned_lower(_ForwardIterator __first,
34137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			      _ForwardIterator __last, const _Tp& __value)
34237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
34337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && *__first < __value)
34437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
34537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && !(*__first < __value))
34637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
34737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __first == __last;
34837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
34937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
35037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _ForwardIterator, typename _Tp>
35137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
35237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_partitioned_upper(_ForwardIterator __first,
35337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			      _ForwardIterator __last, const _Tp& __value)
35437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
35537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && !(__value < *__first))
35637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
35737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && __value < *__first)
35837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
35937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __first == __last;
36037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
36137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
36237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  // Determine if a sequence is partitioned w.r.t. this element.
36337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _ForwardIterator, typename _Tp, typename _Pred>
36437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
36537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_partitioned_lower(_ForwardIterator __first,
36637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			      _ForwardIterator __last, const _Tp& __value,
36737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			      _Pred __pred)
36837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
36937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && bool(__pred(*__first, __value)))
37037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
37137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && !bool(__pred(*__first, __value)))
37237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
37337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __first == __last;
37437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
37537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
37637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh  template<typename _ForwardIterator, typename _Tp, typename _Pred>
37737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    inline bool
37837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    __check_partitioned_upper(_ForwardIterator __first,
37937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			      _ForwardIterator __last, const _Tp& __value,
38037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh			      _Pred __pred)
38137f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    {
38237f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && !bool(__pred(__value, *__first)))
38337f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
38437f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      while (__first != __last && bool(__pred(__value, *__first)))
38537f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh	++__first;
38637f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh      return __first == __last;
38737f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh    }
38837f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh} // namespace __gnu_debug
38937f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh
39037f12739251d2637c9405c75951962b5e27bbceeAndrew Hsieh#endif
391