1169691Skan// -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the terms
7169691Skan// of the GNU General Public License as published by the Free Software
8169691Skan// Foundation; either version 2, or (at your option) any later
9169691Skan// version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful, but
12169691Skan// WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14169691Skan// General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License
17169691Skan// along with this library; see the file COPYING.  If not, write to
18169691Skan// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19169691Skan// MA 02111-1307, USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free
22169691Skan// software library without restriction.  Specifically, if other files
23169691Skan// instantiate templates or use macros or inline functions from this
24169691Skan// file, or you compile this file and link it with other files to
25169691Skan// produce an executable, this file does not by itself cause the
26169691Skan// resulting executable to be covered by the GNU General Public
27169691Skan// License.  This exception does not however invalidate any other
28169691Skan// reasons why the executable file might be covered by the GNU General
29169691Skan// Public License.
30169691Skan
31169691Skan// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32169691Skan
33169691Skan// Permission to use, copy, modify, sell, and distribute this software
34169691Skan// is hereby granted without fee, provided that the above copyright
35169691Skan// notice appears in all copies, and that both that copyright notice
36169691Skan// and this permission notice appear in supporting documentation. None
37169691Skan// of the above authors, nor IBM Haifa Research Laboratories, make any
38169691Skan// representation about the suitability of this software for any
39169691Skan// purpose. It is provided "as is" without express or implied
40169691Skan// warranty.
41169691Skan
42169691Skan/**
43169691Skan * @file debug_fn_imps.hpp
44169691Skan * Contains an implementation class for bin_search_tree_.
45169691Skan */
46169691Skan
47169691Skan#ifdef _GLIBCXX_DEBUG
48169691Skan
49169691SkanPB_DS_CLASS_T_DEC
50169691Skanvoid
51169691SkanPB_DS_CLASS_C_DEC::
52169691Skanassert_valid() const
53169691Skan{
54169691Skan  structure_only_assert_valid();
55169691Skan  assert_consistent_with_debug_base();
56169691Skan  assert_size();
57169691Skan  assert_iterators();
58169691Skan  if (m_p_head->m_p_parent == NULL)
59169691Skan    {
60169691Skan      _GLIBCXX_DEBUG_ASSERT(m_size == 0);
61169691Skan    }
62169691Skan  else
63169691Skan    {
64169691Skan      _GLIBCXX_DEBUG_ASSERT(m_size > 0);
65169691Skan    }
66169691Skan}
67169691Skan
68169691SkanPB_DS_CLASS_T_DEC
69169691Skanvoid
70169691SkanPB_DS_CLASS_C_DEC::
71169691Skanstructure_only_assert_valid() const
72169691Skan{
73169691Skan  _GLIBCXX_DEBUG_ASSERT(m_p_head != NULL);
74169691Skan  if (m_p_head->m_p_parent == NULL)
75169691Skan    {
76169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left == m_p_head);
77169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right == m_p_head);
78169691Skan    }
79169691Skan  else
80169691Skan    {
81169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent->m_p_parent == m_p_head);
82169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left != m_p_head);
83169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right != m_p_head);
84169691Skan    }
85169691Skan
86169691Skan  if (m_p_head->m_p_parent != NULL)
87169691Skan    assert_node_consistent(m_p_head->m_p_parent);
88169691Skan  assert_min();
89169691Skan  assert_max();
90169691Skan}
91169691Skan
92169691SkanPB_DS_CLASS_T_DEC
93169691Skanvoid
94169691SkanPB_DS_CLASS_C_DEC::
95169691Skanassert_node_consistent(const node_pointer p_nd) const
96169691Skan{
97169691Skan  assert_node_consistent_(p_nd);
98169691Skan}
99169691Skan
100169691SkanPB_DS_CLASS_T_DEC
101169691Skantypename PB_DS_CLASS_C_DEC::node_consistent_t
102169691SkanPB_DS_CLASS_C_DEC::
103169691Skanassert_node_consistent_(const node_pointer p_nd) const
104169691Skan{
105169691Skan  if (p_nd == NULL)
106169691Skan    return (std::make_pair((const_pointer)NULL,(const_pointer)NULL));
107169691Skan
108169691Skan  assert_node_consistent_with_left(p_nd);
109169691Skan  assert_node_consistent_with_right(p_nd);
110169691Skan
111169691Skan  const std::pair<const_pointer, const_pointer>
112169691Skan    l_range = assert_node_consistent_(p_nd->m_p_left);
113169691Skan
114169691Skan  if (l_range.second != NULL)
115169691Skan    _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*l_range.second),
116169691Skan					     PB_DS_V2F(p_nd->m_value)));
117169691Skan
118169691Skan  const std::pair<const_pointer, const_pointer>
119169691Skan    r_range = assert_node_consistent_(p_nd->m_p_right);
120169691Skan
121169691Skan  if (r_range.first != NULL)
122169691Skan    _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value),
123169691Skan					     PB_DS_V2F(*r_range.first)));
124169691Skan
125169691Skan  return (std::make_pair((l_range.first != NULL)? l_range.first :& p_nd->m_value,(r_range.second != NULL)? r_range.second :& p_nd->m_value));
126169691Skan}
127169691Skan
128169691SkanPB_DS_CLASS_T_DEC
129169691Skanvoid
130169691SkanPB_DS_CLASS_C_DEC::
131169691Skanassert_node_consistent_with_left(const node_pointer p_nd) const
132169691Skan{
133169691Skan  if (p_nd->m_p_left == NULL)
134169691Skan    return;
135169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left->m_p_parent == p_nd);
136169691Skan  _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value),
137169691Skan					    PB_DS_V2F(p_nd->m_p_left->m_value)));
138169691Skan}
139169691Skan
140169691SkanPB_DS_CLASS_T_DEC
141169691Skanvoid
142169691SkanPB_DS_CLASS_C_DEC::
143169691Skanassert_node_consistent_with_right(const node_pointer p_nd) const
144169691Skan{
145169691Skan  if (p_nd->m_p_right == NULL)
146169691Skan    return;
147169691Skan  _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right->m_p_parent == p_nd);
148169691Skan  _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_p_right->m_value),
149169691Skan				       PB_DS_V2F(p_nd->m_value)));
150169691Skan}
151169691Skan
152169691SkanPB_DS_CLASS_T_DEC
153169691Skanvoid
154169691SkanPB_DS_CLASS_C_DEC::
155169691Skanassert_min() const
156169691Skan{
157169691Skan  assert_min_imp(m_p_head->m_p_parent);
158169691Skan}
159169691Skan
160169691SkanPB_DS_CLASS_T_DEC
161169691Skanvoid
162169691SkanPB_DS_CLASS_C_DEC::
163169691Skanassert_min_imp(const node_pointer p_nd) const
164169691Skan{
165169691Skan  if (p_nd == NULL)
166169691Skan    {
167169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left == m_p_head);
168169691Skan      return;
169169691Skan    }
170169691Skan
171169691Skan  if (p_nd->m_p_left == NULL)
172169691Skan    {
173169691Skan      _GLIBCXX_DEBUG_ASSERT(p_nd == m_p_head->m_p_left);
174169691Skan      return;
175169691Skan    }
176169691Skan  assert_min_imp(p_nd->m_p_left);
177169691Skan}
178169691Skan
179169691SkanPB_DS_CLASS_T_DEC
180169691Skanvoid
181169691SkanPB_DS_CLASS_C_DEC::
182169691Skanassert_max() const
183169691Skan{
184169691Skan  assert_max_imp(m_p_head->m_p_parent);
185169691Skan}
186169691Skan
187169691SkanPB_DS_CLASS_T_DEC
188169691Skanvoid
189169691SkanPB_DS_CLASS_C_DEC::
190169691Skanassert_max_imp(const node_pointer p_nd) const
191169691Skan{
192169691Skan  if (p_nd == NULL)
193169691Skan    {
194169691Skan      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right == m_p_head);
195169691Skan      return;
196169691Skan    }
197169691Skan
198169691Skan  if (p_nd->m_p_right == NULL)
199169691Skan    {
200169691Skan      _GLIBCXX_DEBUG_ASSERT(p_nd == m_p_head->m_p_right);
201169691Skan      return;
202169691Skan    }
203169691Skan
204169691Skan  assert_max_imp(p_nd->m_p_right);
205169691Skan}
206169691Skan
207169691SkanPB_DS_CLASS_T_DEC
208169691Skanvoid
209169691SkanPB_DS_CLASS_C_DEC::
210169691Skanassert_iterators() const
211169691Skan{
212169691Skan  size_type iterated_num = 0;
213169691Skan  const_iterator prev_it = end();
214169691Skan  for (const_iterator it = begin(); it != end(); ++it)
215169691Skan    {
216169691Skan      ++iterated_num;
217169691Skan      _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)).m_p_nd == it.m_p_nd);
218169691Skan      const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it));
219169691Skan      --upper_bound_it;
220169691Skan      _GLIBCXX_DEBUG_ASSERT(upper_bound_it.m_p_nd == it.m_p_nd);
221169691Skan
222169691Skan      if (prev_it != end())
223169691Skan	_GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*prev_it),
224169691Skan						 PB_DS_V2F(*it)));
225169691Skan      prev_it = it;
226169691Skan    }
227169691Skan
228169691Skan  _GLIBCXX_DEBUG_ASSERT(iterated_num == m_size);
229169691Skan  size_type reverse_iterated_num = 0;
230169691Skan  const_reverse_iterator reverse_prev_it = rend();
231169691Skan  for (const_reverse_iterator reverse_it = rbegin(); reverse_it != rend();
232169691Skan       ++reverse_it)
233169691Skan    {
234169691Skan      ++reverse_iterated_num;
235169691Skan      _GLIBCXX_DEBUG_ASSERT(lower_bound(
236169691Skan				   PB_DS_V2F(*reverse_it)).m_p_nd == reverse_it.m_p_nd);
237169691Skan
238169691Skan      const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*reverse_it));
239169691Skan      --upper_bound_it;
240169691Skan      _GLIBCXX_DEBUG_ASSERT(upper_bound_it.m_p_nd == reverse_it.m_p_nd);
241169691Skan      if (reverse_prev_it != rend())
242169691Skan	_GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(*reverse_prev_it),
243169691Skan						  PB_DS_V2F(*reverse_it)));
244169691Skan      reverse_prev_it = reverse_it;
245169691Skan    }
246169691Skan  _GLIBCXX_DEBUG_ASSERT(reverse_iterated_num == m_size);
247169691Skan}
248169691Skan
249169691SkanPB_DS_CLASS_T_DEC
250169691Skanvoid
251169691SkanPB_DS_CLASS_C_DEC::
252169691Skanassert_consistent_with_debug_base() const
253169691Skan{
254169691Skan  map_debug_base::check_size(m_size);
255169691Skan  assert_consistent_with_debug_base(m_p_head->m_p_parent);
256169691Skan}
257169691Skan
258169691SkanPB_DS_CLASS_T_DEC
259169691Skanvoid
260169691SkanPB_DS_CLASS_C_DEC::
261169691Skanassert_consistent_with_debug_base(const node_pointer p_nd) const
262169691Skan{
263169691Skan  if (p_nd == NULL)
264169691Skan    return;
265169691Skan  map_debug_base::check_key_exists(PB_DS_V2F(p_nd->m_value));
266169691Skan  assert_consistent_with_debug_base(p_nd->m_p_left);
267169691Skan  assert_consistent_with_debug_base(p_nd->m_p_right);
268169691Skan}
269169691Skan
270169691SkanPB_DS_CLASS_T_DEC
271169691Skanvoid
272169691SkanPB_DS_CLASS_C_DEC::
273169691Skanassert_size() const
274169691Skan{
275169691Skan  _GLIBCXX_DEBUG_ASSERT(recursive_count(m_p_head->m_p_parent) == m_size);
276169691Skan}
277169691Skan
278169691Skan#endif
279