Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FastMultiSet.h
Go to the documentation of this file.
1 
26 #ifndef LIMBO_CONTAINERS_FASTMULTISET_H
27 #define LIMBO_CONTAINERS_FASTMULTISET_H
28 
29 #include <iostream>
30 #include <map>
31 #include <multiset>
32 #include <cassert>
33 #include <boost/typeof.hpp>
34 
36 namespace limbo
37 {
39 namespace containers
40 {
41 
42 using std::map;
43 using std::less;
44 using std::multiset;
45 
50 template <typename KeyType,
51  typename Compare1 = less<KeyType>,
52  typename Compare2 = less<KeyType> >
53 class FastMultiSet : public multiset<KeyType, Compare1>
54 {
55  public:
57  typedef KeyType key_type;
59  typedef KeyType value_type;
61  typedef Compare1 key_compare1;
62  typedef Compare2 key_compare2;
63  typedef multiset<key_type, key_compare1> base_type;
64  typedef map<key_type, typename base_type::iterator, key_compare2> map_type;
65  typedef typename map_type::value_type map_value_type;
66 
67  typedef typename base_type::reference reference;
68  typedef typename base_type::const_reference const_reference;
69  typedef typename base_type::pointer pointer;
70  typedef typename base_type::const_pointer const_pointer;
71  typedef typename base_type::iterator iterator;
72  typedef typename base_type::const_iterator const_iterator;
73  typedef typename base_type::reverse_iterator reverse_iterator;
74  typedef typename base_type::const_reverse_iterator const_reverse_iterator;
75  typedef typename base_type::difference_type difference_type;
76  typedef typename base_type::size_type size_type;
78 
82  explicit FastMultiSet(key_compare1 const& comp1 = key_compare1(),
83  key_compare2 const& comp2 = key_compare2())
84  : base_type(comp1), m_map(comp2) {}
88  : base_type(rhs)
89  {
90  // O(2NlogN)
91  // rhs may be in bad order
92  // so we have to reconstruct m_map
93  m_map.clear();
94  for (iterator it = this->begin();
95  it != this->end(); ++it)
96  m_map.insert(std::make_pair(*it, it));
97  }
98 
102  virtual iterator insert(key_type const& val)
103  {
104  // for safty, take O(logN)
105  BOOST_AUTO(found, m_map.find(val));
106  assert(found == m_map.end());
107  iterator it = this->base_type::insert(val); // no hint
108  m_map[val] = it;
109  return it;
110  }
115  virtual iterator insert(iterator position, key_type const& val)
116  {
117  // for safty, take O(logN)
118  BOOST_AUTO(found, m_map.find(val));
119  assert(found == m_map.end());
120  iterator it = this->base_type::insert(position, val); // with hint
121  m_map[val] = it;
122  return it;
123  }
127  template <typename InputIterator> void insert(InputIterator first, InputIterator last);
128 
132  virtual size_type erase(key_type const& val)
133  {
134  BOOST_AUTO(found, m_map.find(val));
135  if (found == m_map.end()) return 0;
136  this->base_type::erase(found->second);
137  m_map.erase(found);
138  return 1;
139  }
142  void erase(iterator position);
145  void erase(iterator first, iterator last);
146 
150  virtual iterator update(key_type const& val)
151  {
152  BOOST_AUTO(found, m_map.find(val)); // O(logN)
153  // it is possible in some applications
154  if (found == m_map.end()) return this->end();
155  // update multiset
156  this->base_type::erase(found->second); // O(1)
157  iterator it = this->base_type::insert(val); // O(logN)
158  // update map
159  found->second = it; // O(1)
160  return found->second;
161  }
162 
166  virtual size_type count(key_type const& val) const
167  {
168  return m_map.count(val); // O(logN)
169  }
173  virtual iterator find(key_type const& val) const
174  {
175  BOOST_AUTO(found, m_map.find(val)); // O(logN)
176  if (found == m_map.end()) // not found
177  return this->end();
178  else // found
179  return found->second;
180  }
181 
184  void print(std::ostream& os) const
185  {
186  os << "/////////// FastMultiSet ////////////\n";
187  os << "<< set >>\n";
188  for (const_iterator it = this->begin();
189  it != this->end(); ++it)
190  os << *it << endl;
191  os << "<< map >>\n";
192  for (BOOST_AUTO(it, m_map.begin());
193  it != m_map.end(); ++it)
194  os << it->first << " --> " << *(it->second) << endl;
195  }
200  friend std::ostream& operator<<(std::ostream& os, FastMultiSet const& rhs)
201  {
202  rhs.print(os);
203  return os;
204  }
205 
206  protected:
207  map_type m_map;
208 };
209 
210 } // namespace containers
211 } // namespace limbo
212 
213 #endif
FastMultiSet(key_compare1 const &comp1=key_compare1(), key_compare2 const &comp2=key_compare2())
constructor
Definition: FastMultiSet.h:82
virtual size_type erase(key_type const &val)
erase value
Definition: FastMultiSet.h:132
FastMultiSet(FastMultiSet const &rhs)
copy constructor
Definition: FastMultiSet.h:87
void print(std::ostream &os) const
print object
Definition: FastMultiSet.h:184
virtual iterator find(key_type const &val) const
use m_map.find rather than std::multiset::find to have faster access
Definition: FastMultiSet.h:173
virtual iterator update(key_type const &val)
update value, the value is changed which means its position is not correct in the container ...
Definition: FastMultiSet.h:150
virtual size_type count(key_type const &val) const
use m_map.count rather than multiset::count to have faster access
Definition: FastMultiSet.h:166
friend std::ostream & operator<<(std::ostream &os, FastMultiSet const &rhs)
print object
Definition: FastMultiSet.h:200
map_type m_map
internal map
Definition: FastMultiSet.h:207
namespace for Limbo
Definition: GraphUtility.h:22
virtual iterator insert(key_type const &val)
insert value
Definition: FastMultiSet.h:102
virtual iterator insert(iterator position, key_type const &val)
insert value with hint of position
Definition: FastMultiSet.h:115
KeyType key_type
for set concept, value_type is also key_type
Definition: FastMultiSet.h:57
KeyType value_type
for set concept, key_type is also value_type
Definition: FastMultiSet.h:59