diff options
| author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-11-11 20:09:16 +0000 |
|---|---|---|
| committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-11-11 20:09:16 +0000 |
| commit | d570f2e9ecb174ce2e28624245dbc7d3070ab2d4 (patch) | |
| tree | 48d847b6238daa37c4ad869a73f671de6a44761f /libstdc++-v3/include/debug/debug.h | |
| parent | edcee31f574903af8d01e2675588fffe5ddccc49 (diff) | |
| download | ppe42-gcc-d570f2e9ecb174ce2e28624245dbc7d3070ab2d4.tar.gz ppe42-gcc-d570f2e9ecb174ce2e28624245dbc7d3070ab2d4.zip | |
2003-11-11 Doug Gregor <gregod@cs.rpi.edu>
* docs/html/debug.html: Document libstdc++ debug mode.
* docs/html/debug_mode.html: Document libstdc++ debug mode design.
* docs/html/test.html: Document how to test under debug mode.
* docs/html/17_intro/howto.html: Document debug-mode macros.
* include/Makefile.am: Install debug-mode headers.
* src/Makefile.am: Include debug.cc.
* include/bits/basic_string.tcc:
(basic_string::_S_construct): Fix NULL pointer check.
(__is_null_pointer): New.
Add precondition annotations.
* include/bits/stream_iterator.h (istream_iterator,
ostream_iterator): Added precondition annotations.
* include/bits/streambuf_iterator.h (istreambuf_iterator): Ditto.
* include/bits/stl_queue.h (queue, priority_queue): Ditto.
* include/bits/stl_stack.h (stack): Ditto.
* include/bits/basic_string.h (basic_string): Ditto.
* include/bits/basic_string.tcc (basic_string): Ditto.
* include/std/std_memory.h (auto_ptr): Ditto.
* include/std/std_valarray.h (valarray): Ditto.
* include/bits/stl_algo.h: Added algorithm precondition
annotations.
* include/bits/stl_algobase.h: Added algorithm precondition
annotations.
* include/bits/stl_numeric.h: Ditto.
* include/ext/algorithm: Added algorithm precondition
annotations.
(__is_heap): Moved away from here.
* include/bits/stl_heap.h: Added algorithm precondition
annotations.
(__is_heap): Moved to the top of this file.
(__is_heap): Added iterator range overloads.
* testsuite/20_util/auto_ptr_neg.cc: Fix line numbers to match up
with changes in std_memory.h.
* testsuite/23_containers/list/operators/4.cc: Don't verify
performance guarantees when in debug mode.
* testsuite/23_containers/bitset/invalidation/1.cc: New.
* testsuite/23_containers/deque/invalidation/1.cc: New.
* testsuite/23_containers/deque/invalidation/2.cc: New.
* testsuite/23_containers/deque/invalidation/3.cc: New.
* testsuite/23_containers/deque/invalidation/4.cc: New.
* testsuite/23_containers/list/invalidation/1.cc: New.
* testsuite/23_containers/list/invalidation/2.cc: New.
* testsuite/23_containers/list/invalidation/3.cc: New.
* testsuite/23_containers/list/invalidation/4.cc: New.
* testsuite/23_containers/map/invalidation/1.cc: New.
* testsuite/23_containers/map/invalidation/2.cc: New.
* testsuite/23_containers/multimap/invalidation/1.cc: New.
* testsuite/23_containers/multimap/invalidation/2.cc: New.
* testsuite/23_containers/multiset/invalidation/1.cc: New.
* testsuite/23_containers/multiset/invalidation/2.cc: New.
* testsuite/23_containers/set/invalidation/1.cc: New.
* testsuite/23_containers/set/invalidation/2.cc: New.
* testsuite/23_containers/vector/invalidation/1.cc: New.
* testsuite/23_containers/vector/invalidation/2.cc: New.
* testsuite/23_containers/vector/invalidation/3.cc: New.
* testsuite/23_containers/vector/invalidation/4.cc: New.
* testsuite/25_algorithms/heap.cc: Don't verify
performance guarantees when in debug mode.
* include/debug/bitset: New.
* include/debug/debug.h: New.
* include/debug/deque: New.
* include/debug/formatter.h: New.
* include/debug/hash_map: New.
* include/debug/hash_map.h: New.
* include/debug/hash_multimap.h: New.
* include/debug/hash_set: New.
* include/debug/hash_set.h: New.
* include/debug/hash_multiset.h: New.
* include/debug/list: New.
* include/debug/map: New.
* include/debug/map.h: New.
* include/debug/multimap.h: New.
* include/debug/multiset.h: New.
* include/debug/safe_base.h: New.
* include/debug/safe_iterator.h: New.
* include/debug/safe_iterator.tcc: New.
* include/debug/safe_sequence.h: New.
* include/debug/set: New.
* include/debug/set.h: New.
* include/debug/string: New.
* include/debug/vector: New.
* src/debug.cc: New.
* config/linker-map.gnu: Add debug mode symbols.
2003-11-11 Benjamin Kosnik <bkoz@redhat.com>
* src/string-inst.cc: Tweak namespaces.
* src/misc-inst.cc: Same.
* docs/html/debug.html: Edits.
* config/link-map.gnu: Remove cruft.
* include/bits/c++config: Add in namespace associations.
* include/std/std_bitset.h: Adjust namespace to __gnu_norm,
comment tweaks.
* include/bits/deque.tcc: Same.
* include/bits/list.tcc: Same.
* include/bits/stl_bvector.h: Same.
* include/bits/stl_deque.h: Same.
* include/bits/stl_list.h: Same.
* include/bits/stl_map.h: Same.
* include/bits/stl_multimap.h: Same.
* include/bits/stl_multiset.h: Same.
* include/bits/stl_set.h: Same.
* include/bits/stl_vector.h: Same.
* include/bits/vector.tcc: Same.
* include/std/std_algorithm.h: Remove markup comments.
* include/std/std_functional.h: Same.
* include/std/std_iterator.h: Same.
* include/std/std_numeric.h: Same.
* include/std/std_utility.h: Same.
* include/bits/stl_queue.h: Formatting tweaks.
* include/bits/stl_stack.h: Same.
* include/std/std_deque.h: Include debugging version in debug mode.
* include/std/std_list.h: Same.
* include/std/std_map.h: Same.
* include/std/std_set.h: Same.
* include/std/std_vector.h: Same.
* include/std/std_queue.h: Use deque, vector.
* include/std/std_stack.h: Same.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73459 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/debug/debug.h')
| -rw-r--r-- | libstdc++-v3/include/debug/debug.h | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h new file mode 100644 index 00000000000..edb19aa85c3 --- /dev/null +++ b/libstdc++-v3/include/debug/debug.h @@ -0,0 +1,531 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEBUG_H +#define _GLIBCXX_DEBUG_DEBUG_H 1 + +/** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ +#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do { \ + if (! (_Condition)) \ + ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + +// Verify that [_First, _Last) forms a valid iterator range. +#define __glibcxx_check_valid_range(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ + _M_message(::__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. +*/ +#define __glibcxx_check_insert(_Position) \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * that it reference the sequence we are inserting into, and that the + * iterator range [_First, Last) is a valid (possibly empty) + * range. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + * + * @tbd We would like to be able to check for noninterference of + * _Position and the range [_First, _Last), but that can't (in + * general) be done. +*/ +#define __glibcxx_check_insert_range(_Position,_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. +*/ +#define __glibcxx_check_erase(_Position) \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(::__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. +*/ +#define __glibcxx_check_erase_range(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +// Verify that the subscript _N is less than the container's size. +#define __glibcxx_check_subscript(_N) \ +_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(::__gnu_debug::__msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + +// Verify that the container is nonempty +#define __glibcxx_check_nonempty() \ +_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(::__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) + +// Verify that the < operator for elements in the sequence is a +// StrictWeakOrdering by checking that it is irreflexive. +#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + +// Verify that the predicate is StrictWeakOrdering by checking that it +// is irreflexive. +#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + +// Verify that the iterator range [_First, _Last) is sorted +#define __glibcxx_check_sorted(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(::__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ +#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ +#define __glibcxx_check_partitioned(_First,_Last,_Value) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(::__gnu_debug::__msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ +#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(::__gnu_debug::__msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + +// Verify that the iterator range [_First, _Last) is a heap +#define __glibcxx_check_heap(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ + _M_message(::__gnu_debug::__msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ +#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) +# define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) +#else +# define __glibcxx_check_string(_String) +# define __glibcxx_check_string_len(_String,_Len) +#endif + +/** Macros used by the implementation outside of debug wrappers to + * verify certain properties. The __glibcxx_requires_xxx macros are + * merely wrappers around the __glibcxx_check_xxx wrappers when we + * are compiling with debug mode, but disappear when we are in + * release mode so that there is no checking performed in, e.g., the + * standard library algorithms. +*/ +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition) + +# ifdef _GLIBXX_DEBUG_PEDANTIC +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition) +# else +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# endif + +# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) \ + __glibcxx_check_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) \ + __glibcxx_check_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) \ + __glibcxx_check_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty() +# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) \ + __glibcxx_check_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) +#else +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define __glibcxx_requires_cond(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() +# define __glibcxx_requires_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) +#endif + +#include <cassert> // TBD: temporary + +#include <stddef.h> // for ptrdiff_t +#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories +#include <bits/type_traits.h> // for _Is_integer + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + // An arbitrary iterator pointer is not singular. + inline bool + __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template<typename _Iterator> + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template<typename _Tp> + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template<typename _Iterator> + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template<typename _Tp> + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template<typename _RandomAccessIterator> + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template<typename _InputIterator> + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template<typename _Integral> + inline bool + __valid_range_aux(const _Integral&, const _Integral&, __true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template<typename _InputIterator> + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template<typename _InputIterator> + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return __gnu_debug::__valid_range_aux(__first, __last, _Integral()); + } + + /** Safe iterators know how to check if they form a valid range. */ + template<typename _Iterator, typename _Sequence> + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + /* Checks that [first, last) is a valid range, and then returns + * __first. This routine is useful when we can't use a separate + * assertion statement because, e.g., we are in a constructor. + */ + template<typename _InputIterator> + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last) + { + _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template<typename _CharT, typename _Integer> + inline const _CharT* + __check_string(const _CharT* __s, const _Integer& __n) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); +#endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template<typename _CharT> + inline const _CharT* + __check_string(const _CharT* __s) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); +#endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we + // can't step through the sequence. + template<typename _InputIterator> + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template<typename _ForwardIterator> + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template<typename _InputIterator, typename _Predicate> + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template<typename _ForwardIterator, typename _Predicate> + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted. + template<typename _InputIterator> + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); + } + + template<typename _InputIterator, typename _Predicate> + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element. + template<typename _ForwardIterator, typename _Tp> + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element. + template<typename _ForwardIterator, typename _Tp, typename _Pred> + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } +} // namespace __gnu_debug + +#ifdef _GLIBCXX_DEBUG +// We need the error formatter +# include <debug/formatter.h> +#endif + +#endif |

