CMS 3D CMS Logo

MapOfVectors.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_MapOfVectors_h
2 #define DataFormats_Common_MapOfVectors_h
3 
5 #include <vector>
6 #include <map>
7 
8 #include <boost/range/iterator_range.hpp>
9 #include <boost/iterator/iterator_facade.hpp>
10 
11 class TestMapOfVectors;
12 
13 namespace edm {
14 
15  /* a linearized read-only map-of vectors
16  NOTE: The iterator for MapOfVectors an not safely be used across threads, even if only const methods are called.
17  */
18  template <typename K, typename T>
19  class MapOfVectors {
20  public:
21  typedef MapOfVectors<K, T> self;
22  typedef std::map<K, std::vector<T> > TheMap;
23 
24  typedef unsigned int size_type;
25 
26  typedef std::vector<K> Keys;
27  typedef std::vector<size_type> Offsets;
28  typedef std::vector<T> Data;
29 
30  typedef typename Keys::const_iterator key_iterator;
31  typedef Offsets::const_iterator offset_iterator;
32  typedef typename Data::const_iterator data_iterator;
33 
34  typedef boost::iterator_range<data_iterator> range;
35 
36  typedef std::pair<K, range> Pair;
37 
38  class Iter : public boost::iterator_facade<Iter, Pair const, boost::forward_traversal_tag> {
39  public:
40  typedef Iter self;
41  Iter() {}
42 
43  explicit Iter(key_iterator k, offset_iterator o, std::vector<T> const& d) : key(k), off(o), data(d.begin()) {}
44 
45  private:
47 
48  void increment() {
49  ++key;
50  ++off;
51  }
52 
53  bool equal(self const& other) const { return this->key == other.key; }
54 
55  Pair const& dereference() const {
56  // FIXME can be optimized...
57  cache.first = *key;
58  cache.second = range(data + (*off), data + (*(off + 1)));
59  return cache;
60  }
61 
65  //This class is not intended to be used across threads
67  };
68 
69  typedef Iter const_iterator;
70 
71  range emptyRange() const { return range(m_data.end(), m_data.end()); }
72 
73  MapOfVectors() : m_offsets(1, 0) {}
74 
75  MapOfVectors(TheMap const& it) {
76  m_keys.reserve(it.size());
77  m_offsets.reserve(it.size() + 1);
78  m_offsets.push_back(0);
79  size_type tot = 0;
80  for (typename TheMap::const_iterator p = it.begin(); p != it.end(); ++p)
81  tot += (*p).second.size();
82  m_data.reserve(tot);
83  for (typename TheMap::const_iterator p = it.begin(); p != it.end(); ++p)
84  loadNext((*p).first, (*p).second);
85  }
86 
87  void loadNext(K const& k, std::vector<T> const& v) {
88  m_keys.push_back(k);
89  m_data.resize(m_offsets.back() + v.size());
90  std::copy(v.begin(), v.end(), m_data.begin() + m_offsets.back());
91  m_offsets.push_back(m_data.size());
92  }
93 
94  size_type size() const { return m_keys.size(); }
95 
96  bool empty() const { return m_keys.empty(); }
97 
98  key_iterator findKey(K const& k) const {
99  std::pair<key_iterator, key_iterator> p = std::equal_range(m_keys.begin(), m_keys.end(), k);
100  return (p.first != p.second) ? p.first : m_keys.end();
101  }
102 
103  size_type offset(K const& k) const {
104  key_iterator p = findKey(k);
105  if (p == m_keys.end())
106  return m_data.size();
107  return m_offsets[p - m_keys.begin()];
108  }
109 
110  range find(K const& k) const {
111  key_iterator p = findKey(k);
112  if (p == m_keys.end())
113  return emptyRange();
114  size_type loc = p - m_keys.begin();
115  data_iterator b = m_data.begin() + m_offsets[loc];
116  data_iterator e = m_data.begin() + m_offsets[loc + 1];
117  return range(b, e);
118  }
119 
121  const_iterator begin() const { return const_iterator(m_keys.begin(), m_offsets.begin(), m_data); }
122 
123  const_iterator end() const { return const_iterator(m_keys.end(), m_offsets.begin() + m_keys.size(), m_data); }
124 
126  m_keys.swap(other.m_keys);
127  m_offsets.swap(other.m_offsets);
128  m_data.swap(other.m_data);
129  }
130 
132  MapOfVectors temp(rhs);
133  this->swap(temp);
134  return *this;
135  }
136 
137  private:
138  //for testing
139  friend class ::TestMapOfVectors;
140 
141  std::vector<K> m_keys;
142  std::vector<size_type> m_offsets;
143  std::vector<T> m_data;
144  };
145 
146  // Free swap function
147  template <typename K, typename T>
148  inline void swap(MapOfVectors<K, T>& lhs, MapOfVectors<K, T>& rhs) {
149  lhs.swap(rhs);
150  }
151 
152 } // namespace edm
153 
154 #endif // DatFormats_Common_MapOfVectors_h
Iter(key_iterator k, offset_iterator o, std::vector< T > const &d)
Definition: MapOfVectors.h:43
Pair const & dereference() const
Definition: MapOfVectors.h:55
#define CMS_SA_ALLOW
Keys::const_iterator key_iterator
Definition: MapOfVectors.h:30
unsigned int size_type
Definition: MapOfVectors.h:24
MapOfVectors(TheMap const &it)
Definition: MapOfVectors.h:75
std::vector< T > m_data
Definition: MapOfVectors.h:143
void loadNext(K const &k, std::vector< T > const &v)
Definition: MapOfVectors.h:87
range emptyRange() const
Definition: MapOfVectors.h:71
Offsets::const_iterator offset_iterator
Definition: MapOfVectors.h:31
void swap(MapOfVectors &other)
Definition: MapOfVectors.h:125
std::map< K, std::vector< T > > TheMap
Definition: MapOfVectors.h:22
range find(K const &k) const
Definition: MapOfVectors.h:110
std::vector< size_type > m_offsets
Definition: MapOfVectors.h:142
std::vector< K > m_keys
Definition: MapOfVectors.h:141
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
std::pair< K, range > Pair
Definition: MapOfVectors.h:36
bool empty() const
Definition: MapOfVectors.h:96
friend class boost::iterator_core_access
Definition: MapOfVectors.h:46
MapOfVectors & operator=(MapOfVectors const &rhs)
Definition: MapOfVectors.h:131
key_iterator findKey(K const &k) const
Definition: MapOfVectors.h:98
d
Definition: ztail.py:151
std::vector< size_type > Offsets
Definition: MapOfVectors.h:27
Data::const_iterator data_iterator
Definition: MapOfVectors.h:32
size_type size() const
Definition: MapOfVectors.h:94
std::vector< T > Data
Definition: MapOfVectors.h:28
bool equal(self const &other) const
Definition: MapOfVectors.h:53
double b
Definition: hdecay.h:118
offset_iterator off
Definition: MapOfVectors.h:63
const_iterator end() const
Definition: MapOfVectors.h:123
HLT enums.
boost::iterator_range< data_iterator > range
Definition: MapOfVectors.h:34
std::vector< K > Keys
Definition: MapOfVectors.h:26
const_iterator begin() const
The iterator returned can not safely be used across threads.
Definition: MapOfVectors.h:121
size_type offset(K const &k) const
Definition: MapOfVectors.h:103