/************************************************************************/ /* */ /* Centre for Speech Technology Research */ /* University of Edinburgh, UK */ /* Copyright (c) 1996,1997 */ /* All Rights Reserved. */ /* */ /* Permission is hereby granted, free of charge, to use and distribute */ /* this software and its documentation without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of this work, and to */ /* permit persons to whom this work is furnished to do so, subject to */ /* the following conditions: */ /* 1. The code must retain the above copyright notice, this list of */ /* conditions and the following disclaimer. */ /* 2. Any modifications must be clearly marked as such. */ /* 3. Original authors' names are not deleted. */ /* 4. The authors' names are not used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */ /* THIS SOFTWARE. */ /* */ /************************************************************************/ /* Author: Richard Caley (rjc@cstr.ed.ac.uk) */ /* Date: Fri Feb 28 1997 */ /************************************************************************/ /* */ /* A template class which allows names (const char *s) to be */ /* associated with enums, providing conversion. */ /* */ /* EST_TValuesEnum is the obvious generalisation to associating */ /* things other than const char * with each value. */ /* */ /* EST_T{Named/Valued}EnumI can include extra information for each */ /* enum element. */ /* */ /* This should be rewritten as something other than linear search. At */ /* least sort them. */ /* */ /************************************************************************/ #ifndef __EST_TNAMEDENUM_H__ #define __EST_TNAMEDENUM_H__ #include using namespace std; #include "EST_String.h" #include "EST_rw_status.h" #define NAMED_ENUM_MAX_SYNONYMS (10) // Used in the type of tables with no info field. typedef char NO_INFO; // struct used to define the mapping. template struct EST_TValuedEnumDefinition { public: ENUM token; VAL values[NAMED_ENUM_MAX_SYNONYMS]; INFO info; } ; // This is the most general case, a mapping from enum to some other type // with extra info. template class EST_TValuedEnumI { protected: int ndefinitions; ENUM p_unknown_enum; VAL p_unknown_value; EST_TValuedEnumDefinition *definitions; virtual int eq_vals(VAL v1, VAL v2) const {return v1 == v2; }; // This is only a void * because INFO can`t manage to get the // parameter declaration in the definition past gcc with the actual type. void initialise(const void *defs); void initialise(const void *defs, ENUM (*conv)(const char *)); void initialise(void) {ndefinitions=0; definitions=NULL;}; void initialise(ENUM unknown_e, VAL unknown_v) {initialise(); p_unknown_enum=unknown_e; p_unknown_value = unknown_v;}; protected: EST_TValuedEnumI(void) {initialise();}; public: EST_TValuedEnumI(EST_TValuedEnumDefinition defs[]) {initialise((const void *)defs); }; EST_TValuedEnumI(EST_TValuedEnumDefinition defs[], ENUM (*conv)(const char *)) {initialise((const void *)defs, conv); }; virtual ~EST_TValuedEnumI(void); int n(void) const; ENUM token(VAL value) const; ENUM token(int n) const { return nth_token(n); } ENUM nth_token(int n) const; VAL value(ENUM token, int n=0) const; INFO &info(ENUM token) const; ENUM unknown_enum(void) const {return p_unknown_enum;}; VAL unknown_value(void) const {return p_unknown_value;}; int valid(ENUM token) const { return !eq_vals(value(token),p_unknown_value); }; }; // This is a special case for names. This saves typing and also // takes care of the fact that strings need their own compare function. template class EST_TNamedEnumI : public EST_TValuedEnumI { protected: EST_TNamedEnumI(void) : EST_TValuedEnumI() {}; int eq_vals(const char *v1, const char *v2) const {return strcmp(v1,v2) ==0; }; public: EST_TNamedEnumI(EST_TValuedEnumDefinition defs[]) {this->initialise((const void *)defs); }; EST_TNamedEnumI(EST_TValuedEnumDefinition defs[], ENUM (*conv)(const char *)) {this->initialise((const void *)defs, conv); }; const char *name(ENUM tok, int n=0) const {return value(tok,n); }; }; // Now the simple cases with no extra information template class EST_TValuedEnum : public EST_TValuedEnumI { public: EST_TValuedEnum(EST_TValuedEnumDefinition defs[]) {this->initialise((const void *)defs);}; EST_TValuedEnum(EST_TValuedEnumDefinition defs[], ENUM (*conv)(const char *)) {this->initialise((const void *)defs, conv);}; }; template class EST_TNamedEnum : public EST_TNamedEnumI { private: EST_read_status priv_load(EST_String name, EST_TNamedEnum *definitive); EST_write_status priv_save(EST_String name, EST_TNamedEnum *definitive, char quote) const; public: EST_TNamedEnum(ENUM undef_e, const char *undef_n = NULL) {this->initialise(undef_e, undef_n);}; EST_TNamedEnum(EST_TValuedEnumDefinition defs[]) {this->initialise((const void *)defs);}; EST_TNamedEnum(EST_TValuedEnumDefinition defs[], ENUM (*conv)(const char *)) {this->initialise((const void *)defs, conv);}; EST_read_status load(EST_String name) { return priv_load(name, NULL); }; EST_read_status load(EST_String name, EST_TNamedEnum &definitive) { return priv_load(name, &definitive); }; EST_write_status save(EST_String name, char quote='"') const { return priv_save(name, NULL, quote); }; EST_write_status save(EST_String name, EST_TNamedEnum &definitive, char quote='"') const { return priv_save(name, &definitive, quote); }; }; #include "instantiate/EST_TNamedEnumI.h" #endif