foobar2000 SDK  2015-01-14
map.h
Go to the documentation of this file.
1 #ifndef _MAP_T_H_INCLUDED_
2 #define _MAP_T_H_INCLUDED_
3 
4 namespace pfc {
5  PFC_DECLARE_EXCEPTION(exception_map_entry_not_found,exception,"Map entry not found");
6 
7  template<typename t_destination> class __map_overwrite_wrapper {
8  public:
9  __map_overwrite_wrapper(t_destination & p_destination) : m_destination(p_destination) {}
10  template<typename t_key,typename t_value> void operator() (const t_key & p_key,const t_value & p_value) {m_destination.set(p_key,p_value);}
11  private:
12  t_destination & m_destination;
13  };
14 
15  template<typename t_storage_key, typename t_storage_value, typename t_comparator = comparator_default>
16  class map_t {
17  private:
19  public:
20  typedef t_storage_key t_key; typedef t_storage_value t_value;
21  template<typename _t_key,typename _t_value>
22  void set(const _t_key & p_key, const _t_value & p_value) {
23  bool isnew;
24  t_storage & storage = m_data.add_ex(t_search_set<_t_key,_t_value>(p_key,p_value), isnew);
25  if (!isnew) storage.m_value = p_value;
26  }
27 
28  template<typename _t_key>
29  t_storage_value & find_or_add(_t_key const & p_key) {
30  return m_data.add(t_search_query<_t_key>(p_key)).m_value;
31  }
32 
33  template<typename _t_key>
34  t_storage_value & find_or_add_ex(_t_key const & p_key,bool & p_isnew) {
35  return m_data.add_ex(t_search_query<_t_key>(p_key),p_isnew).m_value;
36  }
37 
38  template<typename _t_key>
39  bool have_item(const _t_key & p_key) const {
40  return m_data.have_item(t_search_query<_t_key>(p_key));
41  }
42 
43  template<typename _t_key,typename _t_value>
44  bool query(const _t_key & p_key,_t_value & p_value) const {
45  const t_storage * storage = m_data.find_ptr(t_search_query<_t_key>(p_key));
46  if (storage == NULL) return false;
47  p_value = storage->m_value;
48  return true;
49  }
50 
51  template<typename _t_key>
52  const t_storage_value & operator[] (const _t_key & p_key) const {
53  const t_storage_value * ptr = query_ptr(p_key);
54  if (ptr == NULL) throw exception_map_entry_not_found();
55  return *ptr;
56  }
57 
58  template<typename _t_key>
59  t_storage_value & operator[] (const _t_key & p_key) {
60  return find_or_add(p_key);
61  }
62 
63  template<typename _t_key>
64  const t_storage_value * query_ptr(const _t_key & p_key) const {
65  const t_storage * storage = m_data.find_ptr(t_search_query<_t_key>(p_key));
66  if (storage == NULL) return NULL;
67  return &storage->m_value;
68  }
69 
70  template<typename _t_key>
71  t_storage_value * query_ptr(const _t_key & p_key) {
72  t_storage * storage = m_data.find_ptr(t_search_query<_t_key>(p_key));
73  if (storage == NULL) return NULL;
74  return &storage->m_value;
75  }
76 
77  template<typename _t_key>
78  bool query_ptr(const _t_key & p_key, const t_storage_value * & out) const {
79  const t_storage * storage = m_data.find_ptr(t_search_query<_t_key>(p_key));
80  if (storage == NULL) return false;
81  out = &storage->m_value;
82  return true;
83  }
84 
85  template<typename _t_key>
86  bool query_ptr(const _t_key & p_key, t_storage_value * & out) {
87  t_storage * storage = m_data.find_ptr(t_search_query<_t_key>(p_key));
88  if (storage == NULL) return false;
89  out = &storage->m_value;
90  return true;
91  }
92 
93  template<bool inclusive,bool above,typename _t_key>
94  const t_storage_value * query_nearest_ptr(_t_key & p_key) const {
95  const t_storage * storage = m_data.template find_nearest_item<inclusive,above>(t_search_query<_t_key>(p_key));
96  if (storage == NULL) return NULL;
97  p_key = storage->m_key;
98  return &storage->m_value;
99  }
100 
101  template<bool inclusive,bool above,typename _t_key>
102  t_storage_value * query_nearest_ptr(_t_key & p_key) {
103  t_storage * storage = m_data.template find_nearest_item<inclusive,above>(t_search_query<_t_key>(p_key));
104  if (storage == NULL) return NULL;
105  p_key = storage->m_key;
106  return &storage->m_value;
107  }
108 
109  template<bool inclusive,bool above,typename _t_key,typename _t_value>
110  bool query_nearest(_t_key & p_key,_t_value & p_value) const {
111  const t_storage * storage = m_data.template find_nearest_item<inclusive,above>(t_search_query<_t_key>(p_key));
112  if (storage == NULL) return false;
113  p_key = storage->m_key;
114  p_value = storage->m_value;
115  return true;
116  }
117 
118 
119  template<typename _t_key>
120  bool remove(const _t_key & p_key) {
121  return m_data.remove_item(t_search_query<_t_key>(p_key));
122  }
123 
124  template<typename t_callback>
125  void enumerate(t_callback & p_callback) const {
126  enumeration_wrapper<t_callback> cb(p_callback);
127  m_data.enumerate(cb);
128  }
129 
130  template<typename t_callback>
131  void enumerate(t_callback & p_callback) {
132  enumeration_wrapper_var<t_callback> cb(p_callback);
134  }
135 
136 
137  t_size get_count() const throw() {return m_data.get_count();}
138 
139  void remove_all() throw() {m_data.remove_all();}
140 
141  template<typename t_source>
142  void overwrite(const t_source & p_source) {
143  __map_overwrite_wrapper<t_self> wrapper(*this);
144  p_source.enumerate(wrapper);
145  }
146 
147  //backwards compatibility method wrappers
148  template<typename _t_key> bool exists(const _t_key & p_key) const {return have_item(p_key);}
149 
150 
151  template<typename _t_key> bool get_first(_t_key & p_out) const {
152  return m_data.get_first(t_retrieve_key<_t_key>(p_out));
153  }
154 
155  template<typename _t_key> bool get_last(_t_key & p_out) const {
156  return m_data.get_last(t_retrieve_key<_t_key>(p_out));
157  }
158 
159  private:
160  template<typename _t_key>
161  struct t_retrieve_key {
163  t_retrieve_key(_t_key & p_key) : m_key(p_key) {}
164  template<typename t_what> const t_self & operator=(const t_what & p_what) {m_key = p_what.m_key; return *this;}
165  _t_key & m_key;
166  };
167  template<typename _t_key>
168  struct t_search_query {
169  t_search_query(const _t_key & p_key) : m_key(p_key) {}
170  _t_key const & m_key;
171  };
172  template<typename _t_key,typename _t_value>
173  struct t_search_set {
174  t_search_set(const _t_key & p_key, const _t_value & p_value) : m_key(p_key), m_value(p_value) {}
175 
176  _t_key const & m_key;
177  _t_value const & m_value;
178  };
179 
180  struct t_storage {
181  const t_storage_key m_key;
182  t_storage_value m_value;
183 
184  template<typename _t_key>
185  t_storage(t_search_query<_t_key> const & p_source) : m_key(p_source.m_key), m_value() {}
186 
187  template<typename _t_key,typename _t_value>
188  t_storage(t_search_set<_t_key,_t_value> const & p_source) : m_key(p_source.m_key), m_value(p_source.m_value) {}
189 
190  static bool equals(const t_storage & v1, const t_storage & v2) {return v1.m_key == v2.m_key && v1.m_value == v2.m_value;}
191  bool operator==(const t_storage & other) const {return equals(*this,other);}
192  bool operator!=(const t_storage & other) const {return !equals(*this,other);}
193  };
194 
196  public:
197  template<typename t1,typename t2>
198  inline static int compare(const t1 & p_item1,const t2 & p_item2) {
199  return t_comparator::compare(p_item1.m_key,p_item2.m_key);
200  }
201  };
202 
203  template<typename t_callback>
205  public:
206  enumeration_wrapper(t_callback & p_callback) : m_callback(p_callback) {}
207  void operator()(const t_storage & p_item) {m_callback(p_item.m_key,p_item.m_value);}
208  private:
209  t_callback & m_callback;
210  };
211 
212  template<typename t_callback>
214  public:
215  enumeration_wrapper_var(t_callback & p_callback) : m_callback(p_callback) {}
216  void operator()(t_storage & p_item) {m_callback(implicit_cast<t_storage_key const&>(p_item.m_key),p_item.m_value);}
217  private:
218  t_callback & m_callback;
219  };
220 
222 
223  t_content m_data;
224  public:
227  typedef typename t_content::iterator iterator;
228 
229  iterator first() throw() {return m_data._first_var();}
230  iterator last() throw() {return m_data._last_var();}
231  const_iterator first() const throw() {return m_data.first();}
232  const_iterator last() const throw() {return m_data.last();}
233 
234  template<typename _t_key> iterator find(const _t_key & key) {return m_data.find(t_search_query<_t_key>(key));}
235  template<typename _t_key> const_iterator find(const _t_key & key) const {return m_data.find(t_search_query<_t_key>(key));}
236 
237  static bool equals(const t_self & v1, const t_self & v2) {
238  return t_content::equals(v1.m_data,v2.m_data);
239  }
240  bool operator==(const t_self & other) const {return equals(*this,other);}
241  bool operator!=(const t_self & other) const {return !equals(*this,other);}
242 
243  bool remove(iterator const& iter) {
244  PFC_ASSERT(iter.is_valid());
245  return m_data.remove(iter);
246  //should never return false unless there's a bug in calling code
247  }
248  bool remove(const_iterator const& iter) {
249  PFC_ASSERT(iter.is_valid());
250  return m_data.remove(iter);
251  //should never return false unless there's a bug in calling code
252  }
253  };
254 }
255 
256 #endif //_MAP_T_H_INCLUDED_
const t_storage_value & operator[](const _t_key &p_key) const
Definition: map.h:52
const_iterator first() const
Definition: map.h:231
t_storage & add(const t_param &p_item)
Definition: avltree.h:475
bool get_first(t_param &p_item) const
Definition: avltree.h:492
map_t< t_storage_key, t_storage_value, t_comparator > t_self
Definition: map.h:18
const t_storage_key m_key
Definition: map.h:181
Definition: map.h:16
t_storage_value t_value
Definition: map.h:20
void _enumerate_var(t_callback &p_callback)
Allows callback to modify the tree content. Unsafe! Caller must not modify items in a way that change...
Definition: avltree.h:465
t_size get_count() const
Definition: avltree.h:453
iterator find(const _t_key &key)
Definition: map.h:234
void operator()(t_storage &p_item)
Definition: map.h:216
void enumerate(t_callback &p_callback) const
Definition: map.h:125
bool get_first(_t_key &p_out) const
Definition: map.h:151
bool operator!=(const t_self &other) const
Definition: map.h:241
t_destination & m_destination
Definition: map.h:12
t_storage_value & find_or_add_ex(_t_key const &p_key, bool &p_isnew)
Definition: map.h:34
bool query_ptr(const _t_key &p_key, const t_storage_value *&out) const
Definition: map.h:78
void operator()(const t_key &p_key, const t_value &p_value)
Definition: map.h:10
t_content m_data
Definition: map.h:223
void remove_all()
Definition: map.h:139
bool query_ptr(const _t_key &p_key, t_storage_value *&out)
Definition: map.h:86
int compare(t1 const &p1, t2 const &p2)
Definition: pathUtils.h:29
t_storage_value * query_ptr(const _t_key &p_key)
Definition: map.h:71
const_iterator find(const _t_key &key) const
Definition: map.h:235
iterator _first_var()
Unsafe! Caller must not modify items in a way that changes sort order!
Definition: avltree.h:488
static bool equals(const t_self &v1, const t_self &v2)
Definition: avltree.h:505
traits_t< t_content > traits
Definition: map.h:225
t_storage(t_search_query< _t_key > const &p_source)
Definition: map.h:185
static bool equals(const t_storage &v1, const t_storage &v2)
Definition: map.h:190
bool have_item(const t_param &p_item) const
Same as contains().
Definition: avltree.h:433
t_storage & add_ex(const t_param &p_item, bool &p_isnew)
Definition: avltree.h:476
bool operator!=(const t_storage &other) const
Definition: map.h:192
t_search_query(const _t_key &p_key)
Definition: map.h:169
const t_storage_value * query_nearest_ptr(_t_key &p_key) const
Definition: map.h:94
t_storage_value & find_or_add(_t_key const &p_key)
Definition: map.h:29
iterator _last_var()
Unsafe! Caller must not modify items in a way that changes sort order!
Definition: avltree.h:490
const_iterator find(t_param const &item) const
Definition: avltree.h:420
const_iterator first() const
Definition: avltree.h:485
void enumerate(t_callback &p_callback) const
Definition: avltree.h:458
_t_value const & m_value
Definition: map.h:177
t_storage_value m_value
Definition: map.h:182
const t_storage_value * query_ptr(const _t_key &p_key) const
Definition: map.h:64
avltree_t< t_storage, comparator_wrapper > t_content
Definition: map.h:221
_t_key const & m_key
Definition: map.h:176
size_t t_size
Definition: int_types.h:48
const_iterator last() const
Definition: map.h:232
t_storage_key t_key
Definition: map.h:20
_t_key const & m_key
Definition: map.h:170
const t_self & operator=(const t_what &p_what)
Definition: map.h:164
enumeration_wrapper_var(t_callback &p_callback)
Definition: map.h:215
t_retrieve_key(_t_key &p_key)
Definition: map.h:163
bool get_last(_t_key &p_out) const
Definition: map.h:155
enumeration_wrapper(t_callback &p_callback)
Definition: map.h:206
t_retrieve_key< _t_key > t_self
Definition: map.h:162
t_storage(t_search_set< _t_key, _t_value > const &p_source)
Definition: map.h:188
void set(const _t_key &p_key, const _t_value &p_value)
Definition: map.h:22
bool query_nearest(_t_key &p_key, _t_value &p_value) const
Definition: map.h:110
std::exception exception
Definition: primitives.h:193
void enumerate(t_callback &p_callback)
Definition: map.h:131
iterator first()
Definition: map.h:229
void overwrite(const t_source &p_source)
Definition: map.h:142
static int compare(const t1 &p_item1, const t2 &p_item2)
Definition: map.h:198
bool operator==(const t_self &other) const
Definition: map.h:240
t_content::iterator iterator
Definition: map.h:227
t_content::const_iterator const_iterator
Definition: map.h:226
void operator()(const t_storage &p_item)
Definition: map.h:207
const t_storage * find_ptr(t_param const &p_item) const
Definition: avltree.h:477
t_search_set(const _t_key &p_key, const _t_value &p_value)
Definition: map.h:174
bool exists(const _t_key &p_key) const
Definition: map.h:148
__map_overwrite_wrapper(t_destination &p_destination)
Definition: map.h:9
t_callback & m_callback
Definition: map.h:209
bool operator==(const t_storage &other) const
Definition: map.h:191
t_size get_count() const
Definition: map.h:137
PFC_DECLARE_EXCEPTION(exception_map_entry_not_found, exception,"Map entry not found")
iterator last()
Definition: map.h:230
bool remove(const_iterator const &iter)
Definition: avltree.h:440
bool get_last(t_param &p_item) const
Definition: avltree.h:498
const_iterator last() const
Definition: avltree.h:486
t_storage_value * query_nearest_ptr(_t_key &p_key)
Definition: map.h:102
void remove_all()
Definition: avltree.h:435
static bool equals(const t_self &v1, const t_self &v2)
Definition: map.h:237
bool have_item(const _t_key &p_key) const
Definition: map.h:39
bool remove_item(t_param const &p_item)
Definition: avltree.h:447
bool query(const _t_key &p_key, _t_value &p_value) const
Definition: map.h:44