speech-tools/include/EST_TNamedEnum.h
2015-09-19 10:52:26 +02:00

170 lines
7.9 KiB
C++

/************************************************************************/
/* */
/* 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 <cstring>
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<class ENUM, class VAL, class INFO>
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 ENUM, class VAL, class INFO> class EST_TValuedEnumI {
protected:
int ndefinitions;
ENUM p_unknown_enum;
VAL p_unknown_value;
EST_TValuedEnumDefinition<ENUM,VAL,INFO> *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<ENUM,VAL,INFO> defs[])
{initialise((const void *)defs); };
EST_TValuedEnumI(EST_TValuedEnumDefinition<const char *,VAL,INFO> 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 ENUM, class INFO> class EST_TNamedEnumI : public EST_TValuedEnumI<ENUM, const char *, INFO> {
protected:
EST_TNamedEnumI(void) : EST_TValuedEnumI<ENUM, const char *, INFO>() {};
int eq_vals(const char *v1, const char *v2) const {return strcmp(v1,v2) ==0; };
public:
EST_TNamedEnumI(EST_TValuedEnumDefinition<ENUM,const char *,INFO> defs[])
{this->initialise((const void *)defs); };
EST_TNamedEnumI(EST_TValuedEnumDefinition<const char *,const char *,INFO> defs[], ENUM (*conv)(const char *))
{this->initialise((const void *)defs, conv); };
const char *name(ENUM tok, int n=0) const {return this->value(tok,n); };
};
// Now the simple cases with no extra information
template<class ENUM, class VAL> class EST_TValuedEnum : public EST_TValuedEnumI<ENUM,VAL,NO_INFO> {
public:
EST_TValuedEnum(EST_TValuedEnumDefinition<ENUM,VAL,NO_INFO> defs[])
{this->initialise((const void *)defs);};
EST_TValuedEnum(EST_TValuedEnumDefinition<const char *,VAL,NO_INFO> defs[], ENUM (*conv)(const char *))
{this->initialise((const void *)defs, conv);};
};
template<class ENUM> class EST_TNamedEnum : public EST_TNamedEnumI<ENUM,NO_INFO> {
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<ENUM,const char *,NO_INFO> defs[])
{this->initialise((const void *)defs);};
EST_TNamedEnum(EST_TValuedEnumDefinition<const char *,const char *,NO_INFO> 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