vbl_batch_multimap.h
Go to the documentation of this file.
1 // This is core/vbl/vbl_batch_multimap.h
2 #ifndef vbl_batch_multimap_h_
3 #define vbl_batch_multimap_h_
4 
5 //:
6 // \file
7 // \brief Like a faster std::multimap but using only a single block of memory, and no fast insertion or deletion.
8 // \author Ian Scott, Imorphics 2011
9 
10 
11 #include <vector>
12 #include <cstddef>
13 #include <functional>
14 #include <utility>
15 #include <algorithm>
16 #include <cassert>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 
21 namespace
22 {
23 
24 }
25 //: A fast read and batch-write map-style collection.
26 // This container stores its elements in a single vector, and has fast construction and deletion.
27 // It has all the const-access map fundtions, but its contents can only be modified all-at-once.
28 template <typename K, typename T, typename C=std::less<K> >
30 {
31 public:
32  typedef K key_type;
33  typedef T mapped_type;
34  typedef typename std::pair<key_type, mapped_type> value_type;
35  typedef C key_compare;
36  typedef typename std::vector<value_type> container_type;
37  typedef typename container_type::allocator_type allocator_type;
38 
39  typedef typename container_type::const_iterator const_iterator;
40 
41  typedef typename container_type::const_reference const_reference;
42 
43 
44 
46  {
47  // friend class vbl_batch_multimap<key_type, mapped_type, key_compare>;
48  // protected:
49  public:
51 
53  : comp(c) { }
54 
55  public:
56  bool operator()(const value_type& x, const value_type& y) const
57  { return comp(x.first, y.first); }
58 
59  bool compare(const value_type& x, const value_type& y) const
60  { return comp(x.first, y.first); }
61  };
62 
63 
65 
66  template <typename CI>
67  vbl_batch_multimap(CI start, CI finish):
68  data_(start, finish)
69  {
70  std::sort(data_.begin(), data_.end(), value_compare_t(key_compare()));
71  }
72 
73  //: Change all the values in the multimap.
74  template <typename CI>
75  void assign(CI start, CI finish)
76  {
77  data_.assign(start, finish);
78  std::sort(data_.begin(), data_.end(), value_compare_t(key_compare()));
79  }
80 
81  //: Change all the values in the multimap, to a ready sorted sequence
82  // The input values must already be sorted on their v.first members.
83  template <typename CI>
84  void assign_sorted(CI start, CI finish)
85  {
86  data_.assign(start, finish);
87  assert(is_sorted(start, finish, value_compare_t(key_compare())));
88  }
89 
91  {
92  data_.swap(rhs.data_);
93  }
94 
95 
97  {
98  return data_ == rhs.data_;
99  }
100 
101 // const vector API
102 
103  const_iterator begin() const { return data_.begin(); }
104  const_iterator end() const { return data_.end(); }
105  bool empty() const { return data_.empty(); }
106  std::size_t size() const { return data_.size(); }
107 
108 // const map API
109 
110  //: Finds the beginning of a subsequence matching given \p key.
111  // /return iterator to the first element that equals \p key, or the
112  // next greatest element if no match is found.
114  {
115  return std::lower_bound(data_.begin(), data_.end(),
116  std::make_pair(key, mapped_type()), value_compare_t(key_compare()));
117  }
118 
119  //: Finds the one past the end of a subsequence matching given \p key.
120  // /return iterator to one past the last element that equals \p key, or to the
121  // next greatest element if no match is found.
123  {
124  return std::upper_bound(data_.begin(), data_.end(),
125  std::make_pair(key, mapped_type()), value_compare_t(key_compare()));
126  }
127 
128  //: A more efficient make_pair(lower_bound(...), upper_bound(...))
129  std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
130  {
131  return std::equal_range(data_.begin(), data_.end(),
132  std::make_pair(key, mapped_type()), value_compare_t(key_compare()));
133  }
134 
135  //: Finds the first matching value in the sequence, or returns end() if no match,
136  const_iterator find(const key_type& key) const
137  {
138  const_iterator it = lower_bound(key);
139  if (it != end() && it->first != key)
140  return end();
141  else
142  return it;
143  }
144 
145  //: Finds the number of elements with matching \p key,
146  std::size_t count(const key_type& key) const
147  {
148  std::pair<const_iterator, const_iterator> range = equal_range(key);
149  return range.second - range.first;
150  }
151 
152 
153 private:
155 
156  template <typename CI, typename CMP>
157  static bool is_sorted(CI start, CI end, CMP comp)
158  {
159  if (start == end) return true;
160 
161  for (end--; start!=end; ++start)
162  {
163  if ( comp(*(start+1), *start)) return false;
164  }
165  return true;
166  }
167 
168 };
169 
170 template<typename K, typename T, typename C>
172 {
173  x.swap(y);
174 }
175 
176 #endif // vbl_batch_multimap_h_
std::vector< value_type > container_type
std::size_t size() const
container_type::const_iterator const_iterator
std::pair< const_iterator, const_iterator > equal_range(const key_type &key) const
A more efficient make_pair(lower_bound(...), upper_bound(...)).
A fast read and batch-write map-style collection.
container_type::const_reference const_reference
bool operator()(const value_type &x, const value_type &y) const
void assign_sorted(CI start, CI finish)
Change all the values in the multimap, to a ready sorted sequence.
const_iterator find(const key_type &key) const
Finds the first matching value in the sequence, or returns end() if no match,.
const_iterator upper_bound(const key_type &key) const
Finds the one past the end of a subsequence matching given key.
void swap(vbl_batch_multimap< K, T, C > &x, vbl_batch_multimap< K, T, C > &y)
vbl_batch_multimap(CI start, CI finish)
bool compare(const value_type &x, const value_type &y) const
const_iterator lower_bound(const key_type &key) const
Finds the beginning of a subsequence matching given key.
std::size_t count(const key_type &key) const
Finds the number of elements with matching key,.
container_type::allocator_type allocator_type
bool operator==(const vbl_batch_multimap &rhs)
void swap(vbl_batch_multimap &rhs)
static bool is_sorted(CI start, CI end, CMP comp)
std::pair< key_type, mapped_type > value_type
const_iterator end() const
void assign(CI start, CI finish)
Change all the values in the multimap.
const_iterator begin() const