Polymorph.hpp

Go to the documentation of this file.
00001 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00002 //
00003 //        This file is part of E-Cell Simulation Environment package
00004 //
00005 //                Copyright (C) 1996-2002 Keio University
00006 //
00007 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
00008 //
00009 //
00010 // E-Cell is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2 of the License, or (at your option) any later version.
00014 // 
00015 // E-Cell is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 // See the GNU General Public License for more details.
00019 // 
00020 // You should have received a copy of the GNU General Public
00021 // License along with E-Cell -- see the file COPYING.
00022 // If not, write to the Free Software Foundation, Inc.,
00023 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 // 
00025 //END_HEADER
00026 //
00027 // written by Koichi Takahashi <shafi@e-cell.org>,
00028 // E-Cell Project.
00029 //
00030 
00031 #ifndef __POLYMORPH_HPP
00032 #define __POLYMORPH_HPP
00033 
00034 #include <boost/static_assert.hpp>
00035 
00036 #include "libecs.hpp"
00037 #include "convertTo.hpp"
00038 #include "Util.hpp"
00039 
00040 namespace libecs
00041 {
00042 
00043   /** @addtogroup polymorph The Polymorph.
00044    The Polymorph
00045 
00046    @ingroup libecs
00047    @{ 
00048    */ 
00049 
00050   /** @file */
00051   
00052   DECLARE_CLASS( PolymorphValue );
00053 
00054   class PolymorphValue
00055   {
00056 
00057   public:
00058 
00059     ECELL_API virtual ~PolymorphValue();
00060 
00061     virtual const String  asString()        const = 0;
00062     virtual const Real    asReal()          const = 0;
00063     virtual const Integer asInteger()       const = 0;
00064     virtual const PolymorphVector asPolymorphVector() const = 0;
00065 
00066     template< typename T >
00067     const T as() const;
00068 
00069     virtual PolymorphValuePtr createClone() const = 0;
00070 
00071   protected:
00072   
00073     PolymorphValue( PolymorphValueCref ) {}
00074     PolymorphValue() {}
00075 
00076   private:
00077 
00078     PolymorphCref operator= ( PolymorphCref );
00079 
00080   };
00081 
00082 
00083   template <>
00084   inline const String PolymorphValue::as() const
00085   {
00086     return asString();
00087   }
00088 
00089   template <>
00090   inline const Real PolymorphValue::as() const
00091   {
00092     return asReal();
00093   }
00094 
00095   template <>
00096   inline const Integer PolymorphValue::as() const
00097   {
00098     return asInteger();
00099   }
00100 
00101   template <>
00102   inline const PolymorphVector PolymorphValue::as() const
00103   {
00104     return asPolymorphVector();
00105   }
00106 
00107 
00108 
00109   template< typename T >
00110   class ConcretePolymorphValue 
00111     : 
00112     public PolymorphValue
00113   {
00114 
00115     typedef typename libecs::Param<T>::type TParam;
00116 
00117   public:
00118 
00119     ConcretePolymorphValue( TParam aValue ) 
00120       :
00121       theValue( aValue )
00122     {
00123       ; // do nothing
00124     }
00125 
00126     ConcretePolymorphValue( PolymorphValueCref aValue )
00127       :
00128       theValue( aValue.as<T>() )
00129     {
00130       ; // do nothing
00131     }
00132 
00133     virtual ~ConcretePolymorphValue()
00134     {
00135       ; // do nothing
00136     }
00137   
00138     virtual const String asString() const 
00139     { 
00140       return convertTo<String>( theValue ); 
00141     }
00142 
00143     virtual const Real   asReal()  const 
00144     { 
00145       return convertTo<Real>( theValue );
00146     }
00147 
00148     virtual const Integer asInteger()   const 
00149     { 
00150       return convertTo<Integer>( theValue ); 
00151     }
00152 
00153     virtual const PolymorphVector asPolymorphVector() const
00154     { 
00155       return convertTo<PolymorphVector>( theValue ); 
00156     }
00157 
00158     virtual PolymorphValuePtr createClone() const
00159     {
00160       return new ConcretePolymorphValue<T>( *this );
00161     }
00162 
00163   private:
00164 
00165     T theValue;
00166 
00167   };
00168 
00169 
00170 
00171 
00172   class PolymorphNoneValue 
00173     : 
00174     public PolymorphValue
00175   {
00176 
00177   public: 
00178 
00179     PolymorphNoneValue() {}
00180 
00181     ECELL_API virtual ~PolymorphNoneValue();
00182 
00183     ECELL_API virtual const String  asString() const;
00184     virtual const Real    asReal() const       { return 0.0; }
00185     virtual const Integer asInteger() const    { return 0; }
00186     ECELL_API virtual const PolymorphVector asPolymorphVector() const;
00187   
00188     virtual PolymorphValuePtr createClone() const
00189     {
00190       return new PolymorphNoneValue;
00191     }
00192 
00193   };
00194 
00195 
00196 
00197   class Polymorph
00198   {
00199 
00200   public:
00201 
00202     enum Type
00203       {
00204         NONE,
00205         REAL, 
00206         INTEGER,  
00207         STRING,
00208         POLYMORPH_VECTOR
00209       };
00210 
00211   
00212     Polymorph()
00213       :
00214       theValue( new PolymorphNoneValue )
00215     {
00216       ; // do nothing
00217     }
00218 
00219     Polymorph( StringCref  aValue ) 
00220       :
00221       theValue( new ConcretePolymorphValue<String>( aValue ) )
00222     {
00223       ; // do nothing
00224     }
00225   
00226     Polymorph( RealParam aValue )      
00227       :
00228       theValue( new ConcretePolymorphValue<Real>( aValue ) )
00229     {
00230       ; // do nothing
00231     }
00232 
00233     Polymorph( IntegerParam aValue )      
00234       :
00235       theValue( new ConcretePolymorphValue<Integer>( aValue ) )
00236     {
00237       ; // do nothing
00238     }
00239 
00240     Polymorph( PolymorphVectorCref aValue )
00241       :
00242       theValue( new ConcretePolymorphValue<PolymorphVector>( aValue ) )
00243     {
00244       ; // do nothing
00245     }
00246 
00247     Polymorph( PolymorphCref aValue )
00248       :
00249       theValue( aValue.createValueClone() )
00250     {
00251       ; // do nothing
00252     }
00253 
00254     ~Polymorph()
00255     {
00256       delete theValue;
00257     }
00258 
00259     PolymorphCref operator=( PolymorphCref rhs )
00260     {
00261       if( this != &rhs )
00262         {
00263           delete theValue;
00264           theValue = rhs.createValueClone();
00265         }
00266     
00267       return *this;
00268     }
00269 
00270     const String asString() const
00271     { 
00272       return theValue->asString(); 
00273     }
00274 
00275     const Real   asReal() const
00276     { 
00277       return theValue->asReal(); 
00278     }
00279   
00280     const Integer asInteger() const
00281     { 
00282       return theValue->asInteger();
00283     }
00284 
00285     const PolymorphVector asPolymorphVector() const
00286     { 
00287       return theValue->asPolymorphVector();
00288     }
00289 
00290     template< typename T >
00291     const T as() const;
00292       //    {
00293       //      DefaultSpecializationInhibited();
00294       //    }
00295 
00296     ECELL_API const Type getType() const;
00297 
00298     void changeType( const Type aType );
00299 
00300 
00301     operator String() const
00302     {
00303       return asString();
00304     }
00305 
00306     operator Real() const
00307     {
00308       return asReal();
00309     }
00310 
00311     operator Integer() const
00312     {
00313       return asInteger();
00314     }
00315 
00316     operator PolymorphVector() const
00317     {
00318       return asPolymorphVector();
00319     }
00320 
00321   protected:
00322 
00323     PolymorphValuePtr createValueClone() const
00324     {
00325       return theValue->createClone();
00326     }
00327 
00328   protected:
00329 
00330     PolymorphValuePtr theValue;
00331 
00332   };
00333 
00334 
00335 
00336 
00337   template <>
00338   inline const String Polymorph::as() const
00339   {
00340     return asString();
00341   }
00342 
00343   template <>
00344   inline const Real   Polymorph::as() const
00345   {
00346     return asReal();
00347   }
00348 
00349   template <>
00350   inline const Integer Polymorph::as() const
00351   {
00352     return asInteger();
00353   }
00354 
00355   template <>
00356   inline const PolymorphVector Polymorph::as() const
00357   {
00358     return asPolymorphVector();
00359   }
00360 
00361 
00362 
00363   //
00364   // nullValue() specialization for Polymorph. See Util.hpp
00365   //
00366 
00367   template<>
00368   inline const Polymorph nullValue()
00369   {
00370     return Polymorph();
00371   }
00372 
00373 
00374 
00375 
00376   //
00377   // convertTo template specializations for PolymorphVector.
00378   //
00379 
00380   // identity
00381   template<>
00382   class ConvertTo< PolymorphVector, PolymorphVector >
00383   {
00384   public:
00385     const PolymorphVector operator()( const PolymorphVector& aValue )
00386     {
00387       return aValue;
00388     }
00389   };
00390 
00391   // to PolymorphVector
00392 
00393   template< typename FromType >
00394   class ConvertTo< PolymorphVector, FromType >
00395   {
00396   public:
00397     const PolymorphVector operator()( const FromType& aValue )
00398     {
00399       return PolymorphVector( 1, aValue );
00400     }
00401   };
00402 
00403   // Override the <T,String> case defined in convertTo.hpp.
00404   template<>
00405   class ConvertTo< PolymorphVector, String >
00406   {
00407   public:
00408     const PolymorphVector operator()( const String& aValue )
00409     {
00410       return PolymorphVector( 1, aValue );
00411     }
00412   };
00413 
00414 
00415   // from PolymorphVector 
00416   template< typename ToType >
00417   class ConvertTo< ToType, PolymorphVector >
00418   {
00419   public:
00420     const ToType operator()( PolymorphVectorCref aValue )
00421     {
00422       checkSequenceSize( aValue, 1 );
00423       return static_cast<Polymorph>(aValue[0]).as<ToType>();
00424     }
00425   };
00426 
00427   // Override the <String,T> case defined in convertTo.hpp.
00428   template<>
00429   class ConvertTo< String, PolymorphVector >
00430   {
00431   public:
00432     const String operator()( PolymorphVectorCref aValue )
00433     {
00434       checkSequenceSize( aValue, 1 );
00435       return static_cast<Polymorph>(aValue[0]).as<String>();
00436     }
00437   };
00438 
00439 
00440   // @} // polymorph
00441 
00442 } // namespace libecs
00443 
00444 
00445 #endif /* __POLYMORPH_HPP */

Generated on Mon Dec 18 07:29:46 2006 for E-CELL C++ libraries (libecs and libemc) 3.1.105 by  doxygen 1.5.1