source: trunk/yat/utility/SegmentTree.h @ 2360

Last change on this file since 2360 was 2360, checked in by Peter, 13 years ago

refs #640. adding a functor in SegmentTree? to tranlate a value_type to key_type.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.5 KB
Line 
1#ifndef theplu_yat_utility_segment_tree
2#define theplu_yat_utility_segment_tree
3
4// $Id: SegmentTree.h 2360 2010-12-04 01:04:45Z peter $
5
6/*
7  Copyright (C) 2010 Peter Johansson
8
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "Segment.h"
26
27#include "yat_assert.h"
28
29#include <algorithm>
30#include <functional>
31
32namespace theplu {
33namespace yat {
34namespace utility {
35
36  /**
37     \brief Base Class for SegmentSet and SegmentMap
38
39     - Container: underlying container (set or map)
40     - Compare: functor comparing elements (same as in Segment)
41     - Value2Key: functor translating a \c const_reference to \c
42       key_type (or \c const&)
43   */
44  template<class Container, class Compare, class Value2Key>
45  class SegmentTree
46  {
47  public:
48    /// \brief key type
49    typedef typename Container::key_type key_type;
50    /// \brief value type
51    typedef typename Container::value_type value_type;
52    /// \brief element type
53    typedef typename key_type::value_type element_type;
54
55    /// \brief key compare
56    typedef typename Container::key_compare key_compare;
57    /// \brief calue compare
58    typedef typename Container::value_compare value_compare;
59    /// \brief element compare
60    typedef Compare element_compare;
61
62    /// \brief pointer
63    typedef typename Container::pointer pointer;
64    /// \brief reference
65    typedef typename Container::reference reference;
66    /// \brief const reference
67    typedef typename Container::const_reference const_reference;
68    /// \brief size_type
69    typedef typename Container::size_type size_type;
70    /// \brief difference_type
71    typedef typename Container::difference_type difference_type;
72    /// \brief iterator
73    typedef typename Container::iterator iterator;
74    /// \brief const_iterator
75    typedef typename Container::const_iterator const_iterator;
76
77    /**
78       \brief creates a container with no segments
79     */
80    SegmentTree(void) {}
81
82    /**
83       \return const iterator to first Segment
84     */
85    const_iterator begin(void) const { return container_.begin(); }
86
87    /**
88       \return iterator to first Segment
89     */
90    iterator begin(void) { return container_.begin(); }
91
92    /**
93       \brief erases all segments
94     */
95    void clear(void) { container_.clear(); }
96
97    /**
98       \return 1 if there is a set that overlaps with \a element
99     */
100    size_type count(const element_type& element) const;
101
102    /**
103       \return \c true
104    */
105    bool empty(void) const { return container_.empty(); }
106
107    /**
108       \return end of set
109     */
110    const_iterator end(void) const { return container_.end(); }
111
112    /**
113       \return end of set
114     */
115    iterator end(void) { return container_.end(); }
116
117    /**
118       \return an iterator pointing to the Segment that contains \a
119       vt. If no Segment contains \a vt, end() is returned.
120     */
121    const_iterator find(const element_type& vt) const;
122
123    /**
124       \brief insert set
125
126       if \a segment does not overlap with any segment in set, insert
127       segment; otherwise do nothing.
128
129       \return a pair where pair.first points to the added \a segment
130       or if \a segment was not added it points to a Segment in set
131       that overlaps with \a segment; pair.second is true if \a
132       segment was added.
133     */
134    std::pair<iterator, bool> insert(const value_type& segment);
135
136    /**
137       insert \a segment into set. If there is no gap between \a
138       segment and neighboring segments the segments are merged.
139     */
140    const_iterator insert_merge(const value_type& segment);
141
142    /**
143       \return Comparison functor to compare to segments
144     */
145    key_compare key_comp(void) const 
146    { 
147      return key_compare(compare);
148    }
149
150    /**
151       \return iterator pointing to first segment that overlaps with
152       \a element or is greater than \a element.
153     */
154    iterator lower_bound(const element_type& element);
155
156    /**
157       \return iterator pointing to first segment that overlaps with
158       \a element or is greater than \a element.
159     */
160    const_iterator lower_bound(const element_type& element) const;
161
162    /**
163       \return number of segments in set
164     */
165    size_type size(void) const { return container_.size(); }
166
167    /**
168       \return iterator pointing to first segment that is greater than
169       \a segment.
170     */
171    iterator upper_bound(const element_type& element);
172
173    /**
174       \return iterator pointing to first segment that is greater than
175       \a segment.
176     */
177    const_iterator upper_bound(const element_type& element) const;
178
179    /**
180       \return Comparison functor to compare to segments
181     */
182    value_compare value_comp(void) const { return key_comp(); }
183
184  protected:
185    /// underlying container
186    Container container_;
187
188    /**
189       pair.first first (smallest) segment that overlaps with \a
190       segment and pair.second first (smallest) segment that does not
191       overlap with \a segment.
192     */
193    std::pair<iterator, iterator> overlap_range(const key_type& segment) 
194    {
195      iterator first = container_.lower_bound(segment);
196      if (first!=begin()) {
197        --first;
198        if (compare(*first, segment))
199          ++first;
200      }
201      iterator last = first;
202      while (last!=end() && !compare(segment, *last))
203        ++last;
204      YAT_ASSERT(last==end() || compare(segment, *last));
205      return std::make_pair(first, last);
206    }
207
208    // using compiler generated copying
209    //SegmentTree(const SegmentTree&);
210    //SegmentTree& operator=(const SegmentTree&);
211  };
212
213  template<class Container, class Compare, class Value2Key>
214  typename SegmentTree<Container, Compare, Value2Key>::size_type
215  SegmentTree<Container,Compare,Value2Key>::count(const element_type& element) const
216  {
217    if (find(element)==end())
218      return 0;
219    return 1;
220  }
221
222
223  template<class Container, class Compare, class Value2Key>
224  typename SegmentTree<Container, Compare, Value2Key>::const_iterator
225  SegmentTree<Container, Compare, Value2Key>::find(const element_type& vt) const
226  {
227    const_iterator iter = lower_bound(vt);
228    element_compare comp;
229    //    if (iter==end() || comp(vt, iter->begin()))
230    if (iter==end() || comp(vt, Value2Key()(*iter).begin()))
231      return end();
232    return iter;
233  }
234
235
236  template<typename T, class Compare, class Value2Key>
237  std::pair<typename SegmentTree<T, Compare, Value2Key>::iterator, bool> 
238  SegmentTree<T, Compare,Value2Key>::insert(const value_type& segment)
239  {
240    return container_.insert(segment);
241  }
242
243
244  template<typename T, class Compare, class Value2Key>
245  typename SegmentTree<T, Compare, Value2Key>::iterator
246  SegmentTree<T, Compare,Value2Key>::lower_bound(const element_type& element)
247  {
248    key_type segment(element, element);
249    iterator result = container_.lower_bound(segment);
250    // result is larger or overlapping with segment (i.e.! result<segment)
251    YAT_ASSERT(result==end() 
252               || !compare(Value2Key()(*result),segment));
253    return result;
254  }
255
256
257  template<typename T, class Compare, class Value2Key>
258  typename SegmentTree<T, Compare, Value2Key>::const_iterator
259  SegmentTree<T, Compare,Value2Key>::lower_bound(const element_type& element) const
260  {
261    key_type segment(element, element);
262    const_iterator result = container_.lower_bound(segment);
263    // result is larger or overlapping with segment (i.e.! result<segment)
264    YAT_ASSERT(result==end() 
265               || !compare(Value2Key()(*result),segment));
266    return result;
267  }
268
269
270  template<typename T, class Compare, class Value2Key>
271  typename SegmentTree<T, Compare, Value2Key>::iterator
272  SegmentTree<T, Compare,Value2Key>::upper_bound(const element_type& element)
273  {
274    key_type segment(element, element);
275    iterator result = container_.upper_bound(segment);
276    Compare comp;
277    if (result==end() || comp(element, result->begin()))
278      return result;
279    ++result;
280    // result is larger than segment
281    YAT_ASSERT(result==end() || compare(segment, *result));
282    return result;
283  }
284
285
286  template<typename T, class Compare, class Value2Key>
287  typename SegmentTree<T, Compare, Value2Key>::const_iterator
288  SegmentTree<T, Compare,Value2Key>::upper_bound(const element_type& element) const
289  {
290    Segment<T, Compare> segment(element, element);
291    const_iterator result = container_.upper_bound(segment);
292    Compare comp;
293    if (result==end() || comp(element, result->begin()))
294      return result;
295    ++result;
296    // result is larger than segment
297    YAT_ASSERT(result==end() || compare(segment, *result));
298    return result;
299  }
300
301}}}
302#endif
Note: See TracBrowser for help on using the repository browser.