GComm  0.2.3
map.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2012 Codership Oy <info@codership.com>
3  */
4 
12 #ifndef GCOMM_MAP_HPP
13 #define GCOMM_MAP_HPP
14 
15 #include "gu_serialize.hpp"
16 
17 #include <utility>
18 #include <iterator>
19 #include <map>
20 
21 #include "gcomm/exception.hpp"
22 #include "gcomm/types.hpp"
23 
24 namespace gcomm
25 {
26  template<typename K, typename V, typename C>
27  class MapBase
28  {
29  typedef C MapType;
30 
31  public:
32 
33  typedef typename MapType::iterator iterator;
34  typedef typename MapType::const_iterator const_iterator;
35  typedef typename MapType::reverse_iterator reverse_iterator;
36  typedef typename MapType::const_reverse_iterator const_reverse_iterator;
37  typedef typename MapType::value_type value_type;
38  typedef typename MapType::const_reference const_reference;
39  typedef typename MapType::key_type key_type;
40  typedef typename MapType::mapped_type mapped_type;
41 
42  protected:
43 
44  MapType map_;
45  public:
46 
47  MapBase() : map_() {}
48 
49  virtual ~MapBase() {}
50 
51  iterator begin() { return map_.begin(); }
52 
53  iterator end() { return map_.end(); }
54 
55  iterator find(const K& k) { return map_.find(k); }
56 
57  iterator find_checked(const K& k)
58  {
59  iterator ret = map_.find(k);
60  if (ret == map_.end())
61  {
62  gu_throw_fatal << "element " << k << " not found";
63  }
64  return ret;
65  }
66 
67  iterator lower_bound(const K& k) { return map_.lower_bound(k); }
68 
69  const_iterator begin() const { return map_.begin(); }
70 
71  const_iterator end() const { return map_.end(); }
72 
73  const_reverse_iterator rbegin() const { return map_.rbegin(); }
74 
75  const_reverse_iterator rend() const { return map_.rend(); }
76 
77  const_iterator find(const K& k) const { return map_.find(k); }
78 
79  const_iterator find_checked(const K& k) const
80  {
81  const_iterator ret = map_.find(k);
82  if (ret == map_.end())
83  {
84  gu_throw_fatal << "element " << k << " not found";
85  }
86  return ret;
87  }
88 
89  mapped_type& operator[](const key_type& k) { return map_[k]; }
90 
91  void erase(iterator i) { map_.erase(i); }
92 
93  void erase(iterator i, iterator j) { map_.erase(i, j); }
94 
95  void erase(const K& k) { map_.erase(k); }
96 
97  void clear() { map_.clear(); }
98 
99  size_t size() const { return map_.size(); }
100 
101  bool empty() const { return map_.empty(); }
102 
103  size_t serialize(gu::byte_t* const buf,
104  size_t const buflen,
105  size_t offset) const
106  {
107  gu_trace(offset = gu::serialize4(
108  static_cast<uint32_t>(size()), buf, buflen, offset));
109  for (const_iterator i = map_.begin(); i != map_.end(); ++i)
110  {
111  gu_trace(offset = key(i).serialize(buf, buflen, offset));
112  gu_trace(offset = value(i).serialize(buf, buflen, offset));
113  }
114  return offset;
115  }
116 
117  size_t unserialize(const gu::byte_t* buf,
118  size_t const buflen,
119  size_t offset)
120  {
121  uint32_t len;
122  // Clear map in case this object is reused
123  map_.clear();
124 
125  gu_trace(offset = gu::unserialize4(buf, buflen, offset, len));;
126 
127  for (uint32_t i = 0; i < len; ++i)
128  {
129  K k;
130  V v;
131  gu_trace(offset = k.unserialize(buf, buflen, offset));
132  gu_trace(offset = v.unserialize(buf, buflen, offset));
133  if (map_.insert(std::make_pair(k, v)).second == false)
134  {
135  gu_throw_fatal << "Failed to unserialize map";
136  }
137  }
138  return offset;
139  }
140 
141  size_t serial_size() const
142  {
143  return sizeof(uint32_t) + size()*(K::serial_size() + V::serial_size());
144  }
145 
146  bool operator==(const MapBase& other) const
147  {
148  return (map_ == other.map_);
149  }
150 
151  bool operator!=(const MapBase& other) const
152  {
153  return !(map_ == other.map_);
154  }
155 
156  static const K& key(const_iterator i)
157  {
158  return i->first;
159  }
160 
161  static const K& key(iterator i)
162  {
163  return i->first;
164  }
165 
166  static const V& value(const_iterator i)
167  {
168  return i->second;
169  }
170 
171  static V& value(iterator i)
172  {
173  return i->second;
174  }
175 
176  static const K& key(const value_type& vt)
177  {
178  return vt.first;
179  }
180 
181  static V& value(value_type& vt)
182  {
183  return vt.second;
184  }
185 
186  static const V& value(const value_type& vt)
187  {
188  return vt.second;
189  }
190  };
191 
192  // @todo For some reason map key must be declared in gcomm namespace
193  // in order this to work. Find out the reason why and fix.
194  template <typename K, typename V>
195  std::ostream& operator<<(std::ostream& os, const std::pair<K, V>& p)
196  {
197  return (os << "\t" << p.first << "," << p.second << "\n");
198  }
199 
200  template <typename K, typename V, typename C>
201  std::ostream& operator<<(std::ostream& os, const MapBase<K, V, C>& map)
202  {
203  std::copy(map.begin(), map.end(),
204  std::ostream_iterator<const std::pair<const K, V> >(os, ""));
205  return os;
206  }
207 
208 
209  template <typename K, typename V, typename C = std::map<K, V> >
210  class Map : public MapBase<K, V, C>
211  {
212  public:
213  typedef typename MapBase<K, V, C>::iterator iterator;
214  std::pair<iterator, bool> insert(const std::pair<K, V>& p)
215  {
216  return MapBase<K, V, C>::map_.insert(p);
217  }
218 
219  template <class InputIterator>
220  void insert(InputIterator first, InputIterator last)
221  {
222  MapBase<K, V, C>::map_.insert(first, last);
223  }
224 
225  iterator insert_unique(const typename MapBase<K, V, C>::value_type& p)
226  {
227  std::pair<iterator, bool> ret = MapBase<K, V, C>::map_.insert(p);
228  if (false == ret.second)
229  {
230  gu_throw_fatal << "duplicate entry "
231  << "key=" << MapBase<K, V, C>::key(p) << " "
232  << "value=" << MapBase<K, V, C>::value(p) << " "
233  << "map=" << *this;
234  }
235  return ret.first;
236  }
237 
238  };
239 
240 
241 
242 
243  template <typename K, typename V, typename C = std::multimap<K, V> >
244  class MultiMap : public MapBase<K, V, C>
245  {
246  public:
247  typedef typename MapBase<K, V, C>::iterator iterator;
248  typedef typename MapBase<K, V, C>::const_iterator const_iterator;
249  typedef typename MapBase<K, V, C>::value_type value_type;
250  typedef typename MapBase<K, V, C>::const_reference const_reference;
251 
252  iterator insert(const std::pair<K, V>& p)
253  {
254  return MapBase<K, V, C>::map_.insert(p);
255  }
256 
257  iterator insert(iterator position, const value_type& vt)
258  {
259  return MapBase<K, V, C>::map_.insert(position, vt);
260  }
261 
262  std::pair<const_iterator, const_iterator> equal_range(const K& k) const
263  {
264  return MapBase<K, V, C>::map_.equal_range(k);
265  }
266  };
267 }
268 #endif /* GCOMM_MAP_HPP */
Definition: map.hpp:27
Definition: map.hpp:210
Definition: map.hpp:244
GComm exception definitions.