Flags.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 _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 
Generated by  doxygen 1.6.3