UNIVERS  15.3
UNIVERS base processing software API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
AssocAr.H
1 /* AssocAr.H */
2 /* $Id: AssocAr.H,v 1.8 2004/04/19 07:37:14 vlad Exp $ */
3 
4 // May be included many times
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include <mix/SortedAr.H>
9 
10 
11 /*************************************************************
12 
13  Macro-expanded template of associative array.
14 
15  The first, you must declare name of target class:
16  #define AssocAr item_ar
17 
18  You must declare type of items too:
19  typedef struct {
20  float key;
21  int c[2];
22  } item_t;
23  #define AssocItemType item_t
24 
25  We mean that item is a variable of type AssocItemType, that
26  is item_t in this example. Here you must specify one of
27  item_t fields which is key nature.
28  #define AssocKeyField key
29 
30  Type of key value (see type of item_t::key here):
31  #define AssocKeyType float
32 
33  How to copy key value to AssocItemType? I mean only temporal
34  operation for item associative search only, not for storeage. By
35  default next code used:
36  #define AssocKeyAssign item.AssocKeyField=key
37  But you may want to define for char[LEN+1] key type:
38  #define AssocKeyAssign strncpy(item.AssocKeyField,key,LEN);\
39  item.AssocKeyField[LEN]='\0'
40 
41  How to compare keys (in strcmp manner)? We mean that there
42  are two variables key1 (left) and key2 (right). Result must
43  be (-1) if key1<key2, (0) if key1==key2 or (1) if ite1>key2.
44  #define AssocKeysCmp(key1,key2) ((key1)-(key2))
45 
46  As usual you can use printing features:
47  #define AssocPrintItem item.print_self();
48  or
49  #define AssocFormatSpec "key=%g c[2]={%d,%d}\n"
50  #define AssocPrintList item.key,item.c[0],item.c[1]
51 
52  *************************************************************/
53 
54 
55 #ifndef AssocAr
56 #error "AssocAr must be defined as name of generated class of array"
57 #endif /* AssocAr */
58 
59 #ifndef AssocItemType
60 #error "AssocItemType must be defined as type of item"
61 #endif /* AssocType */
62 
63 #ifndef AssocKeysCmp
64 #error "AssocKeysCmp(key1,key2) must be defined in strcmp() manner"
65 #endif /* AssocCmp */
66 
67 #ifndef AssocKeyField
68 #error "AssocKeyField must be field in AssocItemType structure"
69 #endif /* AssocKeyField */
70 
71 #ifndef AssocKeyType
72 #error "AssocKeyType must be type of AssocKeyField"
73 #endif /* AssocKeyType */
74 
75 #ifndef AssocArQuant
76 #define AssocArQuant DEFAULT_QUANT
77 #endif /* AssocArQuant */
78 
79 #ifndef AssocArVolume
80 #define AssocArVolume START_VOLUME
81 #endif /* AssocArVolume */
82 
83 
84 class AssocAr : public SortedAr
85 {
86 protected:
87 
88  AssocItemType& ref (unsigned i) const
89  {return *(AssocItemType*)item_ptr(i);};
90 
91 public:
92 
93  AssocAr (const AssocAr& pArray)
94  :SortedAr(pArray) {};
95  AssocAr (unsigned quant = AssocArQuant,
96  unsigned volume = AssocArVolume)
97  :SortedAr(sizeof(AssocItemType), quant, volume) {};
98 
99  // Base associative operations
100  unsigned key_to_index (AssocKeyType key) const
101  {
102  AssocItemType item;
103 #ifdef AssocKeyAssign
104  AssocKeyAssign;
105 #else
106  item.AssocKeyField = key;
107 #endif
108  register int index = quick_find_ascent((const char*)&item);
109  if(-1 == index) Throw(ERROR__DA_UNKNOWN_KEY);
110  return index;
111  }
112  AssocKeyType index_to_key (unsigned index) const
113  {return ref(index).AssocKeyField;}
114 
115  // Usual compare between two elements
116  virtual Compar
117  compare (const char* ptr1, const char* ptr2) const
118  {
119  AssocKeyType key1 = (*(AssocItemType*)ptr1).AssocKeyField;
120  AssocKeyType key2 = (*(AssocItemType*)ptr2).AssocKeyField;
121  return (Compar)AssocKeysCmp(key1, key2);
122  }
123 
124  // Associative operations to get item by key
125  AssocItemType& assoc_fetch (AssocKeyType key)
126  {return ref(key_to_index(key));};
127  AssocItemType assoc_get (AssocKeyType key) const
128  {return ref(key_to_index(key));};
129 
130  // Synonymous
131  AssocItemType& operator[] (AssocKeyType key)
132  {return assoc_fetch(key);};
133  AssocItemType operator() (AssocKeyType key) const
134  {return assoc_get(key);};
135 
136  // Associative operation to add item (with unique key) to array
137  void add (const AssocItemType& val)
138  {
139  if(known_key(val.AssocKeyField)){
140  Throw(ERROR__DA_KNOWN_KEY);
141  }else{
142  SortedAr::addh((const char*)&val);
143  sort(ASCENT_ORDER);
144  }
145  }
146  // Associative operation to add item (unique and non-unique key) to array
147  void put (const AssocItemType& val)
148  {
149  AssocKeyType key=val.AssocKeyField;
150  if(known_key(key)){
151  memcpy(item_ptr(key_to_index(key)), &val, sizeof(AssocItemType));
152  }else{
153  SortedAr::addh((const char*)&val);
154  sort(ASCENT_ORDER);
155  }
156  }
157 
158  // Associative operation to add several items (with unique key) to
159  // array. Number of actually added items is returned.
160  int add (int val_n, const AssocItemType* vals)
161  {
162  if(NULL == vals)
163  Throw(ERROR__NULL);
164 
165  int val_i, added_n = 0;
166  for(val_i = 0; val_i < val_n; ++val_i)
167  if(!known_key(vals[val_i].AssocKeyField)){
168  SortedAr::addh((const char*)(vals + val_i));
169  ++added_n;
170  }
171  sort(ASCENT_ORDER);
172  return added_n;
173  }
174  // Associative operation to add several items (unique and non-unique
175  // key) to array
176  void put (int val_n, const AssocItemType* vals)
177  {
178  if(NULL == vals)
179  Throw(ERROR__NULL);
180 
181  int val_i;
182  for(val_i = 0; val_i < val_n; ++val_i){
183  AssocKeyType key = vals[val_i].AssocKeyField;
184  if(known_key(key))
185  memcpy(item_ptr(key_to_index(key)), vals + val_i,
186  sizeof(AssocItemType));
187  else
188  SortedAr::addh((const char*)(vals + val_i));
189  }
190  sort(ASCENT_ORDER);
191  }
192 
193  // Associative operation to find thether this key exist in array
194  Logic known_key (AssocKeyType key) const
195  {
196  AssocItemType item;
197 #ifdef AssocKeyAssign
198  AssocKeyAssign;
199 #else
200  item.AssocKeyField = key;
201 #endif
202  register int index = quick_find_ascent((const char*)&item);
203  return (-1 != index);
204  }
205 
206  // Add usual operations to be this array accessible as AnyAr
207  AssocItemType& fetch (unsigned i)
208  {return ref(i);};
209  AssocItemType get (unsigned i) const
210  {return ref(i);};
211 
212  // Smart print
213 #ifdef AssocPrintItem
214  virtual void print_item (unsigned i) const
215  {AssocItemType&item=ref(i);AssocPrintItem;}
216 #undef AssocPrintItem
217 #elif defined(AssocFormatSpec) && defined(AssocPrintList)
218  virtual void print_item (unsigned i) const
219  {AssocItemType&item=ref(i);
220  fprintf(stderr, AssocFormatSpec, AssocPrintList);}
221 #undef AssocFormatSpec
222 #undef AssocPrintList
223 #endif
224 
225 };
226 
227 #undef AssocAr
228 #undef AssocItemType
229 #undef AssocKeyField
230 #undef AssocKeyType
231 #undef AssocKeysCmp
232 #undef AssocKeyAssign
Definition: SortedAr.H:14
Definition: AssocAr.H:84