Edinburgh Speech Tools  2.4-release
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
EST_TKVL.cc
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor */
34 /* Date : May 1995 */
35 /*-----------------------------------------------------------------------*/
36 /* Key/value List Class source file */
37 /* */
38 /*=======================================================================*/
39 
40 #include <cstdlib>
41 #include "EST_TKVL.h"
42 #include "EST_error.h"
43 
44 template <class K, class V> EST_TKVL<K, V>::EST_TKVL(const EST_TKVL<K, V> &kv)
45 {
46  list = kv.list;
47 }
48 
49 template <class K, class V>
51 {
52  list.clear();
53 }
54 
55 template <class K, class V>
56 EST_Litem *EST_TKVL<K, V>::find_pair_key(const K &key) const
57 {
58  EST_Litem *ptr;
59 
60  for (ptr = list.head(); ptr != 0; ptr= ptr->next())
61  if (list.item(ptr).k == key)
62  return ptr;
63  return 0;
64 }
65 
66 template <class K, class V>
67 EST_Litem *EST_TKVL<K, V>::find_pair_val(const V &val) const
68 {
69  EST_Litem *ptr;
70 
71 /// cout << "function list\n" << endl;
72 
73  for (ptr = list.head(); ptr != 0; ptr= ptr->next())
74  {
75 // cout << "ff: " << list.item(ptr).k << endl;
76  if (list.item(ptr).v == val)
77  return ptr;
78  }
79  return 0;
80 }
81 
82 
83 // look for pointer kptr in list. If found, change its value to rval and
84 // return true, otherwise return false.
85 
86 template <class K, class V>
87 int EST_TKVL<K, V>::change_val(EST_Litem *kptr, const V &rval)
88 {
89  if (list.index(kptr) == -1)
90  return 0;
91  else
92  {
93  list.item(kptr).v = rval;
94  return 1;
95  }
96 }
97 
98 template <class K, class V>
99 int EST_TKVL<K, V>::change_key(EST_Litem *kptr, const K &rkey)
100 {
101  if (list.index(kptr) == -1)
102  return 0;
103  else
104  {
105  list.item(kptr).k = rkey;
106  return 1;
107  }
108 }
109 
110 // look for key rkey in list. If found, change its value to rval and
111 // return true, otherwise return false.
112 template <class K, class V>
113 int EST_TKVL<K, V>::change_val(const K &rkey,const V &rval)
114 {
115  EST_Litem *ptr=find_pair_key(rkey);
116  if (ptr == 0)
117  return 0;
118  else
119  {
120  list.item(ptr).v = rval;
121  return 1;
122  }
123 }
124 
125 // NOTE: This _MUST_NOT_ change the EST_TKVL, if it needs to, a separate
126 // const version will need to replace the dummy one below.
127 
128 template<class K, class V>
129 V &EST_TKVL<K, V>::val(const K &rkey, bool must)
130 {
131  EST_Litem *ptr = find_pair_key(rkey);
132 
133  if (ptr == 0)
134  {
135  if (must)
136  EST_error("No value set for '%s'", error_name(rkey));
137 
138  return *default_val;
139  }
140  else
141  return list.item(ptr).v;
142 }
143 
144 template<class K, class V>
145 const V &EST_TKVL<K, V>::val(const K &rkey, bool must) const
146 {
147  return ((EST_TKVL<K, V> *)this)->val(rkey, must);
148 }
149 
150 template<class K, class V>
151 const V &EST_TKVL<K, V>::val_def(const K &rkey, const V &def) const
152 {
153  EST_Litem *ptr = find_pair_key(rkey);
154  if (ptr == 0)
155  return def;
156  else
157  return list.item(ptr).v;
158 }
159 
160 // NOTE: This _MUST_NOT_ change the EST_TKVL, if it needs to, a separate
161 // const version will need to replace the dummy one below.
162 
163 template<class K, class V>
164 V &EST_TKVL<K, V>::val(EST_Litem *kptr, bool must)
165 {
166  if (must == 0)
167  return list.item(kptr).v;
168  /* check kptr is one of mine */
169  if (list.index(kptr) == -1)
170  {
171  if (must)
172  EST_error("No value set in EST_TKVL");
173  return *default_val;
174  }
175  else
176  return list.item(kptr).v;
177 }
178 
179 
180 template<class K, class V>
181 const V &EST_TKVL<K, V>::val(EST_Litem *kptr, bool must) const
182 {
183  return ((EST_TKVL<K, V> *)this)->val(kptr, must);
184 }
185 
186 // NOTE: This _MUST_NOT_ change the EST_TKVL, if it needs to, a separate
187 // const version will need to replace the dummy one below.
188 
189 template<class K, class V>
190 K &EST_TKVL<K, V>::key(EST_Litem *kptr, int must)
191 {
192  if (must == 0)
193  return list.item(kptr).k;
194  if (list.index(kptr) == -1)
195  EST_error("No value set in EST_TKVL");
196 
197  return list.item(kptr).k;
198 }
199 
200 template<class K, class V>
201 const K &EST_TKVL<K, V>::key(EST_Litem *kptr, int must) const
202 {
203  return ((EST_TKVL<K, V> *)this)->key(kptr, must);
204 }
205 
206 template<class K, class V>
207 const K &EST_TKVL<K, V>::key(const V &v, int must) const
208 {
209  EST_Litem *ptr = find_pair_val(v);
210  if (ptr == 0)
211  {
212  if (must)
213  EST_error("No value set for '%s'", error_name(v));
214 
215  return *default_key;
216  }
217 
218  return list.item(ptr).k;
219 }
220 
221 template<class K, class V>
222 const int EST_TKVL<K, V>::present(const K &rkey) const
223 {
224  if (find_pair_key(rkey) == 0)
225  return 0;
226  else
227  return 1;
228 }
229 
230 // map a function over the pairs
231 
232 template<class K, class V>
233 void EST_TKVL<K,V>::map(void (*func)(K&, V&))
234 {
235  EST_Litem *p;
236  for(p=list.head(); p; p=p->next())
237  {
238  EST_TKVI<K,V> item = list.item(p);
239  (*func)(item.k, item.v);
240  }
241 }
242 
243 // add item to list. By default, the list is searched to see if the
244 // item exists already. If so, its value is overwritten. This facility
245 // can be turned off by setting no_search = 1;
246 
247 template<class K, class V>
248 int EST_TKVL<K, V>::add_item(const K &rkey, const V &rval, int no_search)
249 {
250  if (!no_search)
251  if (change_val(rkey, rval)) // first see if key exists
252  return 1;
253 
254  EST_TKVI<K,V> item;
255  item.k = rkey;
256  item.v = rval;
257 
258  list.append(item);
259  return 1;
260 }
261 
262 template<class K, class V>
263 int EST_TKVL<K, V>::remove_item(const K &rkey, int quiet)
264 {
265  EST_Litem *ptr = find_pair_key(rkey);
266  const char *en;
267  if (ptr == 0)
268  {
269  if (!quiet)
270  {
271  en = error_name(rkey);
272  EST_warning("EST_TKVL: no item labelled '%s'", en);
273  }
274  return -1;
275  }
276  else
277  {
278  list.remove(ptr);
279  return 0;
280  }
281 }
282 
283 template<class K, class V> EST_TKVL<K, V> &EST_TKVL<K, V>::operator =
284 (const EST_TKVL<K, V> &kv)
285 {
286  list = kv.list;
287  return *this;
288 }
289 
290 template<class K, class V> EST_TKVL<K, V> &EST_TKVL<K, V>::operator +=
291 (const EST_TKVL<K, V> &kv)
292 {
293  list += kv.list;
294  return *this;
295 }
296 
297 template<class K, class V> EST_TKVL<K, V> EST_TKVL<K, V>::operator + (const EST_TKVL<K, V> &kv)
298 {
299  EST_TKVL<K, V> result;
300  result = *this;
301  result += kv;
302  return result;
303 }
304