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 rc.hpp
44169691Skan * Contains a redundant (binary counter).
45169691Skan */
46169691Skan
47169691Skan#ifndef PB_DS_RC_HPP
48169691Skan#define PB_DS_RC_HPP
49169691Skan
50169691Skannamespace pb_ds
51169691Skan{
52169691Skan  namespace detail
53169691Skan  {
54169691Skan
55169691Skan#define PB_DS_CLASS_T_DEC \
56169691Skan    template<typename Node, class Allocator>
57169691Skan
58169691Skan#define PB_DS_CLASS_C_DEC \
59169691Skan    rc<Node, Allocator>
60169691Skan
61169691Skan    template<typename Node, class Allocator>
62169691Skan    class rc
63169691Skan    {
64169691Skan    private:
65169691Skan      typedef Allocator allocator;
66169691Skan
67169691Skan      typedef typename allocator::size_type size_type;
68169691Skan
69169691Skan      typedef Node node;
70169691Skan
71169691Skan      typedef
72169691Skan      typename allocator::template rebind<
73169691Skan	node>::other::pointer
74169691Skan      node_pointer;
75169691Skan
76169691Skan      typedef
77169691Skan      typename allocator::template rebind<
78169691Skan	node_pointer>::other::pointer
79169691Skan      entry_pointer;
80169691Skan
81169691Skan      typedef
82169691Skan      typename allocator::template rebind<
83169691Skan	node_pointer>::other::const_pointer
84169691Skan      const_entry_pointer;
85169691Skan
86169691Skan      enum
87169691Skan	{
88169691Skan	  max_entries = sizeof(size_type) << 3
89169691Skan	};
90169691Skan
91169691Skan    public:
92169691Skan      typedef node_pointer entry;
93169691Skan
94169691Skan      typedef const_entry_pointer const_iterator;
95169691Skan
96169691Skan    public:
97169691Skan      rc();
98169691Skan
99169691Skan      rc(const PB_DS_CLASS_C_DEC& other);
100169691Skan
101169691Skan      inline void
102169691Skan      swap(PB_DS_CLASS_C_DEC& other);
103169691Skan
104169691Skan      inline void
105169691Skan      push(entry p_nd);
106169691Skan
107169691Skan      inline node_pointer
108169691Skan      top() const;
109169691Skan
110169691Skan      inline void
111169691Skan      pop();
112169691Skan
113169691Skan      inline bool
114169691Skan      empty() const;
115169691Skan
116169691Skan      inline size_type
117169691Skan      size() const;
118169691Skan
119169691Skan      void
120169691Skan      clear();
121169691Skan
122169691Skan      const const_iterator
123169691Skan      begin() const;
124169691Skan
125169691Skan      const const_iterator
126169691Skan      end() const;
127169691Skan
128169691Skan#ifdef _GLIBCXX_DEBUG
129169691Skan      void
130169691Skan      assert_valid() const;
131169691Skan#endif
132169691Skan
133169691Skan#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_
134169691Skan      void
135169691Skan      trace() const;
136169691Skan#endif
137169691Skan
138169691Skan    private:
139169691Skan      node_pointer m_a_entries[max_entries];
140169691Skan
141169691Skan      size_type m_over_top;
142169691Skan    };
143169691Skan
144169691Skan    PB_DS_CLASS_T_DEC
145169691Skan    PB_DS_CLASS_C_DEC::
146169691Skan    rc() : m_over_top(0)
147169691Skan    { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
148169691Skan
149169691Skan    PB_DS_CLASS_T_DEC
150169691Skan    PB_DS_CLASS_C_DEC::
151169691Skan    rc(const PB_DS_CLASS_C_DEC& other) : m_over_top(0)
152169691Skan    { _GLIBCXX_DEBUG_ONLY(assert_valid();) }
153169691Skan
154169691Skan    PB_DS_CLASS_T_DEC
155169691Skan    inline void
156169691Skan    PB_DS_CLASS_C_DEC::
157169691Skan    swap(PB_DS_CLASS_C_DEC& other)
158169691Skan    {
159169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
160169691Skan      _GLIBCXX_DEBUG_ONLY(other.assert_valid();)
161169691Skan
162169691Skan      const size_type over_top = std::max(m_over_top, other.m_over_top);
163169691Skan
164169691Skan      for (size_type i = 0; i < over_top; ++i)
165169691Skan	std::swap(m_a_entries[i], other.m_a_entries[i]);
166169691Skan
167169691Skan      std::swap(m_over_top, other.m_over_top);
168169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
169169691Skan      _GLIBCXX_DEBUG_ONLY(other.assert_valid();)
170169691Skan     }
171169691Skan
172169691Skan    PB_DS_CLASS_T_DEC
173169691Skan    inline void
174169691Skan    PB_DS_CLASS_C_DEC::
175169691Skan    push(entry p_nd)
176169691Skan    {
177169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
178169691Skan      _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries);
179169691Skan      m_a_entries[m_over_top++] = p_nd;
180169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
181169691Skan    }
182169691Skan
183169691Skan    PB_DS_CLASS_T_DEC
184169691Skan    inline void
185169691Skan    PB_DS_CLASS_C_DEC::
186169691Skan    pop()
187169691Skan    {
188169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
189169691Skan      _GLIBCXX_DEBUG_ASSERT(!empty());
190169691Skan      --m_over_top;
191169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
192169691Skan    }
193169691Skan
194169691Skan    PB_DS_CLASS_T_DEC
195169691Skan    inline typename PB_DS_CLASS_C_DEC::node_pointer
196169691Skan    PB_DS_CLASS_C_DEC::
197169691Skan    top() const
198169691Skan    {
199169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
200169691Skan      _GLIBCXX_DEBUG_ASSERT(!empty());
201169691Skan      return *(m_a_entries + m_over_top - 1);
202169691Skan    }
203169691Skan
204169691Skan    PB_DS_CLASS_T_DEC
205169691Skan    inline bool
206169691Skan    PB_DS_CLASS_C_DEC::
207169691Skan    empty() const
208169691Skan    {
209169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
210169691Skan      return m_over_top == 0;
211169691Skan    }
212169691Skan
213169691Skan    PB_DS_CLASS_T_DEC
214169691Skan    inline typename PB_DS_CLASS_C_DEC::size_type
215169691Skan    PB_DS_CLASS_C_DEC::
216169691Skan    size() const
217169691Skan    { return m_over_top; }
218169691Skan
219169691Skan    PB_DS_CLASS_T_DEC
220169691Skan    void
221169691Skan    PB_DS_CLASS_C_DEC::
222169691Skan    clear()
223169691Skan    {
224169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
225169691Skan      m_over_top = 0;
226169691Skan      _GLIBCXX_DEBUG_ONLY(assert_valid();)
227169691Skan    }
228169691Skan
229169691Skan    PB_DS_CLASS_T_DEC
230169691Skan    const typename PB_DS_CLASS_C_DEC::const_iterator
231169691Skan    PB_DS_CLASS_C_DEC::
232169691Skan    begin() const
233169691Skan    { return& m_a_entries[0]; }
234169691Skan
235169691Skan    PB_DS_CLASS_T_DEC
236169691Skan    const typename PB_DS_CLASS_C_DEC::const_iterator
237169691Skan    PB_DS_CLASS_C_DEC::
238169691Skan    end() const
239169691Skan    { return& m_a_entries[m_over_top]; }
240169691Skan
241169691Skan#ifdef _GLIBCXX_DEBUG
242169691Skan    PB_DS_CLASS_T_DEC
243169691Skan    void
244169691Skan    PB_DS_CLASS_C_DEC::
245169691Skan    assert_valid() const
246169691Skan    { _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); }
247169691Skan#endif
248169691Skan
249169691Skan#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_
250169691Skan    PB_DS_CLASS_T_DEC
251169691Skan    void
252169691Skan    PB_DS_CLASS_C_DEC::
253169691Skan    trace() const
254169691Skan    {
255169691Skan      std::cout << "rc" << std::endl;
256169691Skan      for (size_type i = 0; i < m_over_top; ++i)
257169691Skan	std::cerr << m_a_entries[i] << std::endl;
258169691Skan      std::cout << std::endl;
259169691Skan    }
260169691Skan#endif
261169691Skan
262169691Skan#undef PB_DS_CLASS_T_DEC
263169691Skan#undef PB_DS_CLASS_C_DEC
264169691Skan
265169691Skan} // namespace detail
266169691Skan} // namespace pb_ds
267169691Skan
268169691Skan#endif
269