CLAM-Development
1.1
|
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 _Flags_hxx_ 00023 #define _Flags_hxx_ 00024 00025 #include <bitset> 00026 #include <string> 00027 #include <iosfwd> 00028 #include "Component.hxx" 00029 // TODO: This is provisional to share the IllegalValue exception 00030 #include "Enum.hxx" 00031 00032 namespace CLAM { 00033 00034 00040 class FlagsBase : public Component { 00041 // Internal Types 00042 public: 00044 typedef unsigned int tValue; 00046 typedef struct {tValue value; const char*name;} tFlagValue; 00047 00048 // Attributes 00049 protected: 00054 const tFlagValue * mFlagValues; 00055 00056 // Operations 00057 public: 00061 virtual unsigned int GetNFlags() const=0; 00062 virtual void SetFlag(unsigned int whichOne, bool value)=0; 00063 virtual bool IsSetFlag(unsigned int whichOne) const =0; 00069 std::string GetFlagString(unsigned int whichOne) const throw (IllegalValue); 00070 00076 unsigned int GetFlagPosition(const std::string & whichOne) const throw (IllegalValue); 00077 00078 /* 00079 * Stores component's subitems on the given Storage 00080 * @param store The given storage where the subitem will be stored 00081 * @see Storage 00082 * @todo TODO: This method can throw and IllegalValue exception 00083 */ 00084 virtual void StoreOn (Storage & storage) const; 00085 00086 /* 00087 * Loads component's subitems from the given Storage 00088 * @param store The given storage where the subitem will be stored 00089 * @see Storage 00090 * @todo TODO: This method can throw and IllegalValue exception 00091 */ 00092 virtual void LoadFrom (Storage & storage); 00093 00094 // Debug 00095 public: 00106 inline bool CheckInvariant(); 00107 }; 00108 00109 std::istream & operator >> (std::istream & is, FlagsBase & f); 00110 std::ostream & operator << (std::ostream & os, const FlagsBase & f); 00111 00251 template <unsigned int N> class Flags : public FlagsBase, public std::bitset<N> 00252 { 00253 // Construction/Destruction 00254 protected: 00256 Flags(tFlagValue * names) : std::bitset<N>() { 00257 mFlagValues=names; 00258 }; 00262 Flags(tFlagValue * names, const Flags<N> &t) : std::bitset<N>() { 00263 mFlagValues=names; 00264 }; 00271 template <class T> Flags(tFlagValue * names,const T &t) : std::bitset<N>(t) { 00272 mFlagValues=names; 00273 }; 00282 template <class T1, class T2> Flags(tFlagValue * names,const T1 &t1,const T2 &t2) : 00283 std::bitset<N>(t1, t2) 00284 { 00285 mFlagValues=names; 00286 }; 00287 public: 00289 virtual ~Flags () {}; 00290 00292 const char * GetClassName() const {return NULL;} 00293 00294 // Operators 00295 public: 00296 virtual unsigned int GetNFlags () const { 00297 return N; 00298 } 00299 protected: 00300 virtual bool IsSetFlag(unsigned int whichOne) const { 00301 return std::bitset<N>::test(whichOne); 00302 } 00303 virtual void SetFlag(unsigned int whichOne, bool value=true) { 00304 this->set(whichOne, value); 00305 } 00306 00307 // Component Protocol 00308 public: 00315 virtual Component * Species () const = 0; 00316 00317 virtual Component * DeepCopy () const { 00318 Flags<N> * pe = (Flags<N>*)Species(); 00319 *pe=*this; 00320 return pe; 00321 } 00322 00323 virtual Component * ShallowCopy () const { 00324 Flags<N> * pe = (Flags<N>*)Species(); 00325 *pe=*this; 00326 return pe; 00327 } 00328 00329 }; 00330 00331 //MRJ: Why this? There exists a fairly well known issue about 00332 //VC6 support of template base classes, where polymorphism usual assumptions 00333 //don't hold. In this case we introduce two proxy methods that 00334 //just "inform" the compiler about what it has to do next... to promote 00335 //the references to the derived class object into references to the 00336 //base class. Sad but true. In discharge of MS guys this seems to be no 00337 //longer needed in VC++ 7.1. We could have implemented the body of the methods 00338 //inline on the header, but would have prevented us from using the compile-time 00339 //saving usage of the <iosfwd> header. 00340 00341 #ifdef _MSC_VER 00342 template <unsigned int N> 00343 std::istream & operator >> (std::istream & is, Flags<N> & f) { 00344 return (is >> static_cast<FlagsBase&>(f) ); 00345 } 00346 00347 template <unsigned int N> 00348 std::ostream & operator << (std::ostream & os, const Flags<N> & f){ 00349 return (os << static_cast<const FlagsBase&>(f)); 00350 } 00351 #endif //_MSC_VER 00352 00353 } 00354 00355 #endif//_Flags_hxx_ 00356