1117397Skan// Debugging support implementation -*- C++ -*-
297403Sobrien
397403Sobrien// Copyright (C) 2003, 2005, 2006
497403Sobrien// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
1997403Sobrien// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien/** @file debug/macros.h
3297403Sobrien *  This file is a GNU debug extension to the Standard C++ Library.
33107606Sobrien */
3497403Sobrien
35107606Sobrien#ifndef _GLIBCXX_DEBUG_MACROS_H
36107606Sobrien#define _GLIBCXX_DEBUG_MACROS_H 1
3797403Sobrien
38117397Skan/**
39117397Skan * Macros used by the implementation to verify certain
40107606Sobrien * properties. These macros may only be used directly by the debug
41107606Sobrien * wrappers. Note that these are macros (instead of the more obviously
4297403Sobrien * "correct" choice of making them functions) because we need line and
4397403Sobrien * file information at the call site, to minimize the distance between
4497403Sobrien * the user error and where the error is reported.
4597403Sobrien *
4697403Sobrien */
4797403Sobrien#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage)		        \
4897403Sobrien  do 									\
4997403Sobrien  {									\
5097403Sobrien    if (! (_Condition))							\
5197403Sobrien      __gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__)	        \
5297403Sobrien	  ._ErrorMessage._M_error();					\
5397403Sobrien  } while (false)
5497403Sobrien
5597403Sobrien// Verify that [_First, _Last) forms a valid iterator range.
5697403Sobrien#define __glibcxx_check_valid_range(_First,_Last)			\
5797403Sobrien_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__valid_range(_First, _Last),	\
5897403Sobrien		      _M_message(__gnu_debug::__msg_valid_range)	\
5997403Sobrien		      ._M_iterator(_First, #_First)			\
6097403Sobrien		      ._M_iterator(_Last, #_Last))
6197403Sobrien
6297403Sobrien/** Verify that we can insert into *this with the iterator _Position.
6397403Sobrien *  Insertion into a container at a specific position requires that
6497403Sobrien *  the iterator be nonsingular (i.e., either dereferenceable or
6597403Sobrien *  past-the-end) and that it reference the sequence we are inserting
6697403Sobrien *  into. Note that this macro is only valid when the container is a
6797403Sobrien *  _Safe_sequence and the iterator is a _Safe_iterator.
6897403Sobrien*/
6997403Sobrien#define __glibcxx_check_insert(_Position)				\
7097403Sobrien_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(),				\
7197403Sobrien		      _M_message(__gnu_debug::__msg_insert_singular) \
72117397Skan		      ._M_sequence(*this, "this")			\
73117397Skan		      ._M_iterator(_Position, #_Position));		\
74117397Skan_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),			\
75117397Skan		      _M_message(__gnu_debug::__msg_insert_different) \
76117397Skan		      ._M_sequence(*this, "this")			\
77107606Sobrien		      ._M_iterator(_Position, #_Position))
7897403Sobrien
79107606Sobrien/** Verify that we can insert the values in the iterator range
80107606Sobrien *  [_First, _Last) into *this with the iterator _Position.  Insertion
81107606Sobrien *  into a container at a specific position requires that the iterator
82107606Sobrien *  be nonsingular (i.e., either dereferenceable or past-the-end),
8397403Sobrien *  that it reference the sequence we are inserting into, and that the
8497403Sobrien *  iterator range [_First, Last) is a valid (possibly empty)
8597403Sobrien *  range. Note that this macro is only valid when the container is a
86117397Skan *  _Safe_sequence and the iterator is a _Safe_iterator.
8797403Sobrien *
8897403Sobrien *  @tbd We would like to be able to check for noninterference of
8997403Sobrien *  _Position and the range [_First, _Last), but that can't (in
90117397Skan *  general) be done.
91117397Skan*/
92117397Skan#define __glibcxx_check_insert_range(_Position,_First,_Last)		\
9397403Sobrien__glibcxx_check_valid_range(_First,_Last);				\
94107606Sobrien_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(),				\
95107606Sobrien		      _M_message(__gnu_debug::__msg_insert_singular)    \
96107606Sobrien                      ._M_sequence(*this, "this")			\
97107606Sobrien		      ._M_iterator(_Position, #_Position));		\
9897403Sobrien_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),			\
9997403Sobrien		      _M_message(__gnu_debug::__msg_insert_different)   \
10097403Sobrien		      ._M_sequence(*this, "this")			\
10197403Sobrien		      ._M_iterator(_Position, #_Position))
10297403Sobrien
10397403Sobrien/** Verify that we can erase the element referenced by the iterator
10497403Sobrien * _Position. We can erase the element if the _Position iterator is
10597403Sobrien * dereferenceable and references this sequence.
10697403Sobrien*/
107117397Skan#define __glibcxx_check_erase(_Position)				\
108117397Skan_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(),			\
109117397Skan		      _M_message(__gnu_debug::__msg_erase_bad)	        \
11097403Sobrien                      ._M_sequence(*this, "this")			\
11197403Sobrien		      ._M_iterator(_Position, #_Position));		\
11297403Sobrien_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),			\
11397403Sobrien		      _M_message(__gnu_debug::__msg_erase_different)    \
11497403Sobrien		      ._M_sequence(*this, "this")			\
11597403Sobrien		      ._M_iterator(_Position, #_Position))
11697403Sobrien
11797403Sobrien/** Verify that we can erase the elements in the iterator range
11897403Sobrien *  [_First, _Last). We can erase the elements if [_First, _Last) is a
11997403Sobrien *  valid iterator range within this sequence.
12097403Sobrien*/
12197403Sobrien#define __glibcxx_check_erase_range(_First,_Last)			\
12297403Sobrien__glibcxx_check_valid_range(_First,_Last);				\
123107606Sobrien_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),			\
124107606Sobrien		      _M_message(__gnu_debug::__msg_erase_different)    \
125107606Sobrien                      ._M_sequence(*this, "this")			\
126107606Sobrien		      ._M_iterator(_First, #_First)			\
127107606Sobrien		      ._M_iterator(_Last, #_Last))
128107606Sobrien
129107606Sobrien// Verify that the subscript _N is less than the container's size.
13097403Sobrien#define __glibcxx_check_subscript(_N)					\
13197403Sobrien_GLIBCXX_DEBUG_VERIFY(_N < this->size(),				\
13297403Sobrien		      _M_message(__gnu_debug::__msg_subscript_oob)      \
13397403Sobrien                      ._M_sequence(*this, "this")			\
13497403Sobrien		      ._M_integer(_N, #_N)				\
135107606Sobrien		      ._M_integer(this->size(), "size"))
13697403Sobrien
13797403Sobrien// Verify that the container is nonempty
13897403Sobrien#define __glibcxx_check_nonempty()					\
13997403Sobrien_GLIBCXX_DEBUG_VERIFY(! this->empty(),					\
14097403Sobrien		      _M_message(__gnu_debug::__msg_empty)	        \
14197403Sobrien                      ._M_sequence(*this, "this"))
14297403Sobrien
143117397Skan// Verify that the < operator for elements in the sequence is a
144117397Skan// StrictWeakOrdering by checking that it is irreflexive.
145117397Skan#define __glibcxx_check_strict_weak_ordering(_First,_Last)	\
146117397Skan_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First))
14797403Sobrien
14897403Sobrien// Verify that the predicate is StrictWeakOrdering by checking that it
14997403Sobrien// is irreflexive.
15097403Sobrien#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred)	\
15197403Sobrien_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First))
15297403Sobrien
15397403Sobrien
15497403Sobrien// Verify that the iterator range [_First, _Last) is sorted
15597403Sobrien#define __glibcxx_check_sorted(_First,_Last)				\
156110614Skan__glibcxx_check_valid_range(_First,_Last);				\
157107606Sobrien__glibcxx_check_strict_weak_ordering(_First,_Last);			\
158107606Sobrien_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last),	\
159107606Sobrien		      _M_message(__gnu_debug::__msg_unsorted)	        \
160107606Sobrien                      ._M_iterator(_First, #_First)			\
161107606Sobrien		      ._M_iterator(_Last, #_Last))
162110614Skan
163107606Sobrien/** Verify that the iterator range [_First, _Last) is sorted by the
164107606Sobrien    predicate _Pred. */
165107606Sobrien#define __glibcxx_check_sorted_pred(_First,_Last,_Pred)			\
166107606Sobrien__glibcxx_check_valid_range(_First,_Last);				\
167107606Sobrien__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred);	        \
168110614Skan_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \
169107606Sobrien		      _M_message(__gnu_debug::__msg_unsorted_pred)      \
170110614Skan                      ._M_iterator(_First, #_First)			\
171107606Sobrien		      ._M_iterator(_Last, #_Last)			\
172110614Skan		      ._M_string(#_Pred))
173110614Skan
174110614Skan/** Verify that the iterator range [_First, _Last) is partitioned
175110614Skan    w.r.t. the value _Value. */
176110614Skan#define __glibcxx_check_partitioned(_First,_Last,_Value)		\
177110614Skan__glibcxx_check_valid_range(_First,_Last);				\
178110614Skan_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned(_First, _Last,   \
179107606Sobrien							    _Value),	\
180107606Sobrien		      _M_message(__gnu_debug::__msg_unpartitioned)      \
181107606Sobrien		      ._M_iterator(_First, #_First)			\
182117397Skan		      ._M_iterator(_Last, #_Last)			\
183107606Sobrien		      ._M_string(#_Value))
184107606Sobrien
18597403Sobrien/** Verify that the iterator range [_First, _Last) is partitioned
18697403Sobrien    w.r.t. the value _Value and predicate _Pred. */
18797403Sobrien#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred)	\
18897403Sobrien__glibcxx_check_valid_range(_First,_Last);				\
18997403Sobrien_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned(_First, _Last,   \
190102782Skan							 _Value, _Pred), \
191102782Skan		      _M_message(__gnu_debug::__msg_unpartitioned_pred) \
19297403Sobrien		      ._M_iterator(_First, #_First)			\
19397403Sobrien		      ._M_iterator(_Last, #_Last)			\
19497403Sobrien		      ._M_string(#_Pred)				\
19597403Sobrien                      ._M_string(#_Value))
19697403Sobrien
19797403Sobrien// Verify that the iterator range [_First, _Last) is a heap
19897403Sobrien#define __glibcxx_check_heap(_First,_Last)				\
19997403Sobrien__glibcxx_check_valid_range(_First,_Last);				\
20097403Sobrien_GLIBCXX_DEBUG_VERIFY(std::__is_heap(_First, _Last),		        \
20197403Sobrien		      _M_message(__gnu_debug::__msg_not_heap)	        \
20297403Sobrien		      ._M_iterator(_First, #_First)			\
20397403Sobrien		      ._M_iterator(_Last, #_Last))
20497403Sobrien
20597403Sobrien/** Verify that the iterator range [_First, _Last) is a heap
206102782Skan    w.r.t. the predicate _Pred. */
207102782Skan#define __glibcxx_check_heap_pred(_First,_Last,_Pred)			\
20897403Sobrien__glibcxx_check_valid_range(_First,_Last);				\
20997403Sobrien_GLIBCXX_DEBUG_VERIFY(std::__is_heap(_First, _Last, _Pred),		\
21097403Sobrien		      _M_message(__gnu_debug::__msg_not_heap_pred)      \
21197403Sobrien                      ._M_iterator(_First, #_First)			\
21297403Sobrien		      ._M_iterator(_Last, #_Last)			\
21397403Sobrien		      ._M_string(#_Pred))
21497403Sobrien
21597403Sobrien#ifdef _GLIBCXX_DEBUG_PEDANTIC
21697403Sobrien#  define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
21797403Sobrien#  define __glibcxx_check_string_len(_String,_Len) \
21897403Sobrien       _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
21997403Sobrien#else
220107606Sobrien#  define __glibcxx_check_string(_String)
221107606Sobrien#  define __glibcxx_check_string_len(_String,_Len)
22297403Sobrien#endif
223107606Sobrien
224110614Skan#endif
225110614Skan