3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the terms
8 // of the GNU General Public License as published by the Free Software
9 // Foundation; either version 3, or (at your option) any later
12 // This library is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
26 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
28 // Permission to use, copy, modify, sell, and distribute this software
29 // is hereby granted without fee, provided that the above copyright
30 // notice appears in all copies, and that both that copyright notice
31 // and this permission notice appear in supporting documentation. None
32 // of the above authors, nor IBM Haifa Research Laboratories, make any
33 // representation about the suitability of this software for any
34 // purpose. It is provided "as is" without express or implied
38 * @file debug_map_base.hpp
39 * Contains a debug-mode base for all maps.
42 #ifndef PB_DS_DEBUG_MAP_BASE_HPP
43 #define PB_DS_DEBUG_MAP_BASE_HPP
51 #include <ext/throw_allocator.h>
52 #include <debug/debug.h>
58 // Need std::pair ostream extractor.
59 template<typename _CharT
, typename _Traits
, typename _Tp1
, typename _Tp2
>
60 inline std::basic_ostream
<_CharT
, _Traits
>&
61 operator<<(std::basic_ostream
<_CharT
, _Traits
>& __out
,
62 const std::pair
<_Tp1
, _Tp2
>& p
)
63 { return (__out
<< '(' << p
.first
<< ',' << p
.second
<< ')'); }
65 #define PB_DS_CLASS_T_DEC \
66 template<typename Key, class Eq_Fn, typename Const_Key_Reference>
68 #define PB_DS_CLASS_C_DEC \
69 debug_map_base<Key, Eq_Fn, Const_Key_Reference>
71 template<typename Key
, class Eq_Fn
, typename Const_Key_Reference
>
75 typedef typename
std::allocator
< Key
> key_allocator
;
77 typedef typename
key_allocator::size_type size_type
;
79 typedef Const_Key_Reference const_key_reference
;
84 debug_map_base(const PB_DS_CLASS_C_DEC
& other
);
89 insert_new(const_key_reference r_key
);
92 erase_existing(const_key_reference r_key
);
98 check_key_exists(const_key_reference r_key
) const;
101 check_key_does_not_exist(const_key_reference r_key
) const;
104 check_size(size_type size
) const;
107 swap(PB_DS_CLASS_C_DEC
& other
);
109 template<typename Cmp_Fn
>
111 split(const_key_reference
, Cmp_Fn
, PB_DS_CLASS_C_DEC
&);
114 join(PB_DS_CLASS_C_DEC
& other
);
117 typedef std::list
< Key
> key_set
;
118 typedef typename
key_set::iterator key_set_iterator
;
119 typedef typename
key_set::const_iterator const_key_set_iterator
;
121 #ifdef _GLIBCXX_DEBUG
123 assert_valid() const;
126 const_key_set_iterator
127 find(const_key_reference r_key
) const;
130 find(const_key_reference r_key
);
139 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
143 debug_map_base(const PB_DS_CLASS_C_DEC
& other
) : m_key_set(other
.m_key_set
)
144 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
149 { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
154 insert_new(const_key_reference r_key
)
156 _GLIBCXX_DEBUG_ONLY(assert_valid();)
157 // XXX FIXME: Adapt for __gnu_cxx::throw_allocator_random.
158 //__gnu_cxx::throw_allocator<char> alloc;
159 // const double orig_throw_prob = alloc.get_probability();
160 // alloc.set_probability(0);
161 if (find(r_key
) != m_key_set
.end())
163 std::cerr
<< "insert_new" << r_key
<< std::endl
;
169 m_key_set
.push_back(r_key
);
173 std::cerr
<< "insert_new" << r_key
<< std::endl
;
176 // alloc.set_probability(orig_throw_prob);
177 _GLIBCXX_DEBUG_ONLY(assert_valid();)
183 erase_existing(const_key_reference r_key
)
185 _GLIBCXX_DEBUG_ONLY(assert_valid();)
186 key_set_iterator it
= find(r_key
);
187 if (it
== m_key_set
.end())
189 std::cerr
<< "erase_existing" << r_key
<< std::endl
;
193 _GLIBCXX_DEBUG_ONLY(assert_valid();)
201 _GLIBCXX_DEBUG_ONLY(assert_valid();)
203 _GLIBCXX_DEBUG_ONLY(assert_valid();)
209 check_key_exists(const_key_reference r_key
) const
211 _GLIBCXX_DEBUG_ONLY(assert_valid();)
212 if (find(r_key
) == m_key_set
.end())
214 std::cerr
<< "check_key_exists" << r_key
<< std::endl
;
217 _GLIBCXX_DEBUG_ONLY(assert_valid();)
223 check_key_does_not_exist(const_key_reference r_key
) const
225 _GLIBCXX_DEBUG_ONLY(assert_valid();)
226 if (find(r_key
) != m_key_set
.end())
230 cerr
<< "check_key_does_not_exist" << r_key
<< endl
;
238 check_size(size_type size
) const
240 _GLIBCXX_DEBUG_ONLY(assert_valid();)
241 const size_type key_set_size
= m_key_set
.size();
242 if (size
!= key_set_size
)
244 std::cerr
<< "check_size " << size
245 << " " << key_set_size
<< std::endl
;
248 _GLIBCXX_DEBUG_ONLY(assert_valid();)
254 swap(PB_DS_CLASS_C_DEC
& other
)
256 _GLIBCXX_DEBUG_ONLY(assert_valid();)
257 m_key_set
.swap(other
.m_key_set
);
258 _GLIBCXX_DEBUG_ONLY(assert_valid();)
262 typename
PB_DS_CLASS_C_DEC::const_key_set_iterator
264 find(const_key_reference r_key
) const
266 _GLIBCXX_DEBUG_ONLY(assert_valid();)
267 typedef const_key_set_iterator iterator_type
;
268 for (iterator_type it
= m_key_set
.begin(); it
!= m_key_set
.end(); ++it
)
269 if (m_eq(*it
, r_key
))
271 return m_key_set
.end();
275 typename
PB_DS_CLASS_C_DEC::key_set_iterator
277 find(const_key_reference r_key
)
279 _GLIBCXX_DEBUG_ONLY(assert_valid();)
280 key_set_iterator it
= m_key_set
.begin();
281 while (it
!= m_key_set
.end())
283 if (m_eq(*it
, r_key
))
288 _GLIBCXX_DEBUG_ONLY(assert_valid();)
291 #ifdef _GLIBCXX_DEBUG
297 const_key_set_iterator prime_it
= m_key_set
.begin();
298 while (prime_it
!= m_key_set
.end())
300 const_key_set_iterator sec_it
= prime_it
;
302 while (sec_it
!= m_key_set
.end())
304 _GLIBCXX_DEBUG_ASSERT(!m_eq(*sec_it
, *prime_it
));
305 _GLIBCXX_DEBUG_ASSERT(!m_eq(*prime_it
, *sec_it
));
314 template<typename Cmp_Fn
>
317 split(const_key_reference r_key
, Cmp_Fn cmp_fn
, PB_DS_CLASS_C_DEC
& other
)
319 // XXX FIXME: Adapt for __gnu_cxx::throw_allocator_random.
320 // __gnu_cxx::throw_allocator<char> alloc;
321 // const double orig_throw_prob = alloc.get_probability();
322 // alloc.set_probability(0);
324 key_set_iterator it
= m_key_set
.begin();
325 while (it
!= m_key_set
.end())
326 if (cmp_fn(r_key
, * it
))
328 other
.insert_new(*it
);
329 it
= m_key_set
.erase(it
);
333 // alloc.set_probability(orig_throw_prob);
339 join(PB_DS_CLASS_C_DEC
& other
)
341 // XXX FIXME: Adapt for __gnu_cxx::throw_allocator_random.
342 // __gnu_cxx::throw_allocator<char> alloc;
343 // const double orig_throw_prob = alloc.get_probability();
344 // alloc.set_probability(0);
345 key_set_iterator it
= other
.m_key_set
.begin();
346 while (it
!= other
.m_key_set
.end())
349 it
= other
.m_key_set
.erase(it
);
351 _GLIBCXX_DEBUG_ASSERT(other
.m_key_set
.empty());
352 // alloc.set_probability(orig_throw_prob);
355 #undef PB_DS_CLASS_T_DEC
356 #undef PB_DS_CLASS_C_DEC
358 } // namespace detail
359 } // namespace __gnu_pbds