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 :  Alan W Black                             */
34 /*                    Date   :  May 1996                                 */
35 /*-----------------------------------------------------------------------*/
36 /*                                                                       */
37 /* A generic container class, originally for ints floats and string now  */
38 /* extended for some others, eventually allow run addition of new types  */
39 /* "built-in" types (i.e. ones explicitly mentioned in this file) may    */
40 /* be accessed by member functions, objects added at run time may only   */
41 /* be accessed by functions                                              */
42 /*                                                                       */
43 /* This is so similar to the LISP class in SIOD it could be viewed as a  */
44 /* little embarrassing, but this is done without a cons cell heap or gc  */
45 /* which may or may not be a good thing.                                 */
46 /*                                                                       */
47 /*=======================================================================*/
48 #ifndef __EST_VAL_H__
49 #define __EST_VAL_H__
50 
51 #include "EST_String.h"
52 #include "EST_error.h"
53 #include "EST_Contents.h"
54 #include "EST_Val_defs.h"
55 
56 typedef const char *val_type;
57 
58 extern val_type val_unset;
59 extern val_type val_int;
60 extern val_type val_float;
61 extern val_type val_string;
62 
63 /** The EST_Val class is a container class, used to store a single
64     item which can be an int, float, string or other user-defined
65     class. It is often used as the base item in the <link
66     linkend="est-features">EST_Features</link> class, to enable features
67     to take on values of different types.
68 */
69 
70 class EST_Val {
71   private:
72     val_type t;
73     union
74     { int ival;
75       float fval;
76       EST_Contents *pval;} v;
77     // * may have a string name as well as a value
78     EST_String sval;
79     const int to_int() const;
80     const float to_flt() const;
81     const EST_String &to_str() const;
82   public:
83     /**@name Constructor and Destructor functions
84      */
85 
86     //@{
87     /** Default constructor */
EST_Val()88     EST_Val()
89 	{t=val_unset;}
90 
91     /** Copy constructor for another EST_Val*/
92     EST_Val(const EST_Val &val);
93 
94     /** Copy constructor for an int*/
EST_Val(const int i)95     EST_Val(const int i)
96 	{t=val_int; v.ival=i;}
97 
98     /** Copy constructor for a float*/
EST_Val(const float f)99     EST_Val(const float f)
100 	{t=val_float; v.fval=f;}
101 
102     /** Copy constructor for a double*/
EST_Val(const double d)103     EST_Val(const double d) {t=val_float; v.fval=d;}
104 
105     /** Copy constructor for a string*/
106     //    EST_Val(const EST_String &s) {t=val_string; sval = s;}
EST_Val(const EST_String & s)107     EST_Val(const EST_String &s) : t(val_string), sval(s) {};
108 
109     /** Copy constructor for a string literal*/
110     //    EST_Val(const char *s) {t=val_string; sval = s;}
EST_Val(const char * s)111     EST_Val(const char *s) : t(val_string), sval(s) {};
112 
113     EST_Val(val_type type,void *p, void (*f)(void *));
114 
115     /** Destructor */
116     ~EST_Val(void);
117 
118     //@}
119 
120     /**@name Getting cast values
121      */
122 
123     //@{
124 
125     /** returns the type that the val is currently holding */
type(void)126     const val_type type(void) const
127 	{return t;}
128 
129     /** returns the value, cast as an int */
Int(void)130     const int Int(void) const
131 	{if (t==val_int) return v.ival; return to_int();}
132 
133     /** returns the value, cast as an int */
I(void)134     const int I(void) const
135 	{ return Int(); }
136 
137     /** returns the value, cast as a float */
Float(void)138     const float Float(void) const
139 	{if (t==val_float) return v.fval; return to_flt();}
140 
141     /** returns the value, cast as a float */
F(void)142     const float F(void) const
143 	{ return Float(); }
144 
145     /** returns the value, cast as a string */
String(void)146     const EST_String &String(void) const
147        {if (t!=val_string) to_str(); return sval;}
148 
149     /** returns the value, cast as a string */
string(void)150     const EST_String &string(void) const
151        {return String();}
152 
153     /** returns the value, cast as a string */
S(void)154     const EST_String &S(void) const
155        {return String();}
156 
157     /** returns the value, cast as a string */
string_only(void)158     const EST_String &string_only(void) const {return sval;}
159 
160     //@}
161 
162     // Humans should never call this only automatic functions
internal_ptr(void)163     const void *internal_ptr(void) const
164 	{ return v.pval->get_contents(); }
165 
166     /**@name Setting values
167      */
168 
169     //@{
170 
171     /** Assignment of val to an int */
172     EST_Val &operator=(const int i) { t=val_int; v.ival=i; return *this;}
173 
174     /** Assignment of val to a float */
175     EST_Val &operator=(const float f) { t=val_float; v.fval=f; return *this;}
176 
177     /** Assignment of val to a double */
178     EST_Val &operator=(const double d) { t=val_float; v.fval=d; return *this;}
179 
180     /** Assignment of val to a string */
181     EST_Val &operator=(const EST_String &s) { t=val_string; sval = s; return *this;}
182 
183     /** Assignment of val to a string literal*/
184     EST_Val &operator=(const char *s) { t=val_string; sval = s; return *this;}
185 
186     /** Assignment of val to another val*/
187     EST_Val &operator=(const EST_Val &c);
188 
189     //@}
190 
191     /**@name Equivalence test
192      */
193 
194     //@{
195 
196 
197     /** Test whether val is equal to a*/
198     int operator ==(const EST_Val &a) const
199     { if (t != a.t) return (1==0);
200       else if (t == val_string) return (sval == a.sval);
201       else if (t == val_int) return (v.ival == a.v.ival);
202       else if (t == val_float) return (v.fval == a.v.fval);
203       else return (internal_ptr() == a.internal_ptr()); }
204 
205     /** Test whether val is equal to the string a*/
206     int operator ==(const EST_String &a) const { return (string() == a); }
207     /** Test whether val is equal to the char * a*/
208     int operator ==(const char *a) const { return (string() == a); }
209     /** Test whether val is equal to the int a*/
210     int operator ==(const int &i) const { return (Int() == i); }
211     /** Test whether val is equal to the float a*/
212     int operator ==(const float &f) const { return (Float() == f); }
213     /** Test whether val is equal to the double a*/
214     int operator ==(const double &d) const { return (Float() == d); }
215 
216 
217     /** Test whether val is not equal to the val a*/
218     int operator !=(const EST_Val &a) const { return (!(*this == a)); }
219     /** Test whether val is not equal to the string a*/
220     int operator !=(const EST_String &a) const { return (string() != a); }
221     /** Test whether val is not equal to the char * a*/
222     int operator !=(const char *a) const { return (string() != a); }
223     /** Test whether val is not equal to the int a*/
224     int operator !=(const int &i) const { return (Int() != i);}
225     /** Test whether val is not equal to the float a*/
226     int operator !=(const float &f) const { return (Float() != f); }
227     /** Test whether val is not equal to the double float a*/
228     int operator !=(const double &d) const { return (Float() != d); }
229 
230     //@{
231 
232     /**@name Automatic casting
233      */
234     //@{
235 
236     /** Automatically cast val as an int*/
237     operator int() const { return Int(); }
238     /** Automatically cast val as an float*/
239     operator float() const { return Float(); }
240     /** Automatically cast val as an string*/
EST_String()241     operator EST_String() const { return string(); }
242     //@}
243     /** print val*/
244     friend ostream& operator << (ostream &s, const EST_Val &a)
245     { if (a.type() == val_unset) s << "[VAL unset]" ;
246       else if (a.type() == val_int)	  s << a.v.ival;
247       else if (a.type() == val_float)  s << a.v.fval;
248       else if (a.type() == val_string) s << a.sval;
249       else  s << "[PVAL " << a.type() << "]";
250       return s;
251     }
252 };
253 
error_name(const EST_Val val)254 inline const char *error_name(const EST_Val val) { return (EST_String)val;}
255 
256 // For consistency with other (user-defined) types in val
est_val(const EST_String s)257 inline EST_Val est_val(const EST_String s) { return EST_Val(s); }
est_val(const char * s)258 inline EST_Val est_val(const char *s) { return EST_Val(s); }
Int(const EST_Val & v)259 inline int Int(const EST_Val &v) { return v.Int(); }
est_val(const int i)260 inline EST_Val est_val(const int i) { return EST_Val(i); }
Float(const EST_Val & v)261 inline float Float(const EST_Val &v) { return v.Float(); }
est_val(const float f)262 inline EST_Val est_val(const float f) { return EST_Val(f); }
263 
264 #endif
265