Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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.  
  25. /** @file debug/macros.h
  26.  *  This file is a GNU debug extension to the Standard C++ Library.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_DEBUG_MACROS_H
  30. #define _GLIBCXX_DEBUG_MACROS_H 1
  31.  
  32. /**
  33.  * Macros used by the implementation to verify certain
  34.  * properties. These macros may only be used directly by the debug
  35.  * wrappers. Note that these are macros (instead of the more obviously
  36.  * @a correct choice of making them functions) because we need line and
  37.  * file information at the call site, to minimize the distance between
  38.  * the user error and where the error is reported.
  39.  *
  40.  */
  41. #define _GLIBCXX_DEBUG_VERIFY_AT(_Condition,_ErrorMessage,_File,_Line)  \
  42.   do                                                                    \
  43.   {                                                                     \
  44.     if (! (_Condition))                                                 \
  45.       __gnu_debug::_Error_formatter::_M_at(_File, _Line)                \
  46.           ._ErrorMessage._M_error();                                    \
  47.   } while (false)
  48.  
  49. #define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage)                 \
  50.   _GLIBCXX_DEBUG_VERIFY_AT(_Condition,_ErrorMessage,__FILE__,__LINE__)
  51.  
  52. // Verify that [_First, _Last) forms a valid iterator range.
  53. #define __glibcxx_check_valid_range(_First,_Last)                       \
  54. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__valid_range(_First, _Last),        \
  55.                       _M_message(__gnu_debug::__msg_valid_range)        \
  56.                       ._M_iterator(_First, #_First)                     \
  57.                       ._M_iterator(_Last, #_Last))
  58.  
  59. // Verify that [_First, _Last) forms a non-empty iterator range.
  60. #define __glibcxx_check_non_empty_range(_First,_Last)                   \
  61. _GLIBCXX_DEBUG_VERIFY(_First != _Last,                                  \
  62.                       _M_message(__gnu_debug::__msg_non_empty_range)    \
  63.                       ._M_iterator(_First, #_First)                     \
  64.                       ._M_iterator(_Last, #_Last))
  65.  
  66. /** Verify that we can insert into *this with the iterator _Position.
  67.  *  Insertion into a container at a specific position requires that
  68.  *  the iterator be nonsingular, either dereferenceable or past-the-end,
  69.  *  and that it reference the sequence we are inserting into. Note that
  70.  *  this macro is only valid when the container is a_Safe_sequence and
  71.  *  the iterator is a _Safe_iterator.
  72. */
  73. #define __glibcxx_check_insert(_Position)                               \
  74. _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(),                         \
  75.                       _M_message(__gnu_debug::__msg_insert_singular) \
  76.                       ._M_sequence(*this, "this")                       \
  77.                       ._M_iterator(_Position, #_Position));             \
  78. _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                   \
  79.                       _M_message(__gnu_debug::__msg_insert_different) \
  80.                       ._M_sequence(*this, "this")                       \
  81.                       ._M_iterator(_Position, #_Position))
  82.  
  83. /** Verify that we can insert into *this after the iterator _Position.
  84.  *  Insertion into a container after a specific position requires that
  85.  *  the iterator be nonsingular, either dereferenceable or before-begin,
  86.  *  and that it reference the sequence we are inserting into. Note that
  87.  *  this macro is only valid when the container is a_Safe_sequence and
  88.  *  the iterator is a _Safe_iterator.
  89. */
  90. #define __glibcxx_check_insert_after(_Position)                         \
  91. __glibcxx_check_insert(_Position);                                      \
  92. _GLIBCXX_DEBUG_VERIFY(!_Position._M_is_end(),                           \
  93.                       _M_message(__gnu_debug::__msg_insert_after_end)   \
  94.                       ._M_sequence(*this, "this")                       \
  95.                       ._M_iterator(_Position, #_Position))
  96.  
  97. /** Verify that we can insert the values in the iterator range
  98.  *  [_First, _Last) into *this with the iterator _Position.  Insertion
  99.  *  into a container at a specific position requires that the iterator
  100.  *  be nonsingular (i.e., either dereferenceable or past-the-end),
  101.  *  that it reference the sequence we are inserting into, and that the
  102.  *  iterator range [_First, Last) is a valid (possibly empty)
  103.  *  range. Note that this macro is only valid when the container is a
  104.  *  _Safe_sequence and the iterator is a _Safe_iterator.
  105.  *
  106.  *  @todo We would like to be able to check for noninterference of
  107.  *  _Position and the range [_First, _Last), but that can't (in
  108.  *  general) be done.
  109. */
  110. #define __glibcxx_check_insert_range(_Position,_First,_Last)            \
  111. __glibcxx_check_valid_range(_First,_Last);                              \
  112. __glibcxx_check_insert(_Position)
  113.  
  114. /** Verify that we can insert the values in the iterator range
  115.  *  [_First, _Last) into *this after the iterator _Position.  Insertion
  116.  *  into a container after a specific position requires that the iterator
  117.  *  be nonsingular (i.e., either dereferenceable or past-the-end),
  118.  *  that it reference the sequence we are inserting into, and that the
  119.  *  iterator range [_First, Last) is a valid (possibly empty)
  120.  *  range. Note that this macro is only valid when the container is a
  121.  *  _Safe_sequence and the iterator is a _Safe_iterator.
  122.  *
  123.  *  @todo We would like to be able to check for noninterference of
  124.  *  _Position and the range [_First, _Last), but that can't (in
  125.  *  general) be done.
  126. */
  127. #define __glibcxx_check_insert_range_after(_Position,_First,_Last)      \
  128. __glibcxx_check_valid_range(_First,_Last);                              \
  129. __glibcxx_check_insert_after(_Position)
  130.  
  131. /** Verify that we can erase the element referenced by the iterator
  132.  * _Position. We can erase the element if the _Position iterator is
  133.  * dereferenceable and references this sequence.
  134. */
  135. #define __glibcxx_check_erase(_Position)                                \
  136. _GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(),                   \
  137.                       _M_message(__gnu_debug::__msg_erase_bad)          \
  138.                       ._M_sequence(*this, "this")                       \
  139.                       ._M_iterator(_Position, #_Position));             \
  140. _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                   \
  141.                       _M_message(__gnu_debug::__msg_erase_different)    \
  142.                       ._M_sequence(*this, "this")                       \
  143.                       ._M_iterator(_Position, #_Position))
  144.  
  145. /** Verify that we can erase the element after the iterator
  146.  * _Position. We can erase the element if the _Position iterator is
  147.  * before a dereferenceable one and references this sequence.
  148. */
  149. #define __glibcxx_check_erase_after(_Position)                          \
  150. _GLIBCXX_DEBUG_VERIFY(_Position._M_before_dereferenceable(),            \
  151.                       _M_message(__gnu_debug::__msg_erase_after_bad)    \
  152.                       ._M_sequence(*this, "this")                       \
  153.                       ._M_iterator(_Position, #_Position));             \
  154. _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                   \
  155.                       _M_message(__gnu_debug::__msg_erase_different)    \
  156.                       ._M_sequence(*this, "this")                       \
  157.                       ._M_iterator(_Position, #_Position))
  158.  
  159. /** Verify that we can erase the elements in the iterator range
  160.  *  [_First, _Last). We can erase the elements if [_First, _Last) is a
  161.  *  valid iterator range within this sequence.
  162. */
  163. #define __glibcxx_check_erase_range(_First,_Last)                       \
  164. __glibcxx_check_valid_range(_First,_Last);                              \
  165. _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),                      \
  166.                       _M_message(__gnu_debug::__msg_erase_different)    \
  167.                       ._M_sequence(*this, "this")                       \
  168.                       ._M_iterator(_First, #_First)                     \
  169.                       ._M_iterator(_Last, #_Last))
  170.  
  171. /** Verify that we can erase the elements in the iterator range
  172.  *  (_First, _Last). We can erase the elements if (_First, _Last) is a
  173.  *  valid iterator range within this sequence.
  174. */
  175. #define __glibcxx_check_erase_range_after(_First,_Last)                 \
  176. _GLIBCXX_DEBUG_VERIFY(_First._M_can_compare(_Last),                     \
  177.                       _M_message(__gnu_debug::__msg_erase_different)    \
  178.                       ._M_sequence(*this, "this")                       \
  179.                       ._M_iterator(_First, #_First)                     \
  180.                       ._M_iterator(_Last, #_Last));                     \
  181. _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),                      \
  182.                       _M_message(__gnu_debug::__msg_erase_different)    \
  183.                       ._M_sequence(*this, "this")                       \
  184.                       ._M_iterator(_First, #_First));                   \
  185. _GLIBCXX_DEBUG_VERIFY(_First != _Last,                                  \
  186.                       _M_message(__gnu_debug::__msg_valid_range2)       \
  187.                       ._M_sequence(*this, "this")                       \
  188.                       ._M_iterator(_First, #_First)                     \
  189.                       ._M_iterator(_Last, #_Last));                     \
  190. _GLIBCXX_DEBUG_VERIFY(_First._M_incrementable(),                        \
  191.                       _M_message(__gnu_debug::__msg_valid_range2)       \
  192.                       ._M_sequence(*this, "this")                       \
  193.                       ._M_iterator(_First, #_First)                     \
  194.                       ._M_iterator(_Last, #_Last));                     \
  195. _GLIBCXX_DEBUG_VERIFY(!_Last._M_is_before_begin(),                      \
  196.                       _M_message(__gnu_debug::__msg_valid_range2)       \
  197.                       ._M_sequence(*this, "this")                       \
  198.                       ._M_iterator(_First, #_First)                     \
  199.                       ._M_iterator(_Last, #_Last))                      \
  200.  
  201. // Verify that the subscript _N is less than the container's size.
  202. #define __glibcxx_check_subscript(_N)                                   \
  203. _GLIBCXX_DEBUG_VERIFY(_N < this->size(),                                \
  204.                       _M_message(__gnu_debug::__msg_subscript_oob)      \
  205.                       ._M_sequence(*this, "this")                       \
  206.                       ._M_integer(_N, #_N)                              \
  207.                       ._M_integer(this->size(), "size"))
  208.  
  209. // Verify that the bucket _N is less than the container's buckets count.
  210. #define __glibcxx_check_bucket_index(_N)                                \
  211. _GLIBCXX_DEBUG_VERIFY(_N < this->bucket_count(),                        \
  212.                       _M_message(__gnu_debug::__msg_bucket_index_oob)   \
  213.                       ._M_sequence(*this, "this")                       \
  214.                       ._M_integer(_N, #_N)                              \
  215.                       ._M_integer(this->bucket_count(), "size"))
  216.  
  217. // Verify that the container is nonempty
  218. #define __glibcxx_check_nonempty()                                      \
  219. _GLIBCXX_DEBUG_VERIFY(! this->empty(),                                  \
  220.                       _M_message(__gnu_debug::__msg_empty)              \
  221.                       ._M_sequence(*this, "this"))
  222.  
  223. // Verify that the iterator range [_First, _Last) is sorted
  224. #define __glibcxx_check_sorted(_First,_Last)                            \
  225. __glibcxx_check_valid_range(_First,_Last);                              \
  226. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last),       \
  227.                       _M_message(__gnu_debug::__msg_unsorted)           \
  228.                       ._M_iterator(_First, #_First)                     \
  229.                       ._M_iterator(_Last, #_Last))
  230.  
  231. /** Verify that the iterator range [_First, _Last) is sorted by the
  232.     predicate _Pred. */
  233. #define __glibcxx_check_sorted_pred(_First,_Last,_Pred)                 \
  234. __glibcxx_check_valid_range(_First,_Last);                              \
  235. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \
  236.                       _M_message(__gnu_debug::__msg_unsorted_pred)      \
  237.                       ._M_iterator(_First, #_First)                     \
  238.                       ._M_iterator(_Last, #_Last)                       \
  239.                       ._M_string(#_Pred))
  240.  
  241. // Special variant for std::merge, std::includes, std::set_*
  242. #define __glibcxx_check_sorted_set(_First1,_Last1,_First2)              \
  243. __glibcxx_check_valid_range(_First1,_Last1);                            \
  244. _GLIBCXX_DEBUG_VERIFY(                                                  \
  245.   __gnu_debug::__check_sorted_set(_First1, _Last1, _First2),            \
  246.   _M_message(__gnu_debug::__msg_unsorted)                               \
  247.   ._M_iterator(_First1, #_First1)                                       \
  248.   ._M_iterator(_Last1, #_Last1))
  249.  
  250. // Likewise with a _Pred.
  251. #define __glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred)   \
  252. __glibcxx_check_valid_range(_First1,_Last1);                            \
  253. _GLIBCXX_DEBUG_VERIFY(                                                  \
  254.   __gnu_debug::__check_sorted_set(_First1, _Last1, _First2, _Pred),     \
  255.   _M_message(__gnu_debug::__msg_unsorted_pred)                          \
  256.   ._M_iterator(_First1, #_First1)                                       \
  257.   ._M_iterator(_Last1, #_Last1)                                         \
  258.   ._M_string(#_Pred))
  259.  
  260. /** Verify that the iterator range [_First, _Last) is partitioned
  261.     w.r.t. the value _Value. */
  262. #define __glibcxx_check_partitioned_lower(_First,_Last,_Value)          \
  263. __glibcxx_check_valid_range(_First,_Last);                              \
  264. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
  265.                                                             _Value),    \
  266.                       _M_message(__gnu_debug::__msg_unpartitioned)      \
  267.                       ._M_iterator(_First, #_First)                     \
  268.                       ._M_iterator(_Last, #_Last)                       \
  269.                       ._M_string(#_Value))
  270.  
  271. #define __glibcxx_check_partitioned_upper(_First,_Last,_Value)          \
  272. __glibcxx_check_valid_range(_First,_Last);                              \
  273. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
  274.                                                             _Value),    \
  275.                       _M_message(__gnu_debug::__msg_unpartitioned)      \
  276.                       ._M_iterator(_First, #_First)                     \
  277.                       ._M_iterator(_Last, #_Last)                       \
  278.                       ._M_string(#_Value))
  279.  
  280. /** Verify that the iterator range [_First, _Last) is partitioned
  281.     w.r.t. the value _Value and predicate _Pred. */
  282. #define __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
  283. __glibcxx_check_valid_range(_First,_Last);                              \
  284. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
  285.                                                          _Value, _Pred), \
  286.                       _M_message(__gnu_debug::__msg_unpartitioned_pred) \
  287.                       ._M_iterator(_First, #_First)                     \
  288.                       ._M_iterator(_Last, #_Last)                       \
  289.                       ._M_string(#_Pred)                                \
  290.                       ._M_string(#_Value))
  291.  
  292. /** Verify that the iterator range [_First, _Last) is partitioned
  293.     w.r.t. the value _Value and predicate _Pred. */
  294. #define __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
  295. __glibcxx_check_valid_range(_First,_Last);                              \
  296. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
  297.                                                          _Value, _Pred), \
  298.                       _M_message(__gnu_debug::__msg_unpartitioned_pred) \
  299.                       ._M_iterator(_First, #_First)                     \
  300.                       ._M_iterator(_Last, #_Last)                       \
  301.                       ._M_string(#_Pred)                                \
  302.                       ._M_string(#_Value))
  303.  
  304. // Verify that the iterator range [_First, _Last) is a heap
  305. #define __glibcxx_check_heap(_First,_Last)                              \
  306.   _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First),     \
  307.                                        __gnu_debug::__base(_Last)),     \
  308.                       _M_message(__gnu_debug::__msg_not_heap)           \
  309.                       ._M_iterator(_First, #_First)                     \
  310.                       ._M_iterator(_Last, #_Last))
  311.  
  312. /** Verify that the iterator range [_First, _Last) is a heap
  313.     w.r.t. the predicate _Pred. */
  314. #define __glibcxx_check_heap_pred(_First,_Last,_Pred)                   \
  315.   _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First),     \
  316.                                        __gnu_debug::__base(_Last),      \
  317.                                        _Pred),                          \
  318.                       _M_message(__gnu_debug::__msg_not_heap_pred)      \
  319.                       ._M_iterator(_First, #_First)                     \
  320.                       ._M_iterator(_Last, #_Last)                       \
  321.                       ._M_string(#_Pred))
  322.  
  323. // Verify that the container is not self move assigned
  324. #define __glibcxx_check_self_move_assign(_Other)                        \
  325. _GLIBCXX_DEBUG_VERIFY(this != &_Other,                                  \
  326.                       _M_message(__gnu_debug::__msg_self_move_assign)   \
  327.                       ._M_sequence(*this, "this"))
  328.  
  329. // Verify that load factor is position
  330. #define __glibcxx_check_max_load_factor(_F)                             \
  331. _GLIBCXX_DEBUG_VERIFY(_F > 0.0f,                                        \
  332.                       _M_message(__gnu_debug::__msg_valid_load_factor)  \
  333.                       ._M_sequence(*this, "this"))
  334.  
  335. #define __glibcxx_check_equal_allocs(_Other)                    \
  336. _GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(),  \
  337.                       _M_message(__gnu_debug::__msg_equal_allocs)       \
  338.                       ._M_sequence(*this, "this"))
  339.  
  340. #ifdef _GLIBCXX_DEBUG_PEDANTIC
  341. #  define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
  342. #  define __glibcxx_check_string_len(_String,_Len) \
  343.        _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
  344. #else
  345. #  define __glibcxx_check_string(_String)
  346. #  define __glibcxx_check_string_len(_String,_Len)
  347. #endif
  348.  
  349. #endif
  350.