1// -*- C++ -*-
2
3// Copyright (C) 2005 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
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING.  If not, write to the Free
18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction.  Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License.  This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
31
32// Permission to use, copy, modify, sell, and distribute this software
33// is hereby granted without fee, provided that the above copyright
34// notice appears in all copies, and that both that copyright notice and
35// this permission notice appear in supporting documentation. None of
36// the above authors, nor IBM Haifa Research Laboratories, make any
37// representation about the suitability of this software for any
38// purpose. It is provided "as is" without express or implied warranty.
39
40/**
41 * @file constructors_destructor_fn_imps.hpp
42 * Contains an implementation class for ov_tree_.
43 */
44
45PB_ASSOC_CLASS_T_DEC
46typename PB_ASSOC_CLASS_C_DEC::value_allocator
47PB_ASSOC_CLASS_C_DEC::s_alloc;
48
49PB_ASSOC_CLASS_T_DEC
50PB_ASSOC_CLASS_C_DEC::
51PB_ASSOC_OV_TREE_CLASS_NAME() :
52  m_a_values(NULL),
53  m_end_it(NULL),
54  m_size(0)
55{
56  update(node_begin(), (Node_Updator* )this);
57
58  PB_ASSOC_DBG_ONLY(PB_ASSOC_CLASS_C_DEC::assert_valid();)
59    }
60
61PB_ASSOC_CLASS_T_DEC
62PB_ASSOC_CLASS_C_DEC::
63PB_ASSOC_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn) :
64  my_cmp_fn_base(r_cmp_fn),
65  m_a_values(NULL),
66  m_end_it(NULL),
67  m_size(0)
68{
69  update(node_begin(), (Node_Updator* )this);
70
71  PB_ASSOC_DBG_ONLY(PB_ASSOC_CLASS_C_DEC::assert_valid();)
72    }
73
74PB_ASSOC_CLASS_T_DEC
75PB_ASSOC_CLASS_C_DEC::
76PB_ASSOC_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const Node_Updator& r_node_updator) :
77  my_cmp_fn_base(r_cmp_fn),
78  Node_Updator(r_node_updator),
79  m_a_values(NULL),
80  m_end_it(NULL),
81  m_size(0)
82{
83  update(node_begin(), (Node_Updator* )this);
84
85  PB_ASSOC_DBG_ONLY(PB_ASSOC_CLASS_C_DEC::assert_valid();)
86    }
87
88PB_ASSOC_CLASS_T_DEC
89PB_ASSOC_CLASS_C_DEC::
90PB_ASSOC_OV_TREE_CLASS_NAME(const PB_ASSOC_CLASS_C_DEC& r_other) :
91  my_cmp_fn_base(r_other),
92  m_a_values(NULL),
93  m_end_it(NULL),
94  m_size(0)
95{
96  copy_from_ordered_range(r_other.begin(), r_other.end());
97
98  PB_ASSOC_DBG_ONLY(PB_ASSOC_CLASS_C_DEC::assert_valid();)
99    }
100
101PB_ASSOC_CLASS_T_DEC
102template<class It>
103inline void
104PB_ASSOC_CLASS_C_DEC::
105copy_from_range(It first_it, It last_it)
106{
107  enum
108    {
109      is_set_type = is_same_type<Data, null_data_type>::value
110    };
111
112  typedef
113    typename cond_type<
114    is_set_type,
115    std::set<
116    Key,
117    Cmp_Fn,
118    typename Allocator::template rebind<
119    Key>::other>,
120    std::map<
121    Key,
122    Data,
123    Cmp_Fn,
124    typename Allocator::template rebind<
125    std::pair<const Key, Data> >::other> >::type
126    map_type;
127
128  map_type m(first_it, last_it);
129
130  copy_from_ordered_range(m.begin(), m.end());
131}
132
133PB_ASSOC_CLASS_T_DEC
134template<class It>
135void
136PB_ASSOC_CLASS_C_DEC::
137copy_from_ordered_range(It first_it, It last_it)
138{
139  clear();
140
141  const size_type size = std::distance(first_it, last_it);
142
143  pointer a_values = s_alloc.allocate(size);
144
145  iterator target_it = a_values;
146  It source_it = first_it;
147  It source_end_it = last_it;
148
149  cond_dtor cd(a_values, target_it, size);
150
151  while (source_it != source_end_it)
152    {
153      new (const_cast<void* >(
154			      static_cast<const void* >(target_it)))
155	value_type(*source_it++);
156
157      ++target_it;
158    }
159
160  cd.set_no_action();
161
162  m_a_values = a_values;
163
164  m_size = size;
165
166  m_end_it = m_a_values + m_size;
167
168  update(node_begin(), (Node_Updator* )this);
169
170#ifdef PB_ASSOC_OV_TREE_DEBUG_
171  const_iterator dbg_it = m_a_values;
172
173  while (dbg_it != m_end_it)
174    {
175      my_map_debug_base::insert_new(PB_ASSOC_V2F(*dbg_it));
176
177      dbg_it++;
178    }
179
180  PB_ASSOC_CLASS_C_DEC::assert_valid();
181#endif // #ifdef PB_ASSOC_OV_TREE_DEBUG_
182}
183
184PB_ASSOC_CLASS_T_DEC
185template<class It>
186void
187PB_ASSOC_CLASS_C_DEC::
188copy_from_ordered_range(It first_it, It last_it, It other_first_it, It other_last_it)
189{
190  clear();
191
192  const size_type size =
193    std::distance(first_it, last_it) +
194    std::distance(other_first_it, other_last_it);
195
196  pointer a_values = s_alloc.allocate(size);
197
198  iterator target_it = a_values;
199  It source_it = first_it;
200  It source_end_it = last_it;
201
202  cond_dtor cd(a_values, target_it, size);
203
204  while (source_it != source_end_it)
205    {
206      new (const_cast<void* >(
207			      static_cast<const void* >(target_it)))
208	value_type(*source_it++);
209
210      ++target_it;
211    }
212
213  source_it = other_first_it;
214  source_end_it = other_last_it;
215
216  while (source_it != source_end_it)
217    {
218      new (const_cast<void* >(
219			      static_cast<const void* >(target_it)))
220	value_type(*source_it++);
221
222      ++target_it;
223    }
224
225  cd.set_no_action();
226
227  m_a_values = a_values;
228
229  m_size = size;
230
231  m_end_it = m_a_values + m_size;
232
233  update(node_begin(), (Node_Updator* )this);
234
235#ifdef PB_ASSOC_OV_TREE_DEBUG_
236  const_iterator dbg_it = m_a_values;
237
238  while (dbg_it != m_end_it)
239    {
240      my_map_debug_base::insert_new(PB_ASSOC_V2F(*dbg_it));
241
242      dbg_it++;
243    }
244
245  PB_ASSOC_CLASS_C_DEC::assert_valid();
246#endif // #ifdef PB_ASSOC_OV_TREE_DEBUG_
247}
248
249PB_ASSOC_CLASS_T_DEC
250void
251PB_ASSOC_CLASS_C_DEC::
252swap(PB_ASSOC_CLASS_C_DEC& r_other)
253{
254  PB_ASSOC_DBG_ONLY(assert_valid();)
255
256    std::swap(m_a_values, r_other.m_a_values);
257
258  std::swap(m_size, r_other.m_size);
259
260  std::swap(m_end_it, r_other.m_end_it);
261
262  std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )r_other);
263
264  Node_Updator::swap(r_other);
265
266  PB_ASSOC_DBG_ONLY(my_map_debug_base::swap(r_other);)
267
268    PB_ASSOC_DBG_ONLY(assert_valid();)
269    }
270
271PB_ASSOC_CLASS_T_DEC
272PB_ASSOC_CLASS_C_DEC::
273~PB_ASSOC_OV_TREE_CLASS_NAME()
274{
275  PB_ASSOC_DBG_ONLY(assert_valid();)
276
277    cond_dtor cd(m_a_values, m_end_it, m_size);
278}
279