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 point_iterators.hpp
44169691Skan * Contains an implementation class for bin_search_tree_.
45169691Skan */
46169691Skan
47169691Skan#ifndef PB_DS_PAT_TRIE_FIND_ITERATORS_HPP
48169691Skan#define PB_DS_PAT_TRIE_FIND_ITERATORS_HPP
49169691Skan
50169691Skan#include <debug/debug.h>
51169691Skan
52169691Skannamespace pb_ds
53169691Skan{
54169691Skan  namespace detail
55169691Skan  {
56169691Skan
57169691Skan#define PB_DS_CONST_IT_C_DEC					\
58169691Skan    pat_trie_const_it_<						\
59169691Skan					Type_Traits,		\
60169691Skan					Node,			\
61169691Skan					Leaf,			\
62169691Skan					Head,			\
63169691Skan					Internal_Node,		\
64169691Skan					Is_Forward_Iterator,	\
65169691Skan					Allocator>
66169691Skan
67169691Skan#define PB_DS_CONST_ODIR_IT_C_DEC				\
68169691Skan    pat_trie_const_it_<						\
69169691Skan					Type_Traits,		\
70169691Skan					Node,			\
71169691Skan					Leaf,			\
72169691Skan					Head,			\
73169691Skan					Internal_Node,		\
74169691Skan					!Is_Forward_Iterator,	\
75169691Skan					Allocator>
76169691Skan
77169691Skan#define PB_DS_IT_C_DEC							\
78169691Skan    pat_trie_it_<							\
79169691Skan						Type_Traits,		\
80169691Skan						Node,			\
81169691Skan						Leaf,			\
82169691Skan						Head,			\
83169691Skan						Internal_Node,		\
84169691Skan						Is_Forward_Iterator,	\
85169691Skan						Allocator>
86169691Skan
87169691Skan#define PB_DS_ODIR_IT_C_DEC						\
88169691Skan    pat_trie_it_<							\
89169691Skan						Type_Traits,		\
90169691Skan						Node,			\
91169691Skan						Leaf,			\
92169691Skan						Head,			\
93169691Skan						Internal_Node,		\
94169691Skan						!Is_Forward_Iterator,	\
95169691Skan						Allocator>
96169691Skan
97169691Skan
98169691Skan    // Const iterator.
99169691Skan    template<typename Type_Traits,
100169691Skan	     class Node,
101169691Skan	     class Leaf,
102169691Skan	     class Head,
103169691Skan	     class Internal_Node,
104169691Skan	     bool Is_Forward_Iterator,
105169691Skan	     class Allocator>
106169691Skan    class pat_trie_const_it_
107169691Skan    {
108169691Skan
109169691Skan    private:
110169691Skan      typedef
111169691Skan      typename Allocator::template rebind<
112169691Skan      Node>::other::pointer
113169691Skan      node_pointer;
114169691Skan
115169691Skan      typedef
116169691Skan      typename Allocator::template rebind<
117169691Skan	Leaf>::other::const_pointer
118169691Skan      const_leaf_pointer;
119169691Skan
120169691Skan      typedef
121169691Skan      typename Allocator::template rebind<
122169691Skan	Leaf>::other::pointer
123169691Skan      leaf_pointer;
124169691Skan
125169691Skan      typedef
126169691Skan      typename Allocator::template rebind<
127169691Skan	Head>::other::pointer
128169691Skan      head_pointer;
129169691Skan
130169691Skan      typedef
131169691Skan      typename Allocator::template rebind<
132169691Skan	Internal_Node>::other::pointer
133169691Skan      internal_node_pointer;
134169691Skan
135169691Skan    public:
136169691Skan
137169691Skan      typedef std::bidirectional_iterator_tag iterator_category;
138169691Skan
139169691Skan      typedef typename Allocator::difference_type difference_type;
140169691Skan
141169691Skan      typedef typename Type_Traits::value_type value_type;
142169691Skan
143169691Skan      typedef typename Type_Traits::pointer pointer;
144169691Skan
145169691Skan      typedef typename Type_Traits::const_pointer const_pointer;
146169691Skan
147169691Skan      typedef typename Type_Traits::reference reference;
148169691Skan
149169691Skan      typedef typename Type_Traits::const_reference const_reference;
150169691Skan
151169691Skan    public:
152169691Skan
153169691Skan      inline
154169691Skan      pat_trie_const_it_(node_pointer p_nd = NULL) : m_p_nd(p_nd)
155169691Skan      { }
156169691Skan
157169691Skan      inline
158169691Skan      pat_trie_const_it_(const PB_DS_CONST_ODIR_IT_C_DEC& other)
159169691Skan      : m_p_nd(other.m_p_nd)
160169691Skan      { }
161169691Skan
162169691Skan      inline
163169691Skan      PB_DS_CONST_IT_C_DEC&
164169691Skan      operator=(const PB_DS_CONST_IT_C_DEC& other)
165169691Skan      {
166169691Skan	m_p_nd = other.m_p_nd;
167169691Skan	return *this;
168169691Skan      }
169169691Skan
170169691Skan      inline
171169691Skan      PB_DS_CONST_IT_C_DEC&
172169691Skan      operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other)
173169691Skan      {
174169691Skan	m_p_nd = other.m_p_nd;
175169691Skan	return *this;
176169691Skan      }
177169691Skan
178169691Skan      inline const_pointer
179169691Skan      operator->() const
180169691Skan      {
181169691Skan	_GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type);
182169691Skan	return &static_cast<leaf_pointer>(m_p_nd)->value();
183169691Skan      }
184169691Skan
185169691Skan      inline const_reference
186169691Skan      operator*() const
187169691Skan      {
188169691Skan	_GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type);
189169691Skan	return static_cast<leaf_pointer>(m_p_nd)->value();
190169691Skan      }
191169691Skan
192169691Skan      inline bool
193169691Skan      operator==(const PB_DS_CONST_IT_C_DEC& other) const
194169691Skan      { return (m_p_nd == other.m_p_nd); }
195169691Skan
196169691Skan      inline bool
197169691Skan      operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
198169691Skan      { return (m_p_nd == other.m_p_nd); }
199169691Skan
200169691Skan      inline bool
201169691Skan      operator!=(const PB_DS_CONST_IT_C_DEC& other) const
202169691Skan      { return (m_p_nd != other.m_p_nd); }
203169691Skan
204169691Skan      inline bool
205169691Skan      operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
206169691Skan      { return (m_p_nd != other.m_p_nd); }
207169691Skan
208169691Skan      inline PB_DS_CONST_IT_C_DEC&
209169691Skan      operator++()
210169691Skan      {
211169691Skan	inc(integral_constant<int,Is_Forward_Iterator>());
212169691Skan	return *this;
213169691Skan      }
214169691Skan
215169691Skan      inline PB_DS_CONST_IT_C_DEC
216169691Skan      operator++(int)
217169691Skan      {
218169691Skan	PB_DS_CONST_IT_C_DEC ret_it(m_p_nd);
219169691Skan	operator++();
220169691Skan	return ret_it;
221169691Skan      }
222169691Skan
223169691Skan      inline PB_DS_CONST_IT_C_DEC&
224169691Skan      operator--()
225169691Skan      {
226169691Skan	dec(integral_constant<int,Is_Forward_Iterator>());
227169691Skan	return *this;
228169691Skan      }
229169691Skan
230169691Skan      inline PB_DS_CONST_IT_C_DEC
231169691Skan      operator--(int)
232169691Skan      {
233169691Skan	PB_DS_CONST_IT_C_DEC ret_it(m_p_nd);
234169691Skan	operator--();
235169691Skan	return ret_it;
236169691Skan      }
237169691Skan
238169691Skan    protected:
239169691Skan      inline void
240169691Skan      inc(false_type)
241169691Skan      { dec(true_type()); }
242169691Skan
243169691Skan      void
244169691Skan      inc(true_type)
245169691Skan      {
246169691Skan	if (m_p_nd->m_type == pat_trie_head_node_type)
247169691Skan	  {
248169691Skan	    m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min;
249169691Skan	    return;
250169691Skan	  }
251169691Skan
252169691Skan	node_pointer p_y = m_p_nd->m_p_parent;
253169691Skan	while (p_y->m_type != pat_trie_head_node_type &&
254169691Skan	       get_larger_sibling(m_p_nd) == NULL)
255169691Skan	  {
256169691Skan	    m_p_nd = p_y;
257169691Skan	    p_y = p_y->m_p_parent;
258169691Skan	  }
259169691Skan
260169691Skan	if (p_y->m_type == pat_trie_head_node_type)
261169691Skan	  {
262169691Skan	    m_p_nd = p_y;
263169691Skan	    return;
264169691Skan	  }
265169691Skan	m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd));
266169691Skan      }
267169691Skan
268169691Skan      inline void
269169691Skan      dec(false_type)
270169691Skan      { inc(true_type()); }
271169691Skan
272169691Skan      void
273169691Skan      dec(true_type)
274169691Skan      {
275169691Skan	if (m_p_nd->m_type == pat_trie_head_node_type)
276169691Skan	  {
277169691Skan	    m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max;
278169691Skan	    return;
279169691Skan	  }
280169691Skan
281169691Skan	node_pointer p_y = m_p_nd->m_p_parent;
282169691Skan	while (p_y->m_type != pat_trie_head_node_type &&
283169691Skan	       get_smaller_sibling(m_p_nd) == NULL)
284169691Skan	  {
285169691Skan	    m_p_nd = p_y;
286169691Skan	    p_y = p_y->m_p_parent;
287169691Skan	  }
288169691Skan
289169691Skan	if (p_y->m_type == pat_trie_head_node_type)
290169691Skan	  {
291169691Skan	    m_p_nd = p_y;
292169691Skan	    return;
293169691Skan	  }
294169691Skan	m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd));
295169691Skan      }
296169691Skan
297169691Skan      inline static node_pointer
298169691Skan      get_larger_sibling(node_pointer p_nd)
299169691Skan      {
300169691Skan	internal_node_pointer p_parent =
301169691Skan	  static_cast<internal_node_pointer>(p_nd->m_p_parent);
302169691Skan
303169691Skan	typename Internal_Node::iterator it = p_parent->begin();
304169691Skan	while (*it != p_nd)
305169691Skan	  ++it;
306169691Skan
307169691Skan	typename Internal_Node::iterator next_it = it;
308169691Skan	++next_it;
309169691Skan	return ((next_it == p_parent->end())? NULL :* next_it);
310169691Skan      }
311169691Skan
312169691Skan      inline static node_pointer
313169691Skan      get_smaller_sibling(node_pointer p_nd)
314169691Skan      {
315169691Skan	internal_node_pointer p_parent =
316169691Skan	  static_cast<internal_node_pointer>(p_nd->m_p_parent);
317169691Skan
318169691Skan	typename Internal_Node::iterator it = p_parent->begin();
319169691Skan
320169691Skan	if (*it == p_nd)
321169691Skan	  return (NULL);
322169691Skan	typename Internal_Node::iterator prev_it;
323169691Skan	do
324169691Skan	  {
325169691Skan	    prev_it = it;
326169691Skan	    ++it;
327169691Skan	    if (*it == p_nd)
328169691Skan	      return (*prev_it);
329169691Skan	  }
330169691Skan	while (true);
331169691Skan
332169691Skan	_GLIBCXX_DEBUG_ASSERT(false);
333169691Skan	return (NULL);
334169691Skan      }
335169691Skan
336169691Skan      inline static leaf_pointer
337169691Skan      leftmost_descendant(node_pointer p_nd)
338169691Skan      {
339169691Skan	if (p_nd->m_type == pat_trie_leaf_node_type)
340169691Skan	  return static_cast<leaf_pointer>(p_nd);
341169691Skan	return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant();
342169691Skan      }
343169691Skan
344169691Skan      inline static leaf_pointer
345169691Skan      rightmost_descendant(node_pointer p_nd)
346169691Skan      {
347169691Skan	if (p_nd->m_type == pat_trie_leaf_node_type)
348169691Skan	  return static_cast<leaf_pointer>(p_nd);
349169691Skan	return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant();
350169691Skan      }
351169691Skan
352169691Skan    public:
353169691Skan      node_pointer m_p_nd;
354169691Skan    };
355169691Skan
356169691Skan    // Iterator.
357169691Skan    template<typename Type_Traits,
358169691Skan	     class Node,
359169691Skan	     class Leaf,
360169691Skan	     class Head,
361169691Skan	     class Internal_Node,
362169691Skan	     bool Is_Forward_Iterator,
363169691Skan	     class Allocator>
364169691Skan    class pat_trie_it_ :
365169691Skan      public PB_DS_CONST_IT_C_DEC
366169691Skan
367169691Skan    {
368169691Skan    private:
369169691Skan      typedef
370169691Skan      typename Allocator::template rebind<
371169691Skan      Node>::other::pointer
372169691Skan      node_pointer;
373169691Skan
374169691Skan      typedef
375169691Skan      typename Allocator::template rebind<
376169691Skan	Leaf>::other::const_pointer
377169691Skan      const_leaf_pointer;
378169691Skan
379169691Skan      typedef
380169691Skan      typename Allocator::template rebind<
381169691Skan	Leaf>::other::pointer
382169691Skan      leaf_pointer;
383169691Skan
384169691Skan      typedef
385169691Skan      typename Allocator::template rebind<
386169691Skan	Head>::other::pointer
387169691Skan      head_pointer;
388169691Skan
389169691Skan      typedef
390169691Skan      typename Allocator::template rebind<
391169691Skan	Internal_Node>::other::pointer
392169691Skan      internal_node_pointer;
393169691Skan
394169691Skan    public:
395169691Skan      typedef typename Type_Traits::value_type value_type;
396169691Skan
397169691Skan      typedef typename Type_Traits::const_pointer const_pointer;
398169691Skan
399169691Skan      typedef typename Type_Traits::pointer pointer;
400169691Skan
401169691Skan      typedef typename Type_Traits::const_reference const_reference;
402169691Skan
403169691Skan      typedef typename Type_Traits::reference reference;
404169691Skan
405169691Skan      inline
406169691Skan      pat_trie_it_(node_pointer p_nd = NULL) : PB_DS_CONST_IT_C_DEC((node_pointer)p_nd)
407169691Skan      { }
408169691Skan
409169691Skan      inline
410169691Skan      pat_trie_it_(const PB_DS_ODIR_IT_C_DEC& other) : PB_DS_CONST_IT_C_DEC(other.m_p_nd)
411169691Skan      { }
412169691Skan
413169691Skan      inline
414169691Skan      PB_DS_IT_C_DEC&
415169691Skan      operator=(const PB_DS_IT_C_DEC& other)
416169691Skan      {
417169691Skan	base_it_type::m_p_nd = other.m_p_nd;
418169691Skan	return *this;
419169691Skan      }
420169691Skan
421169691Skan      inline
422169691Skan      PB_DS_IT_C_DEC&
423169691Skan      operator=(const PB_DS_ODIR_IT_C_DEC& other)
424169691Skan      {
425169691Skan	base_it_type::m_p_nd = other.m_p_nd;
426169691Skan	return *this;
427169691Skan      }
428169691Skan
429169691Skan      inline pointer
430169691Skan      operator->() const
431169691Skan      {
432169691Skan	_GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type);
433169691Skan
434169691Skan	return &static_cast<leaf_pointer>(base_it_type::m_p_nd)->value();
435169691Skan      }
436169691Skan
437169691Skan      inline reference
438169691Skan      operator*() const
439169691Skan      {
440169691Skan	_GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type);
441169691Skan	return static_cast<leaf_pointer>(base_it_type::m_p_nd)->value();
442169691Skan      }
443169691Skan
444169691Skan      inline PB_DS_IT_C_DEC&
445169691Skan      operator++()
446169691Skan      {
447169691Skan	PB_DS_CONST_IT_C_DEC::
448169691Skan	  operator++();
449169691Skan	return *this;
450169691Skan      }
451169691Skan
452169691Skan      inline PB_DS_IT_C_DEC
453169691Skan      operator++(int)
454169691Skan      {
455169691Skan	PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd);
456169691Skan	operator++();
457169691Skan	return ret_it;
458169691Skan      }
459169691Skan
460169691Skan      inline PB_DS_IT_C_DEC&
461169691Skan      operator--()
462169691Skan      {
463169691Skan	PB_DS_CONST_IT_C_DEC::operator--();
464169691Skan	return *this;
465169691Skan      }
466169691Skan
467169691Skan      inline PB_DS_IT_C_DEC
468169691Skan      operator--(int)
469169691Skan      {
470169691Skan	PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd);
471169691Skan	operator--();
472169691Skan	return ret_it;
473169691Skan      }
474169691Skan
475169691Skan    protected:
476169691Skan      typedef PB_DS_CONST_IT_C_DEC base_it_type;
477169691Skan
478169691Skan      friend class PB_DS_CLASS_C_DEC;
479169691Skan    };
480169691Skan
481169691Skan#undef PB_DS_CONST_IT_C_DEC
482169691Skan#undef PB_DS_CONST_ODIR_IT_C_DEC
483169691Skan#undef PB_DS_IT_C_DEC
484169691Skan#undef PB_DS_ODIR_IT_C_DEC
485169691Skan
486169691Skan  } // namespace detail
487169691Skan} // namespace pb_ds
488169691Skan
489169691Skan#endif
490169691Skan
491