Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

Object.h

Go to the documentation of this file.
00001 // -*- C++ -*-4 1999/10/29 20:41:34 dugas 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio and University of Montreal 00006 // Copyright (C) 2002 Frederic Morin 00007 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 00037 00038 /* ******************************************************* 00039 * $Id: Object.h,v 1.35 2004/07/07 15:09:38 chapados Exp $ 00040 * This file is part of the PLearn library. 00041 ******************************************************* */ 00042 00043 00046 #ifndef Object_INC 00047 #define Object_INC 00048 00049 #include <map> 00050 #include <string> 00051 //#include <set> 00052 //#include "general.h" 00053 #include "PP.h" 00054 #include "StaticInitializer.h" 00055 //#include "TypeTraits.h" 00056 #include "Array.h" 00057 //#include "stringutils.h" 00058 #include "TypeFactory.h" 00059 //#include "OptionBase.h" 00060 #include "Option.h" 00061 00062 namespace PLearn { 00063 using namespace std; 00064 00091 // --------------------------------------------------------- 00092 00093 #define PLEARN_DECLARE_OBJECT(CLASSTYPE) \ 00094 public: \ 00095 static string _classname_(); \ 00096 virtual string classname() const; \ 00097 static OptionList& _getOptionList_(); \ 00098 virtual OptionList& getOptionList() const; \ 00099 static Object* _new_instance_for_typemap_(); \ 00100 static bool _isa_(Object* o); \ 00101 virtual CLASSTYPE* deepCopy(CopiesMap &copies) const; \ 00102 static void _static_initialize_(); \ 00103 static StaticInitializer _static_initializer_ 00104 00105 #define PLEARN_IMPLEMENT_OBJECT(CLASSTYPE, ONELINEDESCR, MULTILINEHELP) \ 00106 string CLASSTYPE::_classname_() \ 00107 { return #CLASSTYPE; } \ 00108 string CLASSTYPE::classname() const \ 00109 { return _classname_(); } \ 00110 OptionList& CLASSTYPE::_getOptionList_() \ 00111 { static OptionList ol; \ 00112 if(ol.empty()) \ 00113 declareOptions(ol); \ 00114 return ol; } \ 00115 OptionList& CLASSTYPE::getOptionList() const \ 00116 { return _getOptionList_(); } \ 00117 Object* CLASSTYPE::_new_instance_for_typemap_() \ 00118 { return new CLASSTYPE(); } \ 00119 bool CLASSTYPE::_isa_(Object* o) \ 00120 { return dynamic_cast<CLASSTYPE*>(o) != 0; } \ 00121 CLASSTYPE* CLASSTYPE::deepCopy(CopiesMap& copies) const \ 00122 { CopiesMap::iterator it = copies.find(this); \ 00123 if (it != copies.end()) \ 00124 return static_cast<CLASSTYPE*>(it->second); \ 00125 CLASSTYPE* deep_copy = \ 00126 new CLASSTYPE(dynamic_cast<const CLASSTYPE&>(*this)); \ 00127 copies[this] = deep_copy; \ 00128 deep_copy->makeDeepCopyFromShallowCopy(copies); \ 00129 return deep_copy; } \ 00130 void CLASSTYPE::_static_initialize_() \ 00131 { TypeFactory::register_type( \ 00132 #CLASSTYPE, \ 00133 inherited::_classname_(), \ 00134 &CLASSTYPE::_new_instance_for_typemap_, \ 00135 &CLASSTYPE::_getOptionList_, \ 00136 &CLASSTYPE::_isa_, \ 00137 ONELINEDESCR, \ 00138 MULTILINEHELP ); } \ 00139 StaticInitializer CLASSTYPE::_static_initializer_(&CLASSTYPE::_static_initialize_) 00140 00141 00142 #define PLEARN_DECLARE_ABSTRACT_OBJECT(CLASSTYPE) \ 00143 public: \ 00144 static string _classname_(); \ 00145 static OptionList& _getOptionList_(); \ 00146 static bool _isa_(Object* o); \ 00147 virtual CLASSTYPE* deepCopy(CopiesMap &copies) const; \ 00148 static void _static_initialize_(); \ 00149 static StaticInitializer _static_initializer_ 00150 00151 #define PLEARN_IMPLEMENT_ABSTRACT_OBJECT(CLASSTYPE, ONELINEDESCR, MULTILINEHELP) \ 00152 string CLASSTYPE::_classname_() \ 00153 { return #CLASSTYPE; } \ 00154 OptionList& CLASSTYPE::_getOptionList_() \ 00155 { static OptionList ol; \ 00156 if(ol.empty()) \ 00157 declareOptions(ol); \ 00158 return ol; } \ 00159 bool CLASSTYPE::_isa_(Object* o) \ 00160 { return dynamic_cast<CLASSTYPE*>(o) != 0; } \ 00161 CLASSTYPE* CLASSTYPE::deepCopy(CopiesMap& copies) const \ 00162 { PLERROR("Called virtual method deepCopy of an abstract class. " \ 00163 "This should never happen!"); \ 00164 return 0; } \ 00165 void CLASSTYPE::_static_initialize_() \ 00166 { TypeFactory::register_type( \ 00167 #CLASSTYPE, \ 00168 inherited::_classname_(), \ 00169 0, \ 00170 &CLASSTYPE::_getOptionList_, \ 00171 &CLASSTYPE::_isa_, \ 00172 ONELINEDESCR, \ 00173 MULTILINEHELP ); } \ 00174 StaticInitializer CLASSTYPE::_static_initializer_(&CLASSTYPE::_static_initialize_) 00175 00176 00177 // Now for TEMPLATEs... 00178 00179 /* Ex: For a template class Toto 00180 00181 template<class T, int U> 00182 class Toto: public Titi<T> { 00183 public: 00184 00185 typedef Titi<T> inherited; 00186 #define TEMPLATE_DEF_Toto class T, int U 00187 #define TEMPLATE_ARGS_Toto T,U 00188 #define TEMPLATE_NAME_Toto string("Toto< ") + TypeTraits<T>::name() + ", " + tostring(U) + " >" 00189 PLEARN_DECLARE_TEMPLATE_OBJECT(Toto) 00190 00191 ... 00192 }; 00193 00194 PLEARN_IMPLEMENT_TEMPLATE_OBJECT(Toto) 00195 00196 // Puis au besoin, pour chaque version de template instanciée, il faudra 00197 // peut-être définir le _static_initializer_ (si le compilo n'est pas assez 00198 // smart pour le faire tout seul depuis la définition du template) 00199 template<> StaticInitializer Toto<int,3>::_static_initializer_(&Toto<int,3>::_static_initialize_); 00200 00201 */ 00202 00203 #define PLEARN_DECLARE_TEMPLATE_OBJECT(CLASSTYPE) \ 00204 public: \ 00205 static string _classname_(); \ 00206 virtual string classname() const; \ 00207 static OptionList& _getOptionList_(); \ 00208 virtual OptionList& getOptionList() const; \ 00209 static Object* _new_instance_for_typemap_(); \ 00210 static bool _isa_(Object* o); \ 00211 virtual CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >* deepCopy(CopiesMap &copies) const; \ 00212 static void _static_initialize_(); \ 00213 static StaticInitializer _static_initializer_; 00214 00215 #define PLEARN_IMPLEMENT_TEMPLATE_OBJECT(CLASSTYPE, ONELINEDESCR, MULTILINEHELP) \ 00216 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00217 string CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_classname_() \ 00218 { return TEMPLATE_NAME_ ## CLASSTYPE ; } \ 00219 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00220 string CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::classname() const \ 00221 { return _classname_(); } \ 00222 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00223 OptionList& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_getOptionList_() \ 00224 { static OptionList ol; \ 00225 if(ol.empty()) \ 00226 declareOptions(ol); \ 00227 return ol; } \ 00228 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00229 OptionList& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::getOptionList() const \ 00230 { return _getOptionList_(); } \ 00231 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00232 Object* CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_new_instance_for_typemap_() \ 00233 { return new CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >(); } \ 00234 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00235 bool CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_isa_(Object* o) \ 00236 { return dynamic_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >*>(o) != 0; } \ 00237 \ 00238 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00239 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >* \ 00240 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::deepCopy(CopiesMap& copies) const \ 00241 { \ 00242 CopiesMap::iterator it = copies.find(this); \ 00243 if (it != copies.end()) \ 00244 return static_cast<CLASSTYPE*>(it->second); \ 00245 CLASSTYPE* deep_copy = new CLASSTYPE(dynamic_cast<const CLASSTYPE&>(*this)); \ 00246 copies[this] = deep_copy; \ 00247 deep_copy->makeDeepCopyFromShallowCopy(copies); \ 00248 return deep_copy; \ 00249 } \ 00250 \ 00251 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00252 void CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_static_initialize_() \ 00253 { TypeFactory::register_type( \ 00254 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_classname_(), \ 00255 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::inherited::_classname_(), \ 00256 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_new_instance_for_typemap_, \ 00257 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_getOptionList_, \ 00258 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_isa_, \ 00259 ONELINEDESCR, \ 00260 MULTILINEHELP ); } \ 00261 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00262 StaticInitializer CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_static_initializer_(&CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_static_initialize_); 00263 00264 00265 00270 #define DECLARE_OBJECT_PTR(CLASSTYPE) \ 00271 inline Object *toObjectPtr(const CLASSTYPE &o) \ 00272 { return const_cast<CLASSTYPE *>(&o); } \ 00273 inline PStream &operator>>(PStream &in, CLASSTYPE &o) \ 00274 { o.newread(in); return in; } \ 00275 inline PStream &operator>>(PStream &in, CLASSTYPE * &o) \ 00276 { Object *ptr = o; \ 00277 in >> ptr; \ 00278 o = dynamic_cast<CLASSTYPE *>(ptr); \ 00279 if(ptr!=0 && o==0) \ 00280 PLERROR("Mismatched classes while reading a pointer: %s is not a %s", \ 00281 ptr->classname().c_str(),CLASSTYPE::_classname_().c_str()); \ 00282 return in; } \ 00283 inline PStream &operator<<(PStream &out, const CLASSTYPE &o) \ 00284 { o.newwrite(out); return out; } \ 00285 inline PStream &operator>>(PStream &in, PP<CLASSTYPE> &o) \ 00286 { Object *ptr = (CLASSTYPE *)o; \ 00287 in >> ptr; \ 00288 o = dynamic_cast<CLASSTYPE *>(ptr); \ 00289 if(ptr!=0 && o.isNull()) \ 00290 PLERROR("Mismatched classes while reading a PP: %s is not a %s", \ 00291 ptr->classname().c_str(),CLASSTYPE::_classname_().c_str()); \ 00292 return in; \ 00293 } \ 00294 DECLARE_TYPE_TRAITS(CLASSTYPE) 00295 00296 #define DECLARE_TEMPLATE_OBJECT_PTR(CLASSTYPE) \ 00297 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00298 inline Object *toObjectPtr(const CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > &o) \ 00299 { return const_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *>(&o); } \ 00300 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00301 inline PStream &operator>>(PStream &in, CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > &o) \ 00302 { o.newread(in); return in; } \ 00303 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00304 inline PStream &operator>>(PStream &in, CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > * &o) \ 00305 { if (o) o->newread(in); \ 00306 else o = static_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *>(readObject(in)); \ 00307 return in; } \ 00308 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00309 inline PStream &operator<<(PStream &out, const CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > &o) \ 00310 { o.newwrite(out); return out; } \ 00311 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00312 inline PStream &operator>>(PStream &in, PP<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > > &o) \ 00313 { Object *ptr = (CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *)o; \ 00314 in >> ptr; \ 00315 o = dynamic_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *>(ptr); \ 00316 return in; \ 00317 } \ 00318 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00319 class TypeTraits< CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > > \ 00320 { \ 00321 public: \ 00322 static inline string name() \ 00323 { return CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_classname_(); } \ 00324 static inline unsigned char little_endian_typecode() \ 00325 { return 0xFF; } \ 00326 static inline unsigned char big_endian_typecode() \ 00327 { return 0xFF; } \ 00328 } 00329 00330 00331 00336 #define DECLARE_OBJECT_PP(PPCLASSTYPE, CLASSTYPE) \ 00337 inline PStream &operator>>(PStream &in, PPCLASSTYPE &o) \ 00338 { Object *ptr = 0; \ 00339 in >> ptr; \ 00340 o = dynamic_cast<CLASSTYPE *>(ptr); \ 00341 return in; } \ 00342 inline PStream &operator<<(PStream &out, const PPCLASSTYPE &o) \ 00343 { out << static_cast<const PP<CLASSTYPE> &>(o); return out; } \ 00344 DECLARE_TYPE_TRAITS(PPCLASSTYPE) 00345 00346 00348 00349 class Object: public PPointable 00350 { 00351 protected: 00352 00356 00365 static void declareOptions(OptionList& ol) {} 00366 00367 // Must be called by the call method prior to dending results. 00368 inline void prepareToSendResults(PStream& out, int nres) 00369 { out << nres; } 00370 00371 public: 00372 00373 // hack: 00374 typedef Object inherited; 00375 PLEARN_DECLARE_OBJECT(Object); 00376 00381 Object(); 00382 00383 private: 00393 void build_(); 00394 00395 public: 00397 00400 virtual void build(); 00401 00402 00403 00404 00419 virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies); 00420 00423 virtual string info() const; 00424 00429 virtual void print(ostream& out) const; 00430 00432 void readOptionVal(PStream &in, const string &optionname); 00433 00435 void writeOptionVal(PStream &out, const string &optionname) const; 00436 00439 virtual string getOptionsToSave() const; 00440 00443 void newwrite(PStream& out) const; 00444 00445 00448 void newread(PStream& in); 00449 00457 // This calls readOptionVal on a stringstream built from value 00458 void setOption(const string& optionname, const string& value); 00459 00465 // This calls writeOptionVal into a string stream 00466 string getOption(const string &optionname) const; 00467 00474 virtual void changeOptions(const map<string,string>& name_value); 00475 00477 void changeOption(const string& optionname, const string& value); 00478 00489 virtual void write(ostream& out) const; 00490 00498 virtual void read(istream& in); 00499 00501 00521 virtual void call(const string& methodname, int nargs, PStream& in_parameters, PStream& out_results); 00522 00528 virtual void run(); 00529 00531 virtual void oldread(istream& in); 00532 00533 00535 00536 00537 00541 virtual void save(const string& filename) const; 00542 00546 virtual void load(const string& filename); 00547 00548 virtual ~Object(); 00549 }; 00550 00553 00554 template<class T> inline Object* toObjectPtr(const T* x) // Never to be called stub 00555 { PLERROR("toObjectPtr() - Unexpected error"); return 0; } 00556 00557 template<class T> inline Object* toObjectPtr(const T& x) // Never to be called stub 00558 { PLERROR("toObjectPtr() - Unexpected error"); return 0; } 00559 00560 00561 template<> inline Object* toObjectPtr(const Object &x) 00562 { return const_cast<Object *>(&x); } 00563 00564 template<> inline Object* toObjectPtr(const Object *x) 00565 { return const_cast<Object *>(x); } 00566 00567 00568 template<class T> inline Object* toObjectPtr(const PP<T>& x) 00569 { return toObjectPtr(*static_cast<T *>(x)); } 00570 00571 template<class T> Object* toIndexedObjectPtr(const Array<T> &x, int i) 00572 { return toObjectPtr(static_cast<T &>(x[i])); } 00573 00574 template<class T> Object* toIndexedObjectPtr(const TVec<T> &x, int i) 00575 { return toObjectPtr(static_cast<T &>(x[i])); } 00576 00577 template<class T> Object *toIndexedObjectPtr(const T&, int) // Never to be called stub 00578 { PLERROR("toIndexedObjectPtr() - Unexpected error"); return 0; } 00579 00580 00591 Object *readObject(PStream &in, unsigned int id = UINT_MAX); 00592 inline Object *readObject(istream &in_) 00593 { PStream in(&in_); return readObject(in); } 00594 00596 Object *loadObject(const string &filename); 00597 00601 Object* macroLoadObject(const string &filename, map<string,string>& vars); 00602 00604 Object* macroLoadObject(const string &filename); 00605 00609 inline Object* newObject(const string& representation) 00610 { istrstream in(representation.c_str()); return readObject(in); } 00611 00612 inline ostream& operator<<(ostream& out, const Object& obj) 00613 { obj.print(out); return out; } 00614 00615 inline PStream &operator>>(PStream &in, Object &o) 00616 { o.newread(in); return in; } 00617 inline PStream &operator<<(PStream &out, const Object &o) 00618 { o.newwrite(out); return out; } 00619 00620 00621 // This takes precedence over the template definitions for a template type T in PStream.h 00622 PStream &operator>>(PStream &in, Object * &o); 00623 00624 00625 } // end of namespace PLearn 00626 00628 extern "C" 00629 { 00630 void printobj(PLearn::Object* p); 00631 } 00632 00633 00634 00635 #endif

Generated on Tue Aug 17 16:00:01 2004 for PLearn by doxygen 1.3.7