GUIDOLib  1.7.7
Guido Engine Internal Documentation
kf_vect.h
1 #ifndef KF_Vector_H
2 #define KF_Vector_H
3 
4 /*
5  GUIDO Library
6  Copyright (C) 2002 Holger Hoos, Juergen Kilian, Kai Renz
7  Copyright (C) 2002-2017 Grame
8 
9  This Source Code Form is subject to the terms of the Mozilla Public
10  License, v. 2.0. If a copy of the MPL was not distributed with this
11  file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 
13  Grame Research Laboratory, 11, cours de Verdun Gensoul 69002 Lyon - France
14  research@grame.fr
15 
16 */
21 #include <climits>
22 #include <cstdlib> // for alloc, realloc, memmove...
23 #include <cstring> // for memmove
24 // #include <cstddef> // for memmove
25 // #include "defines.h"
26 // #include <cassert>
27 
28 #include "kf_list.h"
29 
30 
31 #define KF_VECTOR_MININDEX INT_MIN
32 #define KF_VECTOR_MAXINDEX INT_MAX
33 
34 template <class TYPE>
35 class KF_Vector
36 {
37  public:
38  KF_Vector(TYPE p_noelement);
39  KF_Vector(TYPE p_noelement, TYPE * newdata, int newmemsize, int newindexoffset,
40  int newminimum, int newmaximum, int newcount);
41 
42  virtual ~KF_Vector() { free(data); }
43 
44  // - STL-like interface
45  int size() const { return GetCount(); }
46  bool empty() const { return size() == 0; }
47 
48  //void SetMaximum(int index);
49  //void SetMinimum(int index);
50 
51  void RemoveAll();
52  int GetNextIndex(int index) const;
53  void Set(int index, TYPE mydata);
54 
55  virtual void Cut(int index,KF_Vector<TYPE> **pnew);
56  virtual void Delete(int index);
57 
58  TYPE Get(int index) const; // replaced by at()
59  int GetMaximum() const
60  {
61  assert(maximum - indexoffset + 1 <= memsize );
62  return maximum;
63  }
64 
65  int GetMinimum() const
66  {
67  assert( minimum - indexoffset >= 0 ) ;
68  return minimum;
69  }
70 
71  int GetCount() const // replaced by size()
72  {
73  assert( count <= memsize);
74  return count;
75  }
76 
77  protected:
78  // this routine is needed to resize the memory area index is the new index that is needed .....
79  void Resize(int index);
80 
81  TYPE noelement;
82  int maximum;
83  int minimum;
84 
85  int count;
87 
88  TYPE * data;
89  int memsize;
90 };
91 
92 
93 template <class TYPE>
94 KF_Vector<TYPE>::KF_Vector(TYPE p_noelement)
95 {
96  minimum = 0;
97  maximum = -1;
98  memsize = 10;
99  data = (TYPE *) malloc( memsize * sizeof(TYPE));
100 
101  indexoffset = 0;
102  noelement = p_noelement;
103 
104  int i = 0;
105  for (i=0;i<memsize;i++)
106  {
107  // initialize with zeroelement ....
108  data[i] = noelement;
109  }
110  count = 0;
111 }
112 
113 template <class TYPE>
114 KF_Vector<TYPE>::KF_Vector(TYPE p_noelement,TYPE * newdata,int newmemsize,
115  int newindexoffset,int newminimum,int newmaximum,int newcount)
116 {
117  noelement = p_noelement;
118  data = newdata;
119  memsize = newmemsize;
120  count = newcount;
121  indexoffset = newindexoffset;
122  minimum = newminimum;
123  maximum = newmaximum;
124 
125 }
126 
127 template <class TYPE>
128 void KF_Vector<TYPE>::Set(int index, TYPE mydata)
129 {
130  int mymemindex = index - indexoffset;
131 
132  if (mymemindex < 0 || mymemindex >= memsize)
133  {
134  // we have to resize
135  do {
136  Resize(index);
137  mymemindex = index - indexoffset;
138  if (mymemindex >= 0 && mymemindex < memsize)
139  {
140  if (data[mymemindex] == noelement && mydata != noelement)
141  ++ count;
142  if (data[mymemindex] != noelement && mydata == noelement)
143  -- count;
144 
145  data[mymemindex] = mydata;
146  break;
147  }
148  } while (true);
149  }
150  else
151  {
152  if (data[mymemindex] == noelement && mydata != noelement)
153  ++ count;
154  if (data[mymemindex] != noelement && mydata == noelement)
155  -- count;
156  // then the index is already in the data ....
157  data[mymemindex] = mydata;
158  }
159 
160 
161  if (mydata != noelement)
162  {
163  if (count == 1)
164  {
165  minimum = maximum = index;
166  }
167  else
168  {
169  if (index < minimum)
170  minimum = index;
171  if (index > maximum)
172  maximum = index;
173  }
174  }
175  else
176  {
177  if (count == 0)
178  {
179  minimum = 0;
180  maximum = -1;
181  }
182  else // we have to find a new minimum and maximum
183  {
184  //int newmin = minimum;
185  //int newmax = maximum;
186  int i;
187  for (i=minimum;i<=maximum;++i)
188  {
189  if (data[i-indexoffset] != noelement)
190  {
191  minimum = i;
192  break;
193  }
194  }
195  for (i=maximum;i>=minimum;--i)
196  {
197  if (data[i-indexoffset] != noelement)
198  {
199  maximum = i;
200  break;
201  }
202  }
203  }
204 
205  }
206  assert(maximum - minimum <= memsize);
207 }
208 
211 template <class TYPE>
212 void KF_Vector<TYPE>::Delete(int index)
213 {
214  if (index < minimum)
215  {
216  assert(false);
217  return;
218  }
219  if (index > maximum )
220  {
221  assert(false);
222  return;
223  }
224 
225  int mymemindex = index - indexoffset;
226 
227  assert(mymemindex < memsize);
228 
229  if (data[mymemindex] != noelement)
230  {
231  data[mymemindex] = noelement;
232  --count;
233  }
234 
235  if (count == 0)
236  {
237  minimum = 0;
238  maximum = -1;
239 
240  }
241  else if (count == 1)
242  {
243  if (index == minimum)
244  minimum = maximum;
245  else if (index == maximum)
246  maximum = minimum;
247  }
248  else
249  {
250  if (index == minimum)
251  {
252 
253  int newminimum = maximum;
254  int i=0;
255  for (i=minimum+1;i<=maximum;i++)
256  {
257  if (data[i - indexoffset] != noelement)
258  {
259  newminimum = i;
260  break;
261  }
262  }
263  minimum = newminimum;
264  }
265  else if (index == maximum)
266  {
267 
268  int newmaximum = minimum;
269  int i=0;
270  for (i=maximum-1;i>=minimum;i--)
271  {
272  if (data[i-indexoffset] != noelement)
273  {
274  newmaximum = i;
275  break;
276  }
277  }
278  maximum = newmaximum;
279  }
280  }
281 
282  if (maximum < minimum)
283  {
284  minimum = 0;
285  maximum = -1;
286  assert(count == 0);
287  }
288 }
289 
293 template <class TYPE>
294 TYPE KF_Vector<TYPE>::Get(int index) const
295 {
296  if (index < minimum) return noelement;
297  if (index > maximum ) return noelement;
298 
299  const int mymemindex = index - indexoffset;
300 
301  assert(mymemindex < memsize);
302 
303  return data[mymemindex];
304 }
305 
306 template <class TYPE>
307 int KF_Vector<TYPE>::GetNextIndex(int index) const
308 {
309 
310  if (index < minimum)
311  return KF_VECTOR_MININDEX;
312  if (index > maximum )
313  return KF_VECTOR_MININDEX;
314 
315  int mymemindex = index - indexoffset;
316  assert(mymemindex < memsize);
317 
318 
319  int tmpindex;
320  for (tmpindex=mymemindex+1;tmpindex<= maximum-indexoffset;tmpindex++)
321  {
322  if (data[tmpindex] != noelement)
323  return tmpindex + indexoffset;
324  }
325 
326  return KF_VECTOR_MININDEX;
327 
328 }
329 
330 template <class TYPE>
332 {
333  // this removes all
334  // just start a new. Because this is not a "owns"-element
335  // situation, we can just get a new array ...
336 
337  int i;
338  for (i=0;i<memsize;i++)
339  {
340  if (data[i] != noelement)
341  Delete(i+indexoffset);
342  }
343 
344  free(data);
345 
346  memsize = 10;
347  data = (TYPE *) malloc(memsize * sizeof(TYPE));
348  for (i=0;i<memsize;i++)
349  {
350  data[i] = noelement;
351  }
352 
353  maximum = -1;
354  minimum = 0;
355  indexoffset = 0;
356  count = 0;
357 }
358 
365 template <class TYPE>
366 void KF_Vector<TYPE>::Cut( int index, KF_Vector<TYPE> **pnew )
367 {
368  *pnew = NULL;
369  if (index< minimum)
370  return;
371  if (index>maximum)
372  return;
373 
374  int mymemindex = index - indexoffset;
375 
376  int newmin = INT_MAX;
377  int newmax = INT_MIN;
378 
379  int newsize = maximum - index;
380  if (newsize > 0)
381  {
382  // we make sure, that there are -10 left and +10 on the
383  // right hand side ....
384  int newindexoffset = 10;
385 
386  TYPE * newdata = (TYPE *) malloc((newsize + 2 * newindexoffset ) * sizeof( TYPE ) );
387 
388  int i;
389  int newcount = 0;
390  for (i=0;i<newindexoffset;i++)
391  {
392  newdata[i] = noelement;
393  }
394  for (i=newindexoffset;i<newsize+newindexoffset;i++)
395  {
396  newdata[i] = data[mymemindex + 1 + i - newindexoffset] ;
397  if (newdata[i] != noelement)
398  {
399  int tmpindex = mymemindex + indexoffset + i - newindexoffset;
400  if (tmpindex < newmin)
401  newmin = tmpindex;
402  if (tmpindex > newmax)
403  newmax = tmpindex;
404  newcount++;
405  data[mymemindex + 1 + i - newindexoffset] = noelement;
406  }
407  }
408  for (i=newsize+newindexoffset;i<newsize+2*newindexoffset;i++)
409  {
410  newdata[i] = noelement;
411  }
412 
413  if (newmin > newmax)
414  {
415  newmin = 0;
416  newmax = -1;
417  assert(newcount == 0);
418  }
419  // create the new vector.
420  *pnew = new KF_Vector<TYPE>(noelement,newdata,newsize+2*newindexoffset,
421  index + 1 - newindexoffset,newmin, newmax, newcount); // index+1,maximum,newcount);
422 
423 
424  // we have to change the maximum and minimum and also the elements ....
425  count = count - newcount;
426  if (count == 0)
427  {
428  minimum = 0;
429  maximum = -1;
430  }
431  else
432  {
433  int newmaximum = index;
434  while (newmaximum >= minimum &&
435  data[newmaximum - indexoffset] == noelement)
436  --newmaximum;
437 
438  maximum = newmaximum;
439  }
440  }
441  else
442  {
443  // the new vector has no size ....
444  *pnew = new KF_Vector<TYPE>(noelement);
445  }
446 
447  // first find the location of the cut.
448 }
449 
450 
451 // index is the index without indexoffset ...
452 template <class TYPE>
453 void KF_Vector<TYPE>::Resize(int index)
454 {
455  int newmemsize = memsize;
456  int offset = 0;
457  int mymemindex = index - indexoffset;
458 
459  if (mymemindex < 0)
460  {
461  // then we have to increase the array to the left ....
462  do // wow!
463  {
464  if (newmemsize <= 10)
465  {
466  newmemsize = 32;
467  offset = 6;
468  }
469  else if (newmemsize <=20)
470  {
471  newmemsize = 60;
472  offset = 10;
473  }
474  else if (newmemsize <=100)
475  {
476  newmemsize = 240;
477  offset = 20;
478  }
479  else if (newmemsize <= 500)
480  {
481  newmemsize = 560;
482  offset = 30;
483  }
484  else
485  {
486  newmemsize = newmemsize + 560;
487  offset = 60;
488  }
489  }
490  while( mymemindex < memsize - (newmemsize - (offset*2)) );
491 
492  int indexofnew = -index + offset;
493 /* data = (TYPE *) realloc(data,(newmemsize * sizeof(TYPE))); */
494  data = (TYPE *) realloc(data,(newmemsize * sizeof(TYPE)) + indexofnew);
495  assert(data);
496 
497 // int indexofnew = -index + offset;
498  // this moves the data to the right ...
499  memmove(&(data[indexofnew]),data,memsize * sizeof(TYPE));
500 
501  int cnt;
502  for (cnt=0;cnt<indexofnew;++cnt)
503  data[cnt] = noelement;
504 
505  for (cnt=indexofnew + memsize;cnt<newmemsize;cnt++)
506  data[cnt] = noelement;
507 
508  indexoffset = indexoffset + index - offset;
509  memsize = newmemsize;
510  }
511  else if (mymemindex >= newmemsize ) {
512  do {
513  if (newmemsize <= 10) {
514  newmemsize = 32;
515  offset = 6;
516  }
517  else if (newmemsize <=20) {
518  newmemsize = 60;
519  offset = 10;
520  }
521  else if (newmemsize <=100) {
522  newmemsize = 240;
523  offset = 20;
524  }
525  else if (newmemsize <= 500) {
526  newmemsize = 560;
527  offset = 30;
528  }
529  else {
530  newmemsize = newmemsize + 560;
531  offset = 60;
532  }
533  } while( mymemindex >= newmemsize - (offset * 2) );
534 
535 /* data = (TYPE *) realloc(data,(newmemsize * sizeof(TYPE))); */
536  data = (TYPE *) realloc(data,(newmemsize * sizeof(TYPE)) + offset);
537  assert(data);
538 
539  // this moves the data to the right ...
540  memmove(&(data[offset]), data, memsize * sizeof(TYPE));
541 
542  int cnt;
543  for (cnt=0;cnt<offset;++cnt)
544  data[cnt] = noelement;
545  for (cnt=offset + memsize;cnt<newmemsize;cnt++)
546  data[cnt] = noelement;
547 
548  indexoffset = indexoffset - offset;
549  memsize = newmemsize;
550  }
551 }
552 
553 #endif
KF_Vector::size
int size() const
Definition: kf_vect.h:45
KF_Vector::count
int count
Definition: kf_vect.h:85
KF_Vector::Get
TYPE Get(int index) const
Returns element[index] if existing and noelement if element[index] doesn't exist.
Definition: kf_vect.h:294
KF_Vector::GetNextIndex
int GetNextIndex(int index) const
Definition: kf_vect.h:307
KF_Vector::Set
void Set(int index, TYPE mydata)
Definition: kf_vect.h:128
KF_Vector::GetCount
int GetCount() const
Definition: kf_vect.h:71
KF_Vector::GetMinimum
int GetMinimum() const
Definition: kf_vect.h:65
KF_Vector::noelement
TYPE noelement
Definition: kf_vect.h:81
KF_Vector::RemoveAll
void RemoveAll()
Definition: kf_vect.h:331
KF_Vector::memsize
int memsize
Definition: kf_vect.h:89
KF_Vector::GetMaximum
int GetMaximum() const
Definition: kf_vect.h:59
KF_Vector::indexoffset
int indexoffset
Definition: kf_vect.h:86
KF_Vector::Delete
virtual void Delete(int index)
Deletes an Element at position index.
Definition: kf_vect.h:212
KF_Vector::data
TYPE * data
Definition: kf_vect.h:88
KF_Vector::minimum
int minimum
Definition: kf_vect.h:83
KF_Vector::maximum
int maximum
Definition: kf_vect.h:82
KF_Vector::KF_Vector
KF_Vector(TYPE p_noelement)
Definition: kf_vect.h:94
KF_Vector
Definition: kf_vect.h:35
KF_Vector::empty
bool empty() const
Definition: kf_vect.h:46
KF_Vector::~KF_Vector
virtual ~KF_Vector()
Definition: kf_vect.h:42
KF_Vector::Cut
virtual void Cut(int index, KF_Vector< TYPE > **pnew)
Cuts a vector in two.
Definition: kf_vect.h:366
KF_Vector::Resize
void Resize(int index)
Definition: kf_vect.h:453

Guido Project Copyright © 2019 Grame-CNCM