Wondercoll
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
_cvlist.h
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 
42 #ifndef _CV_LIST_H_
43 #define _CV_LIST_H_
44 
45 #include <stdlib.h>
46 #include <assert.h>
47 
48 #define CV_FORCE_INLINE CV_INLINE
49 
50 #if !defined(_LIST_INLINE)
51 #define _LIST_INLINE CV_FORCE_INLINE
52 #endif /*_LIST_INLINE*/
53 
54 #if defined DECLARE_LIST
55 #if defined _MSC_VER && _MSC_VER >= 1200
56  #pragma warning("DECLARE_LIST macro is already defined!")
57 #endif
58 #endif /*DECLARE_LIST*/
59 
60 static const long default_size = 10;
61 static const long default_inc_size = 10;
62 
63 struct _pos
64 {
65  void* m_pos;
66 #ifdef _DEBUG
67  struct _list* m_list;
68 #endif /*_DEBUG*/
69 };
70 typedef struct _pos CVPOS;
71 struct _list
72 {
73  void* m_buffer;
75  long m_buf_size; /* The size of the buffer */
76  long m_size; /* The number of elements */
80 };
81 
82 typedef struct _list _CVLIST;
83 
84 #define DECLARE_LIST(type, prefix)\
85  /* Basic element of a list*/\
86  struct prefix##element_##type\
87  {\
88  struct prefix##element_##type* m_prev;\
89  struct prefix##element_##type* m_next;\
90  type m_data;\
91  };\
92  typedef struct prefix##element_##type ELEMENT_##type;\
93  /* Initialization and destruction*/\
94  _LIST_INLINE _CVLIST* prefix##create_list_##type(long);\
95  _LIST_INLINE void prefix##destroy_list_##type(_CVLIST*);\
96  /* Access functions*/\
97  _LIST_INLINE CVPOS prefix##get_head_pos_##type(_CVLIST*);\
98  _LIST_INLINE CVPOS prefix##get_tail_pos_##type(_CVLIST*);\
99  _LIST_INLINE type* prefix##get_next_##type(CVPOS*);\
100  _LIST_INLINE type* prefix##get_prev_##type(CVPOS*);\
101  /* Modification functions*/\
102  _LIST_INLINE void prefix##clear_list_##type(_CVLIST*);\
103  _LIST_INLINE CVPOS prefix##add_head_##type(_CVLIST*, type*);\
104  _LIST_INLINE CVPOS prefix##add_tail_##type(_CVLIST*, type*);\
105  _LIST_INLINE void prefix##remove_head_##type(_CVLIST*);\
106  _LIST_INLINE void prefix##remove_tail_##type(_CVLIST*);\
107  _LIST_INLINE CVPOS prefix##insert_before_##type(_CVLIST*, CVPOS, type*);\
108  _LIST_INLINE CVPOS prefix##insert_after_##type(_CVLIST*, CVPOS, type*);\
109  _LIST_INLINE void prefix##remove_at_##type(_CVLIST*, CVPOS);\
110  _LIST_INLINE void prefix##set_##type(CVPOS, type*);\
111  _LIST_INLINE type* prefix##get_##type(CVPOS);\
112  /* Statistics functions*/\
113  _LIST_INLINE int prefix##get_count_##type(_CVLIST*);
114 
115 /* This macro finds a space for a new element and puts in into 'element' pointer */
116 #define INSERT_NEW(element_type, l, element)\
117  l->m_size++;\
118  if(l->m_head_free.m_pos != NULL)\
119  {\
120  element = (element_type*)(l->m_head_free.m_pos);\
121  if(element->m_next != NULL)\
122  {\
123  element->m_next->m_prev = NULL;\
124  l->m_head_free.m_pos = element->m_next;\
125  }\
126  else\
127  {\
128  l->m_head_free.m_pos = NULL;\
129  }\
130  }\
131  else\
132  {\
133  if(l->m_buf_size < l->m_size && l->m_head_free.m_pos == NULL)\
134  {\
135  *(void**)l->m_buffer = cvAlloc(l->m_buf_size*sizeof(element_type) + sizeof(void*));\
136  l->m_buffer = *(void**)l->m_buffer;\
137  *(void**)l->m_buffer = NULL;\
138  element = (element_type*)((char*)l->m_buffer + sizeof(void*));\
139  }\
140  else\
141  {\
142  element = (element_type*)((char*)l->m_buffer + sizeof(void*)) + l->m_size - 1;\
143  }\
144  }
145 
146 /* This macro adds 'element' to the list of free elements*/
147 #define INSERT_FREE(element_type, l, element)\
148  if(l->m_head_free.m_pos != NULL)\
149  {\
150  ((element_type*)l->m_head_free.m_pos)->m_prev = element;\
151  }\
152  element->m_next = ((element_type*)l->m_head_free.m_pos);\
153  l->m_head_free.m_pos = element;
154 
155 
156 /*#define GET_FIRST_FREE(l) ((ELEMENT_##type*)(l->m_head_free.m_pos))*/
157 
158 #define IMPLEMENT_LIST(type, prefix)\
159 _CVLIST* prefix##create_list_##type(long size)\
160 {\
161  _CVLIST* pl = (_CVLIST*)cvAlloc(sizeof(_CVLIST));\
162  pl->m_buf_size = size > 0 ? size : default_size;\
163  pl->m_first_buffer = cvAlloc(pl->m_buf_size*sizeof(ELEMENT_##type) + sizeof(void*));\
164  pl->m_buffer = pl->m_first_buffer;\
165  *(void**)pl->m_buffer = NULL;\
166  pl->m_size = 0;\
167  pl->m_head.m_pos = NULL;\
168  pl->m_tail.m_pos = NULL;\
169  pl->m_head_free.m_pos = NULL;\
170  return pl;\
171 }\
172 void prefix##destroy_list_##type(_CVLIST* l)\
173 {\
174  void* cur = l->m_first_buffer;\
175  void* next;\
176  while(cur)\
177  {\
178  next = *(void**)cur;\
179  cvFree(&cur);\
180  cur = next;\
181  }\
182  cvFree(&l);\
183 }\
184 CVPOS prefix##get_head_pos_##type(_CVLIST* l)\
185 {\
186  return l->m_head;\
187 }\
188 CVPOS prefix##get_tail_pos_##type(_CVLIST* l)\
189 {\
190  return l->m_tail;\
191 }\
192 type* prefix##get_next_##type(CVPOS* pos)\
193 {\
194  if(pos->m_pos)\
195  {\
196  ELEMENT_##type* element = (ELEMENT_##type*)(pos->m_pos);\
197  pos->m_pos = element->m_next;\
198  return &element->m_data;\
199  }\
200  else\
201  {\
202  return NULL;\
203  }\
204 }\
205 type* prefix##get_prev_##type(CVPOS* pos)\
206 {\
207  if(pos->m_pos)\
208  {\
209  ELEMENT_##type* element = (ELEMENT_##type*)(pos->m_pos);\
210  pos->m_pos = element->m_prev;\
211  return &element->m_data;\
212  }\
213  else\
214  {\
215  return NULL;\
216  }\
217 }\
218 int prefix##is_pos_##type(CVPOS pos)\
219 {\
220  return !!pos.m_pos;\
221 }\
222 void prefix##clear_list_##type(_CVLIST* l)\
223 {\
224  l->m_head.m_pos = NULL;\
225  l->m_tail.m_pos = NULL;\
226  l->m_size = 0;\
227  l->m_head_free.m_pos = NULL;\
228 }\
229 CVPOS prefix##add_head_##type(_CVLIST* l, type* data)\
230 {\
231  ELEMENT_##type* element;\
232  INSERT_NEW(ELEMENT_##type, l, element);\
233  element->m_prev = NULL;\
234  element->m_next = (ELEMENT_##type*)(l->m_head.m_pos);\
235  memcpy(&(element->m_data), data, sizeof(*data));\
236  if(element->m_next)\
237  {\
238  element->m_next->m_prev = element;\
239  }\
240  else\
241  {\
242  l->m_tail.m_pos = element;\
243  }\
244  l->m_head.m_pos = element;\
245  return l->m_head;\
246 }\
247 CVPOS prefix##add_tail_##type(_CVLIST* l, type* data)\
248 {\
249  ELEMENT_##type* element;\
250  INSERT_NEW(ELEMENT_##type, l, element);\
251  element->m_next = NULL;\
252  element->m_prev = (ELEMENT_##type*)(l->m_tail.m_pos);\
253  memcpy(&(element->m_data), data, sizeof(*data));\
254  if(element->m_prev)\
255  {\
256  element->m_prev->m_next = element;\
257  }\
258  else\
259  {\
260  l->m_head.m_pos = element;\
261  }\
262  l->m_tail.m_pos = element;\
263  return l->m_tail;\
264 }\
265 void prefix##remove_head_##type(_CVLIST* l)\
266 {\
267  ELEMENT_##type* element = ((ELEMENT_##type*)(l->m_head.m_pos));\
268  if(element->m_next != NULL)\
269  {\
270  element->m_next->m_prev = NULL;\
271  }\
272  l->m_head.m_pos = element->m_next;\
273  INSERT_FREE(ELEMENT_##type, l, element);\
274  l->m_size--;\
275 }\
276 void prefix##remove_tail_##type(_CVLIST* l)\
277 {\
278  ELEMENT_##type* element = ((ELEMENT_##type*)(l->m_tail.m_pos));\
279  if(element->m_prev != NULL)\
280  {\
281  element->m_prev->m_next = NULL;\
282  }\
283  l->m_tail.m_pos = element->m_prev;\
284  INSERT_FREE(ELEMENT_##type, l, element);\
285  l->m_size--;\
286 }\
287 CVPOS prefix##insert_after_##type(_CVLIST* l, CVPOS pos, type* data)\
288 {\
289  ELEMENT_##type* element;\
290  ELEMENT_##type* before;\
291  CVPOS newpos;\
292  INSERT_NEW(ELEMENT_##type, l, element);\
293  memcpy(&(element->m_data), data, sizeof(*data));\
294  before = (ELEMENT_##type*)pos.m_pos;\
295  element->m_prev = before;\
296  element->m_next = before->m_next;\
297  before->m_next = element;\
298  if(element->m_next != NULL)\
299  element->m_next->m_prev = element;\
300  else\
301  l->m_tail.m_pos = element;\
302  newpos.m_pos = element;\
303  return newpos;\
304 }\
305 CVPOS prefix##insert_before_##type(_CVLIST* l, CVPOS pos, type* data)\
306 {\
307  ELEMENT_##type* element;\
308  ELEMENT_##type* after;\
309  CVPOS newpos;\
310  INSERT_NEW(ELEMENT_##type, l, element);\
311  memcpy(&(element->m_data), data, sizeof(*data));\
312  after = (ELEMENT_##type*)pos.m_pos;\
313  element->m_prev = after->m_prev;\
314  element->m_next = after;\
315  after->m_prev = element;\
316  if(element->m_prev != NULL)\
317  element->m_prev->m_next = element;\
318  else\
319  l->m_head.m_pos = element;\
320  newpos.m_pos = element;\
321  return newpos;\
322 }\
323 void prefix##remove_at_##type(_CVLIST* l, CVPOS pos)\
324 {\
325  ELEMENT_##type* element = ((ELEMENT_##type*)pos.m_pos);\
326  if(element->m_prev != NULL)\
327  {\
328  element->m_prev->m_next = element->m_next;\
329  }\
330  else\
331  {\
332  l->m_head.m_pos = element->m_next;\
333  }\
334  if(element->m_next != NULL)\
335  {\
336  element->m_next->m_prev = element->m_prev;\
337  }\
338  else\
339  {\
340  l->m_tail.m_pos = element->m_prev;\
341  }\
342  INSERT_FREE(ELEMENT_##type, l, element);\
343  l->m_size--;\
344 }\
345 void prefix##set_##type(CVPOS pos, type* data)\
346 {\
347  ELEMENT_##type* element = ((ELEMENT_##type*)(pos.m_pos));\
348  memcpy(&(element->m_data), data, sizeof(data));\
349 }\
350 type* prefix##get_##type(CVPOS pos)\
351 {\
352  ELEMENT_##type* element = ((ELEMENT_##type*)(pos.m_pos));\
353  return &(element->m_data);\
354 }\
355 int prefix##get_count_##type(_CVLIST* list)\
356 {\
357  return list->m_size;\
358 }
359 
360 #define DECLARE_AND_IMPLEMENT_LIST(type, prefix)\
361  DECLARE_LIST(type, prefix)\
362  IMPLEMENT_LIST(type, prefix)
363 
364 typedef struct __index
365 {
366  int value;
367  float rho, theta;
368 }
369 _index;
370 
371 DECLARE_LIST( _index, h_ )
372 
373 #endif/*_CV_LIST_H_*/