yat  0.13.2pre
MergeIterator.h
1 #ifndef theplu_yat_utility_merge_iterator
2 #define theplu_yat_utility_merge_iterator
3 
4 // $Id: MergeIterator.h 3417 2015-05-25 01:35:59Z peter $
5 
6 /*
7  Copyright (C) 2013, 2015 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 "stl_utility.h"
26 #include "yat/utility/yat_assert.h"
27 
28 #include <boost/iterator/iterator_facade.hpp>
29 #include <boost/iterator/iterator_traits.hpp>
30 
31 #include <iterator>
32 #include <set>
33 #include <vector>
34 
35 namespace theplu {
36 namespace yat {
37 namespace utility {
38 
58  template<
59  typename Base,
60  class Compare=std::less<typename std::iterator_traits<Base>::value_type>
61  >
63  : public boost::iterator_facade<
64  MergeIterator<Base, Compare>,
65  typename boost::iterator_value<Base>::type,
66  boost::single_pass_traversal_tag,
67  typename boost::iterator_reference<Base>::type
68  >
69  {
70  public:
74  MergeIterator(void) {};
75 
84  MergeIterator(const std::vector<std::pair<Base, Base> >& vec)
85  { init(vec); };
86 
96  MergeIterator(const std::vector<std::pair<Base, Base> >& vec,
97  const Compare& comp)
98  : data_(PairCompare(comp))
99  { init(vec); }
100 
101  private:
102  friend class boost::iterator_core_access;
103 
104  typename MergeIterator<Base, Compare>::reference dereference(void) const;
105  bool equal(const MergeIterator& other) const;
106  void init(const std::vector<std::pair<Base,Base> >& v);
107  void increment(void);
108 
109  class PairCompare
110  {
111  public:
112  PairCompare(void) {}
113  PairCompare(const Compare& c) : comp_(c) {}
114  bool operator()(const std::pair<Base, Base>& x,
115  const std::pair<Base, Base>& y) const
116  { return comp_(*x.first, *y.first); }
117  private:
118  Compare comp_;
119  };
120 
121  std::multiset<std::pair<Base, Base>, PairCompare> data_;
122  };
123 
129  template<typename Base>
130  MergeIterator<Base>
131  make_merge_iterator(const std::vector<std::pair<Base, Base> >& vec)
132  {
133  return MergeIterator<Base>(vec);
134  }
135 
136 
143  template<typename Base, class Compare>
145  make_merge_iterator(const std::vector<std::pair<Base, Base> >& vec,
146  const Compare& comp)
147  {
148  return MergeIterator<Base, Compare>(vec, comp);
149  }
150 
151 
152 
153  // template implementations
154 
155  template<typename Base, class Compare>
158  {
159  YAT_ASSERT(data_.size());
160  YAT_ASSERT(data_.begin()->first != data_.begin()->second);
161  return *data_.begin()->first;
162  }
163 
164 
165  template<typename Base, class Compare>
166  bool MergeIterator<Base, Compare>::equal(const MergeIterator& other) const
167  {
168  if (data_.empty() || other.data_.empty())
169  return data_.empty() == other.data_.empty();
170  return data_.begin()->first == other.data_.begin()->first;
171  }
172 
173 
174  template<typename Base, class Compare>
175  void
176  MergeIterator<Base,Compare>::init(const std::vector<std::pair<Base,Base> >& v)
177  {
178  for (size_t i=0; i<v.size(); ++i)
179  if (v[i].first != v[i].second)
180  data_.insert(v[i]);
181  }
182 
183 
184  template<typename Base, class Compare>
185  void MergeIterator<Base, Compare>::increment(void)
186  {
187  if (data_.empty())
188  return;
189  // store first range
190  std::pair<Base, Base> tmp = *data_.begin();
191  // remove first range from set of ranges
192  data_.erase(data_.begin());
193  // iterate the first range and if not end-of-range, insert the
194  // range back into set of ranges
195  if (++(tmp.first) != tmp.second)
196  data_.insert(tmp);
197  }
198 
199 }}}
200 #endif
MergeIterator< Base, Compare > make_merge_iterator(const std::vector< std::pair< Base, Base > > &vec, const Compare &comp)
Definition: MergeIterator.h:145
Iterate over several ranges as if ranges have been merged.
Definition: MergeIterator.h:62
MergeIterator(const std::vector< std::pair< Base, Base > > &vec)
Create MergeIterator.
Definition: MergeIterator.h:84
MergeIterator< Base > make_merge_iterator(const std::vector< std::pair< Base, Base > > &vec)
Definition: MergeIterator.h:131
MergeIterator(const std::vector< std::pair< Base, Base > > &vec, const Compare &comp)
Creates MergeIterator using comp as compare object.
Definition: MergeIterator.h:96
MergeIterator(void)
Definition: MergeIterator.h:74

Generated on Wed Jan 4 2017 02:23:07 for yat by  doxygen 1.8.5