Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

polymorph.h

Go to the documentation of this file.
00001 
00007 #ifndef ___POLYMORPH_H___
00008 #define ___POLYMORPH_H___
00009 
00010 #include <cstring>
00011 #include <string>
00012 using std::string;
00013 #include <typeinfo>
00014 #include <cassert>
00015 
00016 #include "../src/stringutils.h"
00017 #include "../src/stringparser.h"
00018 #include "../src/allocatingpointer.h"
00019 #include "../src/tristate.h"
00020 #include "../src/typeless.h"
00021 
00022 
00023 #ifdef ANSI_COMPATIBLE
00024 /* Optional: defines LONG_DOUBLE_UNAVAILABLE where needed */
00025 #include "../src/ind_types.h"
00026 #endif
00027 
00028 
00029 
00030 /* Forward declaration */
00031 template <class T>  class Polymorph;
00032 
00033 
00039 template <class T>
00040 class PolymorphBase : public Typeless {
00041 public:
00042   typedef T value_type;
00043   typedef  PolymorphBase<value_type> self;
00044   virtual ~PolymorphBase() { }
00045 
00046   PolymorphBase(const value_type  val) : p(val) {  };
00047   PolymorphBase(      value_type* ptr) : p(ptr) {  };
00048 
00049   virtual bool operator<  (const Typeless&   o) const;
00050   virtual bool operator>  (const Typeless&   o) const;
00051 
00052   bool operator<  (const self&       o) const {  return (*p < *(o.p));  }
00053   bool operator>  (const self&       o) const {  return (*p > *(o.p));  }
00054 
00055   bool operator<  (const value_type& o) const {  return (*p <   o   );  }
00056   bool operator>  (const value_type& o) const {  return (*p >   o   );  }
00057 
00058   self&     operator= (const value_type& o) {  p=o;  return *this;  }
00059   Typeless& set(const Typeless&   o);
00060   
00061   const value_type& operator* () const {  return *p;  }
00062   
00065   value_type* valueptr() const {  return p.valueptr();  }
00066 
00067   virtual string stringrep(String::StreamFormat format=String::StreamFormat()) const
00068     {  return String::stringrep(*p,format);  }
00069   
00070   virtual string typestring() const
00071     {  return (name_str? string(name_str) : string(typeid(T).name()));  }
00072 
00079   static void set_typestring(const char* str) {  name_str=str;  }
00080 
00087   virtual Typeless* parse(const StringParser& parser, const string& s) const {
00088     value_type result;
00089     (void)parser; (void)s;
00090     parser.parse(s,result);
00091     return new Polymorph<value_type>(result); 
00092   }
00093 
00098   virtual Typeless* clone() const { return new self(*this); };
00099 
00100   virtual Typeless* duplicate() const { return new self(*p); };
00101 
00102 protected:
00103   AllocatingPointer<value_type> p;
00104   
00105   static const char* name_str;
00106 };
00107 
00108 
00109 
00110 /* Static variables */
00111 template <class T>
00112 const char* PolymorphBase<T>::name_str=0;
00113 
00114 
00115 
00117 template <class T>
00118 bool PolymorphBase<T>::operator<  (const Typeless&   o) const
00119 {
00120   /* First try to match exact type */
00121   const self* oself = dynamic_cast<const self*>(&o);
00122   if (oself) return (*this < **oself);
00123   
00124   /* Fall back to numeric comparison if both are numbers */
00125   if (isnumeric() && o.isnumeric())
00126     return (numericvalue() < o.numericvalue());
00127   
00128   assert(0); /* Unsupported comparison */
00129   exit(-1);
00130   return true;
00131 }
00132 
00133 
00134 
00136 template <class T>
00137 bool PolymorphBase<T>::operator>  (const Typeless&   o) const
00138 {
00139   /* First try to match exact type */
00140   const self* oself = dynamic_cast<const self*>(&o);
00141   if (oself) return (*this > **oself);
00142   
00143   /* Fall back to numeric comparison if both are numbers */
00144   if (isnumeric() && o.isnumeric())
00145     return (numericvalue() > o.numericvalue());
00146   
00147   assert(0); /* Unsupported comparison */
00148   exit(-1);
00149   return true;
00150 }
00151 
00152 
00153 
00161 template <class T>
00162 Typeless& PolymorphBase<T>::set(const Typeless&   o)
00163 {
00164   const self* oself = dynamic_cast<const self*>(&o);
00165   if (oself) p = *(oself->p);
00166   else { assert(0); } // Unsupported assignment; should be an exception instead
00167   
00168   return *this;
00169 }
00170 
00171 
00172 
00175 template <class T>
00176 class Polymorph : public PolymorphBase<T> {
00177 public:
00178   typedef T value_type;
00179   typedef  Polymorph<value_type> self;
00180   virtual ~Polymorph() { }
00181   Polymorph(const value_type  val) : PolymorphBase<value_type>(val) {  };
00182   Polymorph(      value_type* ptr) : PolymorphBase<value_type>(ptr) {  };
00183   virtual Typeless* clone()     const { return new self(*this); };
00184   virtual Typeless* duplicate() const { return new self(*p);    };  
00185 };
00186 
00187 
00192 template <class T>
00193 Polymorph<T> make_Polymorph(T* ptr)
00194 {  return Polymorph<T>(ptr);  }
00195 
00196 
00197 
00200 template <class T>
00201 Polymorph<T> allocating_Polymorph(const T& val)
00202 {  return Polymorph<T>(val);  }
00203 
00204 
00223 #define NumericPolymorph(type)\
00224 template <> class Polymorph<type> : public PolymorphBase<type> {\
00225 public:\
00226   typedef type value_type;\
00227   typedef  Polymorph<value_type> self;\
00228   virtual ~Polymorph() { }\
00229   Polymorph(value_type  val) : PolymorphBase<value_type>(val) {  };\
00230   Polymorph(value_type* ptr) : PolymorphBase<value_type>(ptr) {  };\
00231   virtual Typeless* clone()     const { return new self(*this); };\
00232   virtual Typeless* duplicate() const { return new self(*p);    };\
00233   virtual bool  isnumeric() const {  return true;  }\
00234   virtual Typeless::exprtype numericvalue() const\
00235     {  return Typeless::exprtype(*p);  }\
00236   virtual string prettyprint(String::StreamFormat format=String::StreamFormat()) const\
00237     {  return (*p==Uninitialized ? std::string("Uninitialized") : stringrep(format));  }\
00238 }
00239 
00240 NumericPolymorph(int);
00241 NumericPolymorph(double);
00242 NumericPolymorph(Tristate);
00243 
00244 
00245 
00247 template <> class Polymorph<string> : public PolymorphBase<string> {
00248 public:
00249   typedef string value_type;
00250   typedef  Polymorph<value_type> self;
00251   virtual ~Polymorph() { }
00252   Polymorph(value_type  val) : PolymorphBase<value_type>(val) {  };
00253   Polymorph(value_type* ptr) : PolymorphBase<value_type>(ptr) {  };
00254   virtual Typeless* clone()     const { return new self(*this); };
00255   virtual Typeless* duplicate() const { return new self(*p);    };
00256   virtual string prettyprint(String::StreamFormat format=String::StreamFormat()) const\
00257     {  return ("\"" + stringrep(format) + "\"");  }
00258 };
00259 
00260 
00261 #endif /* ___POLYMORPH_H___ */

Generated on Mon Jan 20 02:35:45 2003 for RF-LISSOM by doxygen1.3-rc2