UniqueRangeSet.h
Go to the documentation of this file.
1 /**
2  * \file UniqueRangeSet.h
3  *
4  * \ingroup RangeTool
5  *
6  * \brief Class def header for a class UniqueRangeSet
7  *
8  * @author kazuhiro
9  */
10 
11 /** \addtogroup RangeTool
12  @{*/
13 
14 #ifndef UNIQUERANGESET_H
15 #define UNIQUERANGESET_H
16 
17 #include <set>
18 #include "Range.h"
19 
20 namespace util {
21 
22  /**
23  \class UniqueRangeSet
24  @brief std::set of util::Range, which does not allow any overlap in contained element.
25  std::set<Range> w/ modified insert/emplace function. Original std::set does not allow \n
26  modification of element. I assume what we're interested in is "find if the range already \n
27  exists, and merge if it exists". The insert function does that by recursively looking up \n
28  overlapping elements w.r.t. input argument of insert function. \n
29 
30  One important function worth noting is util::UniqueRangeSet::Exclusive which takes two \n
31  input arguments, "start" and "end", and returns util::UniqueRangeSet of all exclusive \n
32  regions between "start" and "end". By definition, merging this return with the original \n
33  instance will result in 1 huge util::Range.
34  */
35  template <class T>
36  class UniqueRangeSet : public std::set<util::Range<T> > {
37  public:
38  /// default ctor
40  /// default dtor
42 
43  /// Merge two UniqueRangeSet<T>
44  void Merge(const UniqueRangeSet<T>& in)
45  { for(auto const& r : in) emplace(r._window.first,r._window.second); }
46 
47  /// Very first "start" of all contained range
48  const T& Start() const
49  {
50  if(!(this->size())) throw std::runtime_error("Nothing in the set!");
51  return (*(this->begin()))._window.first;
52  }
53 
54  /// Very last "end" of all contained range
55  const T& End() const
56  {
57  if(!(this->size())) throw std::runtime_error("Nothing in the set!");
58  return (*(this->rbegin()))._window.second;
59  }
60 
61  /**
62  It takes two input arguments, "start" and "end", and returns util::UniqueRangeSet \n
63  of all exclusive regions between "start" and "end". By definition, merging this \n
64  return with the original instance will result in 1 huge util::Range.
65  */
66  UniqueRangeSet<T> Exclusive(const T start, const T end) const
67  {
69 
70  auto start_iter = std::lower_bound(this->begin(),this->end(),start);
71  auto end_iter = std::lower_bound(this->begin(),this->end(),end);
72 
73  // Anything to add to the head?
74  if(start < (*start_iter)._window.first) res.emplace(start,(*start_iter)._window.first);
75 
76  auto iter = start_iter;
77  T tmp_end=end;
78  while(iter != this->end()) {
79  if(iter != start_iter)
80  res.emplace(tmp_end,(*iter)._window.first);
81  tmp_end = (*iter)._window.second;
82  if(iter == end_iter) break;
83  ++iter;
84  }
85 
86  // Anything to add to the tail?
87  if(tmp_end < end)
88  res.emplace(tmp_end,end);
89 
90  return res;
91  }
92 
93  /// Modified emplace that merges overlapping range. Return = # merged range.
94  size_t emplace(const T& start,const T& end) {
95 
96  auto res = std::set<util::Range<T> >::emplace(start,end);
97  if(res.second) return 0;
98 
99  auto& iter = res.first;
100  auto tmp_a = Range<T>(start,end);
101  size_t ctr=0;
102  while(iter != this->end()) {
103  tmp_a.Merge((*iter));
104  this->erase(iter);
105  iter = this->find(tmp_a);
106  ++ctr;
107  }
108  this->insert(tmp_a);
109  return ctr;
110  }
111 
112  /// Modified insert that merges overlapping range. Return = # merged range.
113  size_t insert(const Range<T>& a)
114  {return emplace(a._window.first,a._window.second);}
115 
116  };
117 }
118 
119 #endif
120 /** @} */ // end of doxygen group
size_t insert(const Range< T > &a)
Modified insert that merges overlapping range. Return = # merged range.
void Merge(const Range &a)
Merge two util::Range into 1.
Definition: Range.h:85
Namespace for general, non-LArSoft-specific utilities.
UniqueRangeSet()
default ctor
void Merge(const UniqueRangeSet< T > &in)
Merge two UniqueRangeSet<T>
~UniqueRangeSet()
default dtor
const T & Start() const
Very first "start" of all contained range.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
Class def header for a class Range.
const double a
size_t emplace(const T &start, const T &end)
Modified emplace that merges overlapping range. Return = # merged range.
UniqueRangeSet< T > Exclusive(const T start, const T end) const
std::pair< T, T > _window
Protected to avoid user&#39;s illegal modification on first/second (sorry users!)
Definition: Range.h:92
std::set of util::Range, which does not allow any overlap in contained element. std::set<Range> w/ mo...
Definition: Range.h:23
represents a "Range" w/ notion of ordering. A range is defined by a pair of "start" and "end" values...
Definition: Range.h:34
const T & End() const
Very last "end" of all contained range.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72