vmap.h
1 /*************************************************************************/
2 /* vmap.h */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* http://www.godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
9 /* */
10 /* Permission is hereby granted, free of charge, to any person obtaining */
11 /* a copy of this software and associated documentation files (the */
12 /* "Software"), to deal in the Software without restriction, including */
13 /* without limitation the rights to use, copy, modify, merge, publish, */
14 /* distribute, sublicense, and/or sell copies of the Software, and to */
15 /* permit persons to whom the Software is furnished to do so, subject to */
16 /* the following conditions: */
17 /* */
18 /* The above copyright notice and this permission notice shall be */
19 /* included in all copies or substantial portions of the Software. */
20 /* */
21 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
22 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
23 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
24 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
25 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
26 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
27 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
28 /*************************************************************************/
29 #ifndef VMAP_H
30 #define VMAP_H
31 
32 #include "typedefs.h"
33 #include "vector.h"
34 
35 template<class T,class V>
36 class VMap {
37 
38  struct _Pair {
39 
40  T key;
41  V value;
42 
43  _FORCE_INLINE_ _Pair() {}
44 
45  _FORCE_INLINE_ _Pair(const T& p_key, const V& p_value) {
46 
47  key=p_key;
48  value=p_value;
49  }
50 
51  };
52 
53  Vector<_Pair> _data;
54 
55  _FORCE_INLINE_ int _find(const T& p_val,bool &r_exact) const {
56 
57  r_exact=false;
58  if (_data.empty())
59  return 0;
60 
61  int low = 0;
62  int high = _data.size() -1;
63  int middle;
64  const _Pair *a=&_data[0];
65 
66  while( low <= high )
67  {
68  middle = ( low + high ) / 2;
69 
70  if( p_val < a[ middle].key ) {
71  high = middle - 1; //search low end of array
72  } else if ( a[middle].key < p_val) {
73  low = middle + 1; //search high end of array
74  } else {
75  r_exact=true;
76  return middle;
77  }
78  }
79 
80  //return the position where this would be inserted
81  if (a[middle].key<p_val)
82  middle++;
83  return middle;
84  }
85 
86  _FORCE_INLINE_ int _find_exact(const T& p_val) const {
87 
88  if (_data.empty())
89  return -1;
90 
91  int low = 0;
92  int high = _data.size() -1;
93  int middle;
94  const _Pair *a=&_data[0];
95 
96  while( low <= high )
97  {
98  middle = ( low + high ) / 2;
99 
100  if( p_val < a[ middle].key ) {
101  high = middle - 1; //search low end of array
102  } else if ( a[middle].key < p_val) {
103  low = middle + 1; //search high end of array
104  } else {
105  return middle;
106  }
107  }
108 
109  return -1;
110  }
111 
112 public:
113 
114  int insert(const T& p_key,const V& p_val) {
115 
116  bool exact;
117  int pos = _find(p_key,exact);
118  if (exact) {
119  _data[pos].value=p_val;
120  return pos;
121  }
122  _data.insert(pos,_Pair(p_key,p_val));
123  return pos;
124  }
125 
126  bool has(const T& p_val) const {
127 
128  return _find_exact(p_val)!=-1;
129  }
130 
131  void erase(const T& p_val) {
132 
133  int pos = _find_exact(p_val);
134  if (pos<0)
135  return;
136  _data.remove(pos);
137  }
138 
139  int find(const T& p_val) const {
140 
141  return _find_exact(p_val);
142 
143  }
144 
145  int find_nearest(const T& p_val) const {
146 
147  bool exact;
148  return _find(p_val,exact);
149 
150  }
151 
152  _FORCE_INLINE_ int size() const { return _data.size(); }
153  _FORCE_INLINE_ bool empty() const { return _data.empty(); }
154 
155 
156  const _Pair *get_array() const {
157 
158  return _data.ptr();
159  }
160 
161  _Pair *get_array() {
162 
163  return _data.ptr();
164  }
165 
166 
167  const V& getv(int p_index) const {
168 
169  return _data[p_index].value;
170  }
171 
172  V& getv(int p_index) {
173 
174  return _data[p_index].value;
175  }
176 
177 
178  const T& getk(int p_index) const {
179 
180  return _data[p_index].key;
181  }
182 
183  T& getk(int p_index) {
184 
185  return _data[p_index].key;
186  }
187 
188 
189  inline const V& operator[](const T& p_key) const {
190 
191  int pos = _find_exact(p_key);
192  if (pos<0) {
193  const T& aux=*((T*)0); //nullreturn
194  ERR_FAIL_COND_V(pos<1,aux);
195  }
196 
197  return _data[pos].value;
198  }
199 
200 
201 
202  inline V& operator[](const T& p_key) {
203 
204  int pos = _find_exact(p_key);
205  if (pos<0) {
206  V val;
207  pos = insert(p_key,val);
208 
209  }
210 
211  return _data[pos].value;
212  }
213 
214 
215 
216 };
217 #endif // VMAP_H
Definition: vmap.h:36