yat  0.21pre
SegmentSet.h
1 #ifndef theplu_yat_utility_segment_set
2 #define theplu_yat_utility_segment_set
3 
4 // $Id: SegmentSet.h 4039 2021-02-11 07:30:04Z peter $
5 
6 /*
7  Copyright (C) 2010 Peter Johansson
8  Copyright (C) 2012 Jari Häkkinen
9  Copyright (C) 2014, 2016, 2021 Peter Johansson
10 
11  This file is part of the yat library, http://dev.thep.lu.se/yat
12 
13  The yat library is free software; you can redistribute it and/or
14  modify it under the terms of the GNU General Public License as
15  published by the Free Software Foundation; either version 3 of the
16  License, or (at your option) any later version.
17 
18  The yat library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with yat. If not, see <http://www.gnu.org/licenses/>.
25 */
26 
27 #include "Segment.h"
28 #include "SegmentTree.h"
29 #include "stl_utility.h"
30 #include "yat_assert.h"
31 
32 #include <set>
33 #include <utility>
34 
35 namespace theplu {
36 namespace yat {
37 namespace utility {
38 
46  template<typename T, class Compare = std::less<T> >
47  class SegmentSet
48  : public SegmentTree<std::set<Segment<T, Compare>,
49  SegmentCompare<T, Compare> >,
50  Compare,
51  Identity<const Segment<T, Compare>&> >
52  {
53  typedef SegmentSet<T, Compare> me;
54  public:
58  SegmentSet(void) {}
59 
64  typename me::const_iterator
66  {
67  std::pair<typename me::iterator, typename me::iterator> p =
68  this->overlap_range(segment);
69  Segment<T> tmp(segment);
70  return move_insert_merge(p, std::move(tmp));
71  }
72 
79  typename me::const_iterator
81  {
82  std::pair<typename me::iterator, typename me::iterator> p =
83  this->overlap_range(segment);
84  return move_insert_merge(p, std::move(segment));
85  }
86 
97  typename me::iterator insert_merge(typename me::iterator hint,
98  const Segment<T, Compare>& segment)
99  {
100  Segment<T, Compare> tmp(segment);
101  return insert_merge(hint, std::move(tmp));
102  }
103 
104 
108  typename me::iterator
109  insert_merge(typename me::iterator hint,
110  Segment<T, Compare>&& segment)
111  {
112  std::pair<typename me::iterator, typename me::iterator> p(hint, hint);
113  if (this->container_.empty())
114  return move_insert_merge(p, std::move(segment));
115 
116  // If hint points to an element that is less than segment, hint
117  // is no good and we ignore the hint.
118  if (hint!=this->end() && compare(*hint, segment))
119  return insert_merge(std::move(segment));
120 
121  if (p.first!=this->begin()) {
122  --p.first;
123  // If --hint point to an element greater than segment, hint is
124  // no good.
125  if (compare(segment, *p.first))
126  return insert_merge(std::move(segment));
127  // find first element that is smaller than segment
128  while (p.first!=this->begin() && !compare(*p.first, segment))
129  --p.first;
130  YAT_ASSERT(p.first==this->begin() || compare(*p.first, segment));
131  YAT_ASSERT(p.first!=this->end());
132  if (compare(*p.first, segment))
133  ++p.first;
134  }
135 
136  // find first element greater than segment
137  while (p.second!=this->end() && !compare(segment, *p.second))
138  ++p.second;
139 
140  return move_insert_merge(p, std::move(segment));
141  }
142 
143 
152  template<typename Iterator>
153  void insert_merge(Iterator first, Iterator last)
154  {
155  typename me::iterator it = this->end();
156  for ( ; first!=last; ++first) {
157  it = insert_merge(it, *first);
158  ++it;
159  }
160  }
161  private:
162  // used by functions merge_basic. This function does the actual
163  // work. Note that it takes an rvalue; functions that only have
164  // access to an lvalue const& need to create a (temporary) copy
165  // that can be moved in.
166  //
167  // p.first points to the first segment that overlaps with \a segment or
168  // is greater than segment.
169  // p.second points to the first segment that is greater than \a segment
170  typename me::const_iterator
171  move_insert_merge(const std::pair<typename me::iterator,
172  typename me::iterator>& p,
173  Segment<T, Compare>&& segment)
174  {
175  YAT_ASSERT(p.first==this->end() || !compare(*p.first, segment));
176  YAT_ASSERT(p.second==this->end() || compare(segment, *p.second));
177  if (p.first==p.second) { // no overlap between set and segment
178  return this->container_.insert(p.first, std::move(segment));
179  }
180  /*
181  p.first last p.second
182  ---> ---> ---> --->
183 
184  ----------------------->
185  segment
186  */
187  Compare comp;
188  typename me::iterator last=p.second;
189  YAT_ASSERT(last==this->end() || compare(segment, *last));
190  YAT_ASSERT(last!=this->begin()); // last!=p.first
191  --last;
192  YAT_ASSERT(compare_3way(segment, *last)==0);
193 
194  Segment<T, Compare>
195  segment2(std::min(p.first->begin(), segment.begin(), comp),
196  std::max(last->end(), segment.end(), comp));
197 
198  this->container_.erase(p.first, p.second);
199  return this->container_.insert(p.second, std::move(segment2));
200  }
201 
202  // using compiler generated copying
203  //SegmentSet(const SegmentSet&);
204  //SegmentSet& operator=(const SegmentSet&);
205  };
206 
207 }}}
208 #endif
SegmentSet(void)
creates a set with no segments
Definition: SegmentSet.h:58
std::set< Segment< T, Compare >, SegmentCompare< T, Compare > > ::iterator iterator
iterator
Definition: SegmentTree.h:89
The Department of Theoretical Physics namespace as we define it.
me::const_iterator insert_merge(const Segment< T, Compare > &segment)
Definition: SegmentSet.h:65
T max(const T &a, const T &b, const T &c)
Definition: stl_utility.h:699
me::iterator insert_merge(typename me::iterator hint, const Segment< T, Compare > &segment)
insert with a hint
Definition: SegmentSet.h:97
std::set< Segment< T, Compare >, SegmentCompare< T, Compare > > ::const_iterator const_iterator
const_iterator
Definition: SegmentTree.h:91
a set of Segments
Definition: SegmentSet.h:47
void insert_merge(Iterator first, Iterator last)
Definition: SegmentSet.h:153
a class for a Segment or Interval
Definition: Segment.h:49
me::iterator insert_merge(typename me::iterator hint, Segment< T, Compare > &&segment)
Definition: SegmentSet.h:109
Base Class for SegmentSet and SegmentMap.
Definition: SegmentTree.h:46
me::const_iterator insert_merge(Segment< T, Compare > &&segment)
Definition: SegmentSet.h:80
std::set< Segment< T, Compare >, SegmentCompare< T, Compare > > container_
underlying container
Definition: SegmentTree.h:240

Generated on Wed Jan 25 2023 03:34:29 for yat by  doxygen 1.8.14