Enum.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef _ENUM_H_
00023 #define _ENUM_H_
00024 #include <exception>
00025 #include <iosfwd>
00026 #include <string>
00027 #include "Assert.hxx"
00028 #include "Component.hxx"
00029 
00030 namespace CLAM {
00031 
00032 // TODO: Integrate this excepcion class with CLAM exception standards
00033 class IllegalValue : public std::exception {
00034         public:
00035                 IllegalValue(const IllegalValue & e): msg(e.msg) {};
00036                 IllegalValue(const std::string & s) : msg(s) {};
00037                 virtual ~IllegalValue() throw() {};
00038                 std::string msg;
00039 };
00040 
00041 
00093 class Enum : public Component {
00094 
00095 // Internal Types
00096 public:
00097         typedef int tValue;
00098         typedef struct {tValue value; const char*name;} tEnumValue;
00099 
00100 // Attributes
00101 private:
00102         const tEnumValue * mEnumValues;
00103         tValue mValue;
00104 
00107 
00108 protected:
00116         Enum (const tEnumValue * values, const tValue & value) /* throw IllegalValue */ {
00117                 mEnumValues = values;
00118                 SetValue(value);
00119         }
00127         Enum (const tEnumValue * values, const std::string & value) /* throw IllegalValue */ {
00128                 mEnumValues = values;
00129                 SetValue(value);
00130         };
00131 public:
00133         virtual ~Enum ();
00134         const char * GetClassName() const {return NULL;}
00136 
00137 // Operations
00138 public:
00142         const tEnumValue * GetSymbolMap() const {
00143                 return mEnumValues;
00144         }
00145 
00150         void SetValue(const tValue v) {
00151                 CLAM_BEGIN_DEBUG_CHECK
00152                         for (int i = 0; mEnumValues[i].name; i++) {
00153                                 if (v==mEnumValues[i].value) {
00154                                         mValue = v;
00155                                         return;
00156                                 }
00157                         }
00158                         CLAM_ASSERT(false, "Invalid value for an Enum");
00159                 CLAM_END_DEBUG_CHECK
00160                 mValue = v; 
00161         }
00171         void SetValueSafely(const tValue v) throw (IllegalValue) {
00172                 for (int i = 0; mEnumValues[i].name; i++) {
00173                         if (v==mEnumValues[i].value) {
00174                                 mValue = v;
00175                                 return;
00176                         }
00177                 }
00178                 throw IllegalValue("Invalid value for an Enum");
00179         }
00184         void SetValue(const std::string & s) 
00185         {
00186                 for (int i = 0; mEnumValues[i].name; i++) {
00187                         if (s.compare(mEnumValues[i].name)==0) {
00188                                 mValue = mEnumValues[i].value;
00189                                 return;
00190                         }
00191                 }
00192                 CLAM_ASSERT(false, "Illegal literal for an Enum");
00193         }
00194         /*
00195          * Changes the value safely. 
00196          * That is it checks the value is ok for the enum and throws a
00197          * catchable exception if not.
00198          * @param s The new symbolic value
00199          * @throw IllegalValue when the value is not valid for the enum
00200          * @todo Fill IllegalValue with useful information to recover 
00201          * instead a insightfull string.
00202          */
00203         void SetValueSafely(const std::string & s) throw (IllegalValue) 
00204         {
00205                 for (int i = 0; mEnumValues[i].name; i++) {
00206                         if (s.compare(mEnumValues[i].name)==0) {
00207                                 mValue = mEnumValues[i].value;
00208                                 return;
00209                         }
00210                 }
00211                 throw IllegalValue("Illegal literal for an Enum.");
00212         }
00213 
00218         tValue GetValue() const {
00219                 return mValue;
00220         }
00221 
00226         std::string GetString() const throw (IllegalValue)
00227         {
00228                 for (int i = 0; mEnumValues[i].name; i++) {
00229                         if (mValue==mEnumValues[i].value) 
00230                                 return mEnumValues[i].name;
00231                 }
00232                 CLAM_ASSERT(false, "Illegal numeric value for an Enum");
00233                 return "IllegalValue";
00234         }
00235 
00236         Enum & operator = (const tValue & v) throw (IllegalValue) {
00237                 SetValue(v);
00238                 return *this;
00239         }
00240 
00241         Enum & operator = (const std::string & v) throw (IllegalValue) {
00242                 SetValue(v);
00243                 return *this;
00244         }
00245 
00246         Enum & operator = (const Enum & v) throw (IllegalValue) {
00247                 SetValue(tValue(v));
00248                 return *this;
00249         }
00250 
00255         operator tValue() const {
00256                 return mValue;
00257         }
00258 
00259 // Component Protocol
00260 public:
00267         virtual Component * Species () const = 0;
00268 
00272         virtual Component * DeepCopy () const {
00273                 Enum * pe = (Enum*)Species();
00274                 pe->SetValue(mValue);
00275                 return pe;
00276         }
00277 
00281         virtual Component * ShallowCopy () const {
00282                 Enum * pe = (Enum*)Species();
00283                 pe->SetValue(mValue);
00284                 return pe;
00285         }
00286 
00294         virtual void StoreOn (Storage & storage) const;
00295 
00303         virtual void LoadFrom (Storage & storage);
00304 
00305 
00306 };
00307 
00314 std::ostream & operator << (std::ostream & os, const Enum & e) throw (IllegalValue);
00315 
00322 std::istream & operator >> (std::istream & os, Enum & e) throw (IllegalValue);
00323 
00324 }
00325 #endif // _ENUM_H_
00326 
Generated by  doxygen 1.6.3