Merged trunk at revision 161680 into branch.
[official-gcc.git] / libstdc++-v3 / include / ext / pb_ds / detail / pat_trie_ / point_iterators.hpp
blob0a142478eb81512142f40c974ae6c381a162dd17
1 // -*- C++ -*-
3 // Copyright (C) 2005, 2006, 2009 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 terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
9 // version.
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
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.
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/>.
25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
27 // Permission to use, copy, modify, sell, and distribute this software
28 // is hereby granted without fee, provided that the above copyright
29 // notice appears in all copies, and that both that copyright notice
30 // and this permission notice appear in supporting documentation. None
31 // of the above authors, nor IBM Haifa Research Laboratories, make any
32 // representation about the suitability of this software for any
33 // purpose. It is provided "as is" without express or implied
34 // warranty.
36 /**
37 * @file point_iterators.hpp
38 * Contains an implementation class for bin_search_tree_.
41 #ifndef PB_DS_PAT_TRIE_FIND_ITERATORS_HPP
42 #define PB_DS_PAT_TRIE_FIND_ITERATORS_HPP
44 #include <debug/debug.h>
46 namespace __gnu_pbds
48 namespace detail
51 #define PB_DS_CONST_IT_C_DEC \
52 pat_trie_const_it_< \
53 Type_Traits, \
54 Node, \
55 Leaf, \
56 Head, \
57 Internal_Node, \
58 Is_Forward_Iterator, \
59 Allocator>
61 #define PB_DS_CONST_ODIR_IT_C_DEC \
62 pat_trie_const_it_< \
63 Type_Traits, \
64 Node, \
65 Leaf, \
66 Head, \
67 Internal_Node, \
68 !Is_Forward_Iterator, \
69 Allocator>
71 #define PB_DS_IT_C_DEC \
72 pat_trie_it_< \
73 Type_Traits, \
74 Node, \
75 Leaf, \
76 Head, \
77 Internal_Node, \
78 Is_Forward_Iterator, \
79 Allocator>
81 #define PB_DS_ODIR_IT_C_DEC \
82 pat_trie_it_< \
83 Type_Traits, \
84 Node, \
85 Leaf, \
86 Head, \
87 Internal_Node, \
88 !Is_Forward_Iterator, \
89 Allocator>
92 // Const iterator.
93 template<typename Type_Traits,
94 class Node,
95 class Leaf,
96 class Head,
97 class Internal_Node,
98 bool Is_Forward_Iterator,
99 class Allocator>
100 class pat_trie_const_it_
103 private:
104 typedef
105 typename Allocator::template rebind<
106 Node>::other::pointer
107 node_pointer;
109 typedef
110 typename Allocator::template rebind<
111 Leaf>::other::const_pointer
112 const_leaf_pointer;
114 typedef
115 typename Allocator::template rebind<
116 Leaf>::other::pointer
117 leaf_pointer;
119 typedef
120 typename Allocator::template rebind<
121 Head>::other::pointer
122 head_pointer;
124 typedef
125 typename Allocator::template rebind<
126 Internal_Node>::other::pointer
127 internal_node_pointer;
129 public:
131 typedef std::bidirectional_iterator_tag iterator_category;
133 typedef typename Allocator::difference_type difference_type;
135 typedef typename Type_Traits::value_type value_type;
137 typedef typename Type_Traits::pointer pointer;
139 typedef typename Type_Traits::const_pointer const_pointer;
141 typedef typename Type_Traits::reference reference;
143 typedef typename Type_Traits::const_reference const_reference;
145 public:
147 inline
148 pat_trie_const_it_(node_pointer p_nd = 0) : m_p_nd(p_nd)
151 inline
152 pat_trie_const_it_(const PB_DS_CONST_ODIR_IT_C_DEC& other)
153 : m_p_nd(other.m_p_nd)
156 inline
157 PB_DS_CONST_IT_C_DEC&
158 operator=(const PB_DS_CONST_IT_C_DEC& other)
160 m_p_nd = other.m_p_nd;
161 return *this;
164 inline
165 PB_DS_CONST_IT_C_DEC&
166 operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other)
168 m_p_nd = other.m_p_nd;
169 return *this;
172 inline const_pointer
173 operator->() const
175 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type);
176 return &static_cast<leaf_pointer>(m_p_nd)->value();
179 inline const_reference
180 operator*() const
182 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type);
183 return static_cast<leaf_pointer>(m_p_nd)->value();
186 inline bool
187 operator==(const PB_DS_CONST_IT_C_DEC& other) const
188 { return (m_p_nd == other.m_p_nd); }
190 inline bool
191 operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
192 { return (m_p_nd == other.m_p_nd); }
194 inline bool
195 operator!=(const PB_DS_CONST_IT_C_DEC& other) const
196 { return (m_p_nd != other.m_p_nd); }
198 inline bool
199 operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
200 { return (m_p_nd != other.m_p_nd); }
202 inline PB_DS_CONST_IT_C_DEC&
203 operator++()
205 inc(integral_constant<int,Is_Forward_Iterator>());
206 return *this;
209 inline PB_DS_CONST_IT_C_DEC
210 operator++(int)
212 PB_DS_CONST_IT_C_DEC ret_it(m_p_nd);
213 operator++();
214 return ret_it;
217 inline PB_DS_CONST_IT_C_DEC&
218 operator--()
220 dec(integral_constant<int,Is_Forward_Iterator>());
221 return *this;
224 inline PB_DS_CONST_IT_C_DEC
225 operator--(int)
227 PB_DS_CONST_IT_C_DEC ret_it(m_p_nd);
228 operator--();
229 return ret_it;
232 protected:
233 inline void
234 inc(false_type)
235 { dec(true_type()); }
237 void
238 inc(true_type)
240 if (m_p_nd->m_type == pat_trie_head_node_type)
242 m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min;
243 return;
246 node_pointer p_y = m_p_nd->m_p_parent;
247 while (p_y->m_type != pat_trie_head_node_type &&
248 get_larger_sibling(m_p_nd) == 0)
250 m_p_nd = p_y;
251 p_y = p_y->m_p_parent;
254 if (p_y->m_type == pat_trie_head_node_type)
256 m_p_nd = p_y;
257 return;
259 m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd));
262 inline void
263 dec(false_type)
264 { inc(true_type()); }
266 void
267 dec(true_type)
269 if (m_p_nd->m_type == pat_trie_head_node_type)
271 m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max;
272 return;
275 node_pointer p_y = m_p_nd->m_p_parent;
276 while (p_y->m_type != pat_trie_head_node_type &&
277 get_smaller_sibling(m_p_nd) == 0)
279 m_p_nd = p_y;
280 p_y = p_y->m_p_parent;
283 if (p_y->m_type == pat_trie_head_node_type)
285 m_p_nd = p_y;
286 return;
288 m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd));
291 inline static node_pointer
292 get_larger_sibling(node_pointer p_nd)
294 internal_node_pointer p_parent =
295 static_cast<internal_node_pointer>(p_nd->m_p_parent);
297 typename Internal_Node::iterator it = p_parent->begin();
298 while (*it != p_nd)
299 ++it;
301 typename Internal_Node::iterator next_it = it;
302 ++next_it;
303 return ((next_it == p_parent->end())? 0 :* next_it);
306 inline static node_pointer
307 get_smaller_sibling(node_pointer p_nd)
309 internal_node_pointer p_parent =
310 static_cast<internal_node_pointer>(p_nd->m_p_parent);
312 typename Internal_Node::iterator it = p_parent->begin();
314 if (*it == p_nd)
315 return (0);
316 typename Internal_Node::iterator prev_it;
319 prev_it = it;
320 ++it;
321 if (*it == p_nd)
322 return (*prev_it);
324 while (true);
326 _GLIBCXX_DEBUG_ASSERT(false);
327 return (0);
330 inline static leaf_pointer
331 leftmost_descendant(node_pointer p_nd)
333 if (p_nd->m_type == pat_trie_leaf_node_type)
334 return static_cast<leaf_pointer>(p_nd);
335 return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant();
338 inline static leaf_pointer
339 rightmost_descendant(node_pointer p_nd)
341 if (p_nd->m_type == pat_trie_leaf_node_type)
342 return static_cast<leaf_pointer>(p_nd);
343 return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant();
346 public:
347 node_pointer m_p_nd;
350 // Iterator.
351 template<typename Type_Traits,
352 class Node,
353 class Leaf,
354 class Head,
355 class Internal_Node,
356 bool Is_Forward_Iterator,
357 class Allocator>
358 class pat_trie_it_ :
359 public PB_DS_CONST_IT_C_DEC
362 private:
363 typedef
364 typename Allocator::template rebind<
365 Node>::other::pointer
366 node_pointer;
368 typedef
369 typename Allocator::template rebind<
370 Leaf>::other::const_pointer
371 const_leaf_pointer;
373 typedef
374 typename Allocator::template rebind<
375 Leaf>::other::pointer
376 leaf_pointer;
378 typedef
379 typename Allocator::template rebind<
380 Head>::other::pointer
381 head_pointer;
383 typedef
384 typename Allocator::template rebind<
385 Internal_Node>::other::pointer
386 internal_node_pointer;
388 public:
389 typedef typename Type_Traits::value_type value_type;
391 typedef typename Type_Traits::const_pointer const_pointer;
393 typedef typename Type_Traits::pointer pointer;
395 typedef typename Type_Traits::const_reference const_reference;
397 typedef typename Type_Traits::reference reference;
399 inline
400 pat_trie_it_(node_pointer p_nd = 0) : PB_DS_CONST_IT_C_DEC((node_pointer)p_nd)
403 inline
404 pat_trie_it_(const PB_DS_ODIR_IT_C_DEC& other) : PB_DS_CONST_IT_C_DEC(other.m_p_nd)
407 inline
408 PB_DS_IT_C_DEC&
409 operator=(const PB_DS_IT_C_DEC& other)
411 base_it_type::m_p_nd = other.m_p_nd;
412 return *this;
415 inline
416 PB_DS_IT_C_DEC&
417 operator=(const PB_DS_ODIR_IT_C_DEC& other)
419 base_it_type::m_p_nd = other.m_p_nd;
420 return *this;
423 inline pointer
424 operator->() const
426 _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type);
428 return &static_cast<leaf_pointer>(base_it_type::m_p_nd)->value();
431 inline reference
432 operator*() const
434 _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type);
435 return static_cast<leaf_pointer>(base_it_type::m_p_nd)->value();
438 inline PB_DS_IT_C_DEC&
439 operator++()
441 PB_DS_CONST_IT_C_DEC::
442 operator++();
443 return *this;
446 inline PB_DS_IT_C_DEC
447 operator++(int)
449 PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd);
450 operator++();
451 return ret_it;
454 inline PB_DS_IT_C_DEC&
455 operator--()
457 PB_DS_CONST_IT_C_DEC::operator--();
458 return *this;
461 inline PB_DS_IT_C_DEC
462 operator--(int)
464 PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd);
465 operator--();
466 return ret_it;
469 protected:
470 typedef PB_DS_CONST_IT_C_DEC base_it_type;
472 friend class PB_DS_CLASS_C_DEC;
475 #undef PB_DS_CONST_IT_C_DEC
476 #undef PB_DS_CONST_ODIR_IT_C_DEC
477 #undef PB_DS_IT_C_DEC
478 #undef PB_DS_ODIR_IT_C_DEC
480 } // namespace detail
481 } // namespace __gnu_pbds
483 #endif