Subversion Repositories Kolibri OS

Rev

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

  1. // Debugging support implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-2015 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 which does not reference the sequence we are inserting into.
  104.  *  Note that this macro is only valid when the container is a
  105.  *  _Safe_sequence and the _Position iterator is a _Safe_iterator.
  106. */
  107. #define __glibcxx_check_insert_range(_Position,_First,_Last)            \
  108. __glibcxx_check_valid_range(_First,_Last);                              \
  109. __glibcxx_check_insert(_Position);                                      \
  110. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\
  111.                       _M_message(__gnu_debug::__msg_insert_range_from_self)\
  112.                       ._M_iterator(_First, #_First)                     \
  113.                       ._M_iterator(_Last, #_Last)                       \
  114.                       ._M_sequence(*this, "this"))
  115.  
  116. /** Verify that we can insert the values in the iterator range
  117.  *  [_First, _Last) into *this after the iterator _Position.  Insertion
  118.  *  into a container after a specific position requires that the iterator
  119.  *  be nonsingular (i.e., either dereferenceable or past-the-end),
  120.  *  that it reference the sequence we are inserting into, and that the
  121.  *  iterator range [_First, _Last) is a valid (possibly empty)
  122.  *  range which does not reference the sequence we are inserting into.
  123.  *  Note that this macro is only valid when the container is a
  124.  *  _Safe_sequence and the _Position iterator is a _Safe_iterator.
  125. */
  126. #define __glibcxx_check_insert_range_after(_Position,_First,_Last)      \
  127. __glibcxx_check_valid_range(_First,_Last);                              \
  128. __glibcxx_check_insert_after(_Position);                                \
  129. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\
  130.                       _M_message(__gnu_debug::__msg_insert_range_from_self)\
  131.                       ._M_iterator(_First, #_First)                     \
  132.                       ._M_iterator(_Last, #_Last)                       \
  133.                       ._M_sequence(*this, "this"))
  134.  
  135. /** Verify that we can erase the element referenced by the iterator
  136.  * _Position. We can erase the element if the _Position iterator is
  137.  * dereferenceable and references this sequence.
  138. */
  139. #define __glibcxx_check_erase(_Position)                                \
  140. _GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(),                   \
  141.                       _M_message(__gnu_debug::__msg_erase_bad)          \
  142.                       ._M_sequence(*this, "this")                       \
  143.                       ._M_iterator(_Position, #_Position));             \
  144. _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                   \
  145.                       _M_message(__gnu_debug::__msg_erase_different)    \
  146.                       ._M_sequence(*this, "this")                       \
  147.                       ._M_iterator(_Position, #_Position))
  148.  
  149. /** Verify that we can erase the element after the iterator
  150.  * _Position. We can erase the element if the _Position iterator is
  151.  * before a dereferenceable one and references this sequence.
  152. */
  153. #define __glibcxx_check_erase_after(_Position)                          \
  154. _GLIBCXX_DEBUG_VERIFY(_Position._M_before_dereferenceable(),            \
  155.                       _M_message(__gnu_debug::__msg_erase_after_bad)    \
  156.                       ._M_sequence(*this, "this")                       \
  157.                       ._M_iterator(_Position, #_Position));             \
  158. _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                   \
  159.                       _M_message(__gnu_debug::__msg_erase_different)    \
  160.                       ._M_sequence(*this, "this")                       \
  161.                       ._M_iterator(_Position, #_Position))
  162.  
  163. /** Verify that we can erase the elements in the iterator range
  164.  *  [_First, _Last). We can erase the elements if [_First, _Last) is a
  165.  *  valid iterator range within this sequence.
  166. */
  167. #define __glibcxx_check_erase_range(_First,_Last)                       \
  168. __glibcxx_check_valid_range(_First,_Last);                              \
  169. _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),                      \
  170.                       _M_message(__gnu_debug::__msg_erase_different)    \
  171.                       ._M_sequence(*this, "this")                       \
  172.                       ._M_iterator(_First, #_First)                     \
  173.                       ._M_iterator(_Last, #_Last))
  174.  
  175. /** Verify that we can erase the elements in the iterator range
  176.  *  (_First, _Last). We can erase the elements if (_First, _Last) is a
  177.  *  valid iterator range within this sequence.
  178. */
  179. #define __glibcxx_check_erase_range_after(_First,_Last)                 \
  180. _GLIBCXX_DEBUG_VERIFY(_First._M_can_compare(_Last),                     \
  181.                       _M_message(__gnu_debug::__msg_erase_different)    \
  182.                       ._M_sequence(*this, "this")                       \
  183.                       ._M_iterator(_First, #_First)                     \
  184.                       ._M_iterator(_Last, #_Last));                     \
  185. _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),                      \
  186.                       _M_message(__gnu_debug::__msg_erase_different)    \
  187.                       ._M_sequence(*this, "this")                       \
  188.                       ._M_iterator(_First, #_First));                   \
  189. _GLIBCXX_DEBUG_VERIFY(_First != _Last,                                  \
  190.                       _M_message(__gnu_debug::__msg_valid_range2)       \
  191.                       ._M_sequence(*this, "this")                       \
  192.                       ._M_iterator(_First, #_First)                     \
  193.                       ._M_iterator(_Last, #_Last));                     \
  194. _GLIBCXX_DEBUG_VERIFY(_First._M_incrementable(),                        \
  195.                       _M_message(__gnu_debug::__msg_valid_range2)       \
  196.                       ._M_sequence(*this, "this")                       \
  197.                       ._M_iterator(_First, #_First)                     \
  198.                       ._M_iterator(_Last, #_Last));                     \
  199. _GLIBCXX_DEBUG_VERIFY(!_Last._M_is_before_begin(),                      \
  200.                       _M_message(__gnu_debug::__msg_valid_range2)       \
  201.                       ._M_sequence(*this, "this")                       \
  202.                       ._M_iterator(_First, #_First)                     \
  203.                       ._M_iterator(_Last, #_Last))                      \
  204.  
  205. // Verify that the subscript _N is less than the container's size.
  206. #define __glibcxx_check_subscript(_N)                                   \
  207. _GLIBCXX_DEBUG_VERIFY(_N < this->size(),                                \
  208.                       _M_message(__gnu_debug::__msg_subscript_oob)      \
  209.                       ._M_sequence(*this, "this")                       \
  210.                       ._M_integer(_N, #_N)                              \
  211.                       ._M_integer(this->size(), "size"))
  212.  
  213. // Verify that the bucket _N is less than the container's buckets count.
  214. #define __glibcxx_check_bucket_index(_N)                                \
  215. _GLIBCXX_DEBUG_VERIFY(_N < this->bucket_count(),                        \
  216.                       _M_message(__gnu_debug::__msg_bucket_index_oob)   \
  217.                       ._M_sequence(*this, "this")                       \
  218.                       ._M_integer(_N, #_N)                              \
  219.                       ._M_integer(this->bucket_count(), "size"))
  220.  
  221. // Verify that the container is nonempty
  222. #define __glibcxx_check_nonempty()                                      \
  223. _GLIBCXX_DEBUG_VERIFY(! this->empty(),                                  \
  224.                       _M_message(__gnu_debug::__msg_empty)              \
  225.                       ._M_sequence(*this, "this"))
  226.  
  227. // Verify that the iterator range [_First, _Last) is sorted
  228. #define __glibcxx_check_sorted(_First,_Last)                            \
  229. __glibcxx_check_valid_range(_First,_Last);                              \
  230.  _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(                     \
  231.                         __gnu_debug::__base(_First),                    \
  232.                         __gnu_debug::__base(_Last)),                    \
  233.                       _M_message(__gnu_debug::__msg_unsorted)           \
  234.                       ._M_iterator(_First, #_First)                     \
  235.                       ._M_iterator(_Last, #_Last))
  236.  
  237. /** Verify that the iterator range [_First, _Last) is sorted by the
  238.     predicate _Pred. */
  239. #define __glibcxx_check_sorted_pred(_First,_Last,_Pred)                 \
  240. __glibcxx_check_valid_range(_First,_Last);                              \
  241. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(                      \
  242.                         __gnu_debug::__base(_First),                    \
  243.                         __gnu_debug::__base(_Last), _Pred),             \
  244.                       _M_message(__gnu_debug::__msg_unsorted_pred)      \
  245.                       ._M_iterator(_First, #_First)                     \
  246.                       ._M_iterator(_Last, #_Last)                       \
  247.                       ._M_string(#_Pred))
  248.  
  249. // Special variant for std::merge, std::includes, std::set_*
  250. #define __glibcxx_check_sorted_set(_First1,_Last1,_First2)              \
  251. __glibcxx_check_valid_range(_First1,_Last1);                            \
  252. _GLIBCXX_DEBUG_VERIFY(                                                  \
  253.   __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1),         \
  254.                                   __gnu_debug::__base(_Last1), _First2),\
  255.   _M_message(__gnu_debug::__msg_unsorted)                               \
  256.   ._M_iterator(_First1, #_First1)                                       \
  257.   ._M_iterator(_Last1, #_Last1))
  258.  
  259. // Likewise with a _Pred.
  260. #define __glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred)   \
  261. __glibcxx_check_valid_range(_First1,_Last1);                            \
  262. _GLIBCXX_DEBUG_VERIFY(                                                  \
  263.   __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1),         \
  264.                                   __gnu_debug::__base(_Last1),          \
  265.                                   _First2, _Pred),                      \
  266.   _M_message(__gnu_debug::__msg_unsorted_pred)                          \
  267.   ._M_iterator(_First1, #_First1)                                       \
  268.   ._M_iterator(_Last1, #_Last1)                                         \
  269.   ._M_string(#_Pred))
  270.  
  271. /** Verify that the iterator range [_First, _Last) is partitioned
  272.     w.r.t. the value _Value. */
  273. #define __glibcxx_check_partitioned_lower(_First,_Last,_Value)          \
  274. __glibcxx_check_valid_range(_First,_Last);                              \
  275. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(           \
  276.                         __gnu_debug::__base(_First),                    \
  277.                         __gnu_debug::__base(_Last), _Value),            \
  278.                       _M_message(__gnu_debug::__msg_unpartitioned)      \
  279.                       ._M_iterator(_First, #_First)                     \
  280.                       ._M_iterator(_Last, #_Last)                       \
  281.                       ._M_string(#_Value))
  282.  
  283. #define __glibcxx_check_partitioned_upper(_First,_Last,_Value)          \
  284. __glibcxx_check_valid_range(_First,_Last);                              \
  285. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(           \
  286.                         __gnu_debug::__base(_First),                    \
  287.                         __gnu_debug::__base(_Last), _Value),            \
  288.                       _M_message(__gnu_debug::__msg_unpartitioned)      \
  289.                       ._M_iterator(_First, #_First)                     \
  290.                       ._M_iterator(_Last, #_Last)                       \
  291.                       ._M_string(#_Value))
  292.  
  293. /** Verify that the iterator range [_First, _Last) is partitioned
  294.     w.r.t. the value _Value and predicate _Pred. */
  295. #define __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
  296. __glibcxx_check_valid_range(_First,_Last);                              \
  297. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(           \
  298.                         __gnu_debug::__base(_First),                    \
  299.                         __gnu_debug::__base(_Last), _Value, _Pred),     \
  300.                       _M_message(__gnu_debug::__msg_unpartitioned_pred) \
  301.                       ._M_iterator(_First, #_First)                     \
  302.                       ._M_iterator(_Last, #_Last)                       \
  303.                       ._M_string(#_Pred)                                \
  304.                       ._M_string(#_Value))
  305.  
  306. /** Verify that the iterator range [_First, _Last) is partitioned
  307.     w.r.t. the value _Value and predicate _Pred. */
  308. #define __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
  309. __glibcxx_check_valid_range(_First,_Last);                              \
  310. _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(           \
  311.                         __gnu_debug::__base(_First),                    \
  312.                         __gnu_debug::__base(_Last), _Value, _Pred),     \
  313.                       _M_message(__gnu_debug::__msg_unpartitioned_pred) \
  314.                       ._M_iterator(_First, #_First)                     \
  315.                       ._M_iterator(_Last, #_Last)                       \
  316.                       ._M_string(#_Pred)                                \
  317.                       ._M_string(#_Value))
  318.  
  319. // Verify that the iterator range [_First, _Last) is a heap
  320. #define __glibcxx_check_heap(_First,_Last)                              \
  321.   _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First),     \
  322.                                        __gnu_debug::__base(_Last)),     \
  323.                       _M_message(__gnu_debug::__msg_not_heap)           \
  324.                       ._M_iterator(_First, #_First)                     \
  325.                       ._M_iterator(_Last, #_Last))
  326.  
  327. /** Verify that the iterator range [_First, _Last) is a heap
  328.     w.r.t. the predicate _Pred. */
  329. #define __glibcxx_check_heap_pred(_First,_Last,_Pred)                   \
  330.   _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First),     \
  331.                                        __gnu_debug::__base(_Last),      \
  332.                                        _Pred),                          \
  333.                       _M_message(__gnu_debug::__msg_not_heap_pred)      \
  334.                       ._M_iterator(_First, #_First)                     \
  335.                       ._M_iterator(_Last, #_Last)                       \
  336.                       ._M_string(#_Pred))
  337.  
  338. // Verify that the container is not self move assigned
  339. #define __glibcxx_check_self_move_assign(_Other)                        \
  340. _GLIBCXX_DEBUG_VERIFY(this != &_Other,                                  \
  341.                       _M_message(__gnu_debug::__msg_self_move_assign)   \
  342.                       ._M_sequence(*this, "this"))
  343.  
  344. // Verify that load factor is positive
  345. #define __glibcxx_check_max_load_factor(_F)                             \
  346. _GLIBCXX_DEBUG_VERIFY(_F > 0.0f,                                        \
  347.                       _M_message(__gnu_debug::__msg_valid_load_factor)  \
  348.                       ._M_sequence(*this, "this"))
  349.  
  350. #define __glibcxx_check_equal_allocs(_This, _Other)                     \
  351. _GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(),  \
  352.                       _M_message(__gnu_debug::__msg_equal_allocs)       \
  353.                       ._M_sequence(_This, "this"))
  354.  
  355. #ifdef _GLIBCXX_DEBUG_PEDANTIC
  356. #  define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
  357. #  define __glibcxx_check_string_len(_String,_Len) \
  358.        _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
  359. #else
  360. #  define __glibcxx_check_string(_String)
  361. #  define __glibcxx_check_string_len(_String,_Len)
  362. #endif
  363.  
  364. #endif
  365.