PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2005 Pascal Vincent and Yoshua Bengio 00006 // Copyright (C) 2002 Frederic Morin 00007 // Copyright (C) 1999-2005 University of Montreal 00008 // Copyright (C) 2007 Xavier Saint-Mleux, ApSTAT Technologies inc. 00009 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are met: 00012 // 00013 // 1. Redistributions of source code must retain the above copyright 00014 // notice, this list of conditions and the following disclaimer. 00015 // 00016 // 2. Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // 00020 // 3. The name of the authors may not be used to endorse or promote 00021 // products derived from this software without specific prior written 00022 // permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00025 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00026 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00027 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00029 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00030 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00031 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00032 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00033 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 // 00035 // This file is part of the PLearn library. For more information on the PLearn 00036 // library, go to the PLearn Web site at www.plearn.org 00037 00038 00039 /* ******************************************************* 00040 * $Id: Object.h 9436 2008-09-04 18:48:55Z nouiz $ 00041 * This file is part of the PLearn library. 00042 ******************************************************* */ 00043 00044 00047 #ifndef Object_INC 00048 #define Object_INC 00049 00050 // Python stuff must be included first 00051 #ifdef PL_PYTHON_VERSION 00052 # include <plearn/python/PythonIncludes.h> 00053 # include <plearn/python/PythonObjectWrapper.h> 00054 #endif //ifdef PL_PYTHON_VERSION 00055 00056 #include <map> 00057 #include <string> 00058 #include "PP.h" 00059 #include "StaticInitializer.h" 00060 #include "TypeFactory.h" 00061 #include "Option.h" 00062 #include "RemoteDeclareMethod.h" 00063 #include <plearn/io/PPath.h> 00064 #include <plearn/io/openString.h> 00065 00066 namespace PLearn { 00067 using namespace std; 00068 00085 #define PLEARN_DECLARE_OBJECT(CLASSTYPE) \ 00086 public: \ 00087 static string _classname_(); \ 00088 virtual string classname() const; \ 00089 static OptionList& _getOptionList_(); \ 00090 virtual OptionList& getOptionList() const; \ 00091 virtual OptionMap& getOptionMap() const; \ 00092 static RemoteMethodMap& _getRemoteMethodMap_(); \ 00093 virtual RemoteMethodMap& getRemoteMethodMap() const; \ 00094 static Object* _new_instance_for_typemap_(); \ 00095 static bool _isa_(const Object* o); \ 00096 virtual CLASSTYPE* deepCopy(CopiesMap &copies) const; \ 00097 static void _static_initialize_(); \ 00098 static StaticInitializer _static_initializer_; \ 00099 static const PPath& declaringFile() \ 00100 { static PPath df= __FILE__; return df;} 00101 00102 #define PLEARN_IMPLEMENT_OBJECT(CLASSTYPE, ONELINEDESCR, MULTILINEHELP) \ 00103 string CLASSTYPE::_classname_() \ 00104 { \ 00105 return #CLASSTYPE; \ 00106 } \ 00107 \ 00108 string CLASSTYPE::classname() const \ 00109 { \ 00110 return _classname_(); \ 00111 } \ 00112 \ 00113 OptionList& CLASSTYPE::_getOptionList_() \ 00114 { \ 00115 static OptionList ol; \ 00116 if(ol.empty()) \ 00117 declareOptions(ol); \ 00118 return ol; \ 00119 } \ 00120 \ 00121 OptionList& CLASSTYPE::getOptionList() const \ 00122 { \ 00123 return _getOptionList_(); \ 00124 } \ 00125 \ 00126 OptionMap& CLASSTYPE::getOptionMap() const \ 00127 { \ 00128 static OptionMap om; \ 00129 if(om.empty()) \ 00130 { \ 00131 OptionList& ol= getOptionList(); \ 00132 for(OptionList::iterator it= ol.begin(); it != ol.end(); ++it) \ 00133 /*N.B. option map will contain derived class's option*/ \ 00134 /* when it also exists in a base class. */ \ 00135 om.insert(make_pair((*it)->optionname(), *it)); \ 00136 } \ 00137 return om; \ 00138 } \ 00139 \ 00140 RemoteMethodMap& CLASSTYPE::_getRemoteMethodMap_() \ 00141 { \ 00142 static bool initialized = false; \ 00143 static RemoteMethodMap rmm; \ 00144 if (! initialized) { \ 00145 declareMethods(rmm); \ 00146 initialized = true; \ 00147 } \ 00148 return rmm; \ 00149 } \ 00150 \ 00151 RemoteMethodMap& CLASSTYPE::getRemoteMethodMap() const \ 00152 { \ 00153 return _getRemoteMethodMap_(); \ 00154 } \ 00155 \ 00156 Object* CLASSTYPE::_new_instance_for_typemap_() \ 00157 { \ 00158 return new CLASSTYPE(); \ 00159 } \ 00160 \ 00161 bool CLASSTYPE::_isa_(const Object* o) \ 00162 { \ 00163 return dynamic_cast<const CLASSTYPE*>(o) != 0; \ 00164 } \ 00165 \ 00166 CLASSTYPE* CLASSTYPE::deepCopy(CopiesMap& copies) const \ 00167 { \ 00168 CopiesMap::iterator it = copies.find(this); \ 00169 if (it != copies.end()) \ 00170 return static_cast<CLASSTYPE*>(it->second); \ 00171 CLASSTYPE* deep_copy = \ 00172 new CLASSTYPE(dynamic_cast<const CLASSTYPE&>(*this)); \ 00173 copies[this] = deep_copy; \ 00174 deep_copy->makeDeepCopyFromShallowCopy(copies); \ 00175 return deep_copy; \ 00176 } \ 00177 \ 00178 void CLASSTYPE::_static_initialize_() \ 00179 { \ 00180 TypeFactory::register_type(#CLASSTYPE, \ 00181 inherited::_classname_(), \ 00182 &CLASSTYPE::_new_instance_for_typemap_, \ 00183 &CLASSTYPE::_getOptionList_, \ 00184 &CLASSTYPE::_getRemoteMethodMap_, \ 00185 &CLASSTYPE::_isa_, \ 00186 ONELINEDESCR, \ 00187 MULTILINEHELP, \ 00188 CLASSTYPE::declaringFile()); \ 00189 } \ 00190 StaticInitializer CLASSTYPE::_static_initializer_(&CLASSTYPE::_static_initialize_) 00191 00192 00193 #define PLEARN_DECLARE_ABSTRACT_OBJECT(CLASSTYPE) \ 00194 public: \ 00195 static string _classname_(); \ 00196 static OptionList& _getOptionList_(); \ 00197 static RemoteMethodMap& _getRemoteMethodMap_(); \ 00198 static bool _isa_(const Object* o); \ 00199 virtual CLASSTYPE* deepCopy(CopiesMap &copies) const; \ 00200 static void _static_initialize_(); \ 00201 static StaticInitializer _static_initializer_; \ 00202 static const PPath& declaringFile() \ 00203 { static PPath df= __FILE__; return df;} 00204 00205 #define PLEARN_IMPLEMENT_ABSTRACT_OBJECT(CLASSTYPE, ONELINEDESCR, MULTILINEHELP) \ 00206 string CLASSTYPE::_classname_() \ 00207 { \ 00208 return #CLASSTYPE; \ 00209 } \ 00210 \ 00211 OptionList& CLASSTYPE::_getOptionList_() \ 00212 { \ 00213 static OptionList ol; \ 00214 if(ol.empty()) \ 00215 declareOptions(ol); \ 00216 return ol; \ 00217 } \ 00218 \ 00219 RemoteMethodMap& CLASSTYPE::_getRemoteMethodMap_() \ 00220 { \ 00221 static bool initialized = false; \ 00222 static RemoteMethodMap rmm; \ 00223 if (! initialized) { \ 00224 declareMethods(rmm); \ 00225 initialized = true; \ 00226 } \ 00227 return rmm; \ 00228 } \ 00229 \ 00230 bool CLASSTYPE::_isa_(const Object* o) \ 00231 { \ 00232 return dynamic_cast<const CLASSTYPE*>(o) != 0; \ 00233 } \ 00234 \ 00235 CLASSTYPE* CLASSTYPE::deepCopy(CopiesMap& copies) const \ 00236 { \ 00237 PLERROR("Called virtual method deepCopy of an abstract class. " \ 00238 "This should never happen!"); \ 00239 return 0; \ 00240 } \ 00241 \ 00242 void CLASSTYPE::_static_initialize_() \ 00243 { \ 00244 TypeFactory::register_type(#CLASSTYPE, \ 00245 inherited::_classname_(), \ 00246 0, \ 00247 &CLASSTYPE::_getOptionList_, \ 00248 &CLASSTYPE::_getRemoteMethodMap_, \ 00249 &CLASSTYPE::_isa_, \ 00250 ONELINEDESCR, \ 00251 MULTILINEHELP, \ 00252 CLASSTYPE::declaringFile()); \ 00253 } \ 00254 StaticInitializer CLASSTYPE::_static_initializer_(&CLASSTYPE::_static_initialize_) 00255 00256 00257 // Now for TEMPLATEs... 00258 00259 /* Ex: For a template class Toto 00260 00261 template<class T, int U> 00262 class Toto: public Titi<T> { 00263 public: 00264 00265 typedef Titi<T> inherited; 00266 #define TEMPLATE_DEF_Toto class T, int U 00267 #define TEMPLATE_ARGS_Toto T,U 00268 #define TEMPLATE_NAME_Toto string("Toto< ") + TypeTraits<T>::name() + ", " + tostring(U) + " >" 00269 PLEARN_DECLARE_TEMPLATE_OBJECT(Toto) 00270 00271 ... 00272 }; 00273 00274 PLEARN_IMPLEMENT_TEMPLATE_OBJECT(Toto,"One line description","Multi line help") 00275 00276 // Puis au besoin, pour chaque version de template instanciée, il faudra 00277 // peut-être définir le _static_initializer_ (si le compilo n'est pas assez 00278 // smart pour le faire tout seul depuis la définition du template) 00279 template<> StaticInitializer Toto<int,3>::_static_initializer_(&Toto<int,3>::_static_initialize_); 00280 00281 */ 00282 00283 #define PLEARN_DECLARE_TEMPLATE_OBJECT(CLASSTYPE) \ 00284 public: \ 00285 static string _classname_(); \ 00286 virtual string classname() const; \ 00287 static OptionList& _getOptionList_(); \ 00288 virtual OptionList& getOptionList() const; \ 00289 virtual OptionMap& getOptionMap() const; \ 00290 static RemoteMethodMap& _getRemoteMethodMap_(); \ 00291 virtual RemoteMethodMap& getRemoteMethodMap() const; \ 00292 static Object* _new_instance_for_typemap_(); \ 00293 static bool _isa_(const Object* o); \ 00294 virtual CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >* deepCopy(CopiesMap &copies) const; \ 00295 static void _static_initialize_(); \ 00296 static StaticInitializer _static_initializer_; \ 00297 static const PPath& declaringFile() { static PPath df= __FILE__; return df;} 00298 00299 #define PLEARN_IMPLEMENT_TEMPLATE_OBJECT(CLASSTYPE, ONELINEDESCR, MULTILINEHELP) \ 00300 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00301 string CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_classname_() \ 00302 { \ 00303 return TEMPLATE_NAME_ ## CLASSTYPE ; \ 00304 } \ 00305 \ 00306 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00307 string CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::classname() const \ 00308 { \ 00309 return _classname_(); \ 00310 } \ 00311 \ 00312 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00313 OptionList& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_getOptionList_() \ 00314 { \ 00315 static OptionList ol; \ 00316 if(ol.empty()) \ 00317 declareOptions(ol); \ 00318 return ol; \ 00319 } \ 00320 \ 00321 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00322 OptionList& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::getOptionList() const \ 00323 { \ 00324 return _getOptionList_(); \ 00325 } \ 00326 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00327 OptionMap& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::getOptionMap() const \ 00328 { \ 00329 static OptionMap om; \ 00330 if(om.empty()) \ 00331 { \ 00332 OptionList& ol= getOptionList(); \ 00333 for(OptionList::iterator it= ol.begin(); it != ol.end(); ++it) \ 00334 /*N.B. option map will contain derived class's option*/ \ 00335 /* when it also exists in a base class. */ \ 00336 om.insert(make_pair((*it)->optionname(), *it)); \ 00337 } \ 00338 return om; \ 00339 } \ 00340 \ 00341 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00342 RemoteMethodMap& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_getRemoteMethodMap_() \ 00343 { \ 00344 static bool initialized = false; \ 00345 static RemoteMethodMap rmm; \ 00346 if (! initialized) { \ 00347 declareMethods(rmm); \ 00348 initialized = true; \ 00349 } \ 00350 return rmm; \ 00351 } \ 00352 \ 00353 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00354 RemoteMethodMap& CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::getRemoteMethodMap() const \ 00355 { \ 00356 return _getRemoteMethodMap_(); \ 00357 } \ 00358 \ 00359 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00360 Object* CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_new_instance_for_typemap_() \ 00361 { \ 00362 return new CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >(); \ 00363 } \ 00364 \ 00365 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00366 bool CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_isa_(const Object* o) \ 00367 { \ 00368 return dynamic_cast<const CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >*>(o) != 0; \ 00369 } \ 00370 \ 00371 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00372 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >* \ 00373 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::deepCopy(CopiesMap& copies) const \ 00374 { \ 00375 CopiesMap::iterator it = copies.find(this); \ 00376 if (it != copies.end()) \ 00377 return static_cast<CLASSTYPE*>(it->second); \ 00378 CLASSTYPE* deep_copy = new CLASSTYPE(dynamic_cast<const CLASSTYPE&>(*this)); \ 00379 copies[this] = deep_copy; \ 00380 deep_copy->makeDeepCopyFromShallowCopy(copies); \ 00381 return deep_copy; \ 00382 } \ 00383 \ 00384 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00385 void CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_static_initialize_() \ 00386 { \ 00387 TypeFactory::register_type( \ 00388 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_classname_(), \ 00389 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::inherited::_classname_(), \ 00390 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_new_instance_for_typemap_, \ 00391 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_getOptionList_, \ 00392 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_getRemoteMethodMap_, \ 00393 &CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_isa_, \ 00394 ONELINEDESCR, \ 00395 MULTILINEHELP, \ 00396 CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::declaringFile()); \ 00397 } \ 00398 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00399 StaticInitializer CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >:: \ 00400 _static_initializer_(&CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >:: \ 00401 _static_initialize_); 00402 00407 #define DECLARE_SPECIALIZED_DIFF_CLASS(CLASSTYPE) \ 00408 template<class ObjectType> \ 00409 class DiffTemplate<ObjectType, CLASSTYPE> { \ 00410 public: \ 00411 static int diff(const string& refer, const string& other, \ 00412 const Option<ObjectType, CLASSTYPE>* opt, \ 00413 PLearnDiff* diffs) \ 00414 { \ 00415 return PLearn::diff(refer, other, opt, diffs); \ 00416 } \ 00417 }; 00418 00426 #define DECLARE_OBJECT_PTR(CLASSTYPE) \ 00427 inline Object *toObjectPtr(const CLASSTYPE &o) \ 00428 { \ 00429 return const_cast<CLASSTYPE *>(&o); \ 00430 } \ 00431 \ 00432 inline PStream &operator>>(PStream &in, CLASSTYPE &o) \ 00433 { \ 00434 o.newread(in); \ 00435 return in; \ 00436 } \ 00437 \ 00438 inline PStream &operator>>(PStream &in, CLASSTYPE * &o) \ 00439 { \ 00440 Object *ptr = o; \ 00441 in >> ptr; \ 00442 o = dynamic_cast<CLASSTYPE *>(ptr); \ 00443 if(ptr!=0 && o==0) \ 00444 PLERROR("Mismatched classes while reading a pointer: %s is not a %s", \ 00445 ptr->classname().c_str(),CLASSTYPE::_classname_().c_str()); \ 00446 return in; \ 00447 } \ 00448 \ 00449 inline PStream &operator<<(PStream &out, const CLASSTYPE &o) \ 00450 { \ 00451 o.newwrite(out); \ 00452 return out; \ 00453 } \ 00454 \ 00455 inline PStream &operator>>(PStream &in, PP<CLASSTYPE> &o) \ 00456 { \ 00457 Object *ptr = (CLASSTYPE *)o; \ 00458 in >> ptr; \ 00459 o = dynamic_cast<CLASSTYPE *>(ptr); \ 00460 if(ptr!=0 && o.isNull()) \ 00461 PLERROR("Mismatched classes while reading a PP: %s is not a %s", \ 00462 ptr->classname().c_str(),CLASSTYPE::_classname_().c_str()); \ 00463 return in; \ 00464 } \ 00465 \ 00466 template<class ObjectType> \ 00467 int diff(const string& refer, const string& other, \ 00468 const Option<ObjectType, CLASSTYPE>* opt, PLearnDiff* diffs) \ 00469 { \ 00470 PP<OptionBase> new_opt = new Option<ObjectType, PP<CLASSTYPE> > \ 00471 (opt->optionname(), 0, 0, "", "", "", opt->level()); \ 00472 return new_opt->diff(refer, other, diffs); \ 00473 } \ 00474 DECLARE_SPECIALIZED_DIFF_CLASS(CLASSTYPE) \ 00475 DECLARE_TYPE_TRAITS(CLASSTYPE) 00476 00477 #define DECLARE_TEMPLATE_OBJECT_PTR(CLASSTYPE) \ 00478 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00479 inline Object *toObjectPtr(const CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > &o) \ 00480 { \ 00481 return const_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *>(&o); \ 00482 } \ 00483 \ 00484 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00485 inline PStream &operator>>(PStream &in, CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > &o) \ 00486 { \ 00487 o.newread(in); return in; \ 00488 } \ 00489 \ 00490 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00491 inline PStream &operator>>(PStream &in, CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > * &o) \ 00492 { \ 00493 if (o) \ 00494 o->newread(in); \ 00495 else \ 00496 o = static_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *>(readObject(in)); \ 00497 return in; \ 00498 } \ 00499 \ 00500 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00501 inline PStream & \ 00502 operator<<(PStream &out, const CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > &o) \ 00503 { \ 00504 o.newwrite(out); \ 00505 return out; \ 00506 } \ 00507 \ 00508 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00509 inline PStream& \ 00510 operator>>(PStream &in, PP<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > > &o) \ 00511 { \ 00512 Object *ptr = (CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *)o; \ 00513 in >> ptr; \ 00514 o = dynamic_cast<CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > *>(ptr); \ 00515 return in; \ 00516 } \ 00517 \ 00518 template < TEMPLATE_DEF_ ## CLASSTYPE > \ 00519 class TypeTraits< CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE > > \ 00520 { \ 00521 public: \ 00522 static inline string name() \ 00523 { return CLASSTYPE< TEMPLATE_ARGS_ ## CLASSTYPE >::_classname_(); } \ 00524 \ 00525 static inline unsigned char little_endian_typecode() \ 00526 { return 0xFF; } \ 00527 \ 00528 static inline unsigned char big_endian_typecode() \ 00529 { return 0xFF; } \ 00530 } 00531 00532 00533 00540 #define DECLARE_OBJECT_PP_SERIALIZE(PPCLASSTYPE, CLASSTYPE) \ 00541 inline PStream &operator>>(PStream &in, PPCLASSTYPE &o) \ 00542 { Object *ptr = 0; \ 00543 in >> ptr; \ 00544 o = dynamic_cast<CLASSTYPE *>(ptr); \ 00545 return in; } \ 00546 inline PStream &operator<<(PStream &out, const PPCLASSTYPE &o) \ 00547 { out << static_cast<const PP<CLASSTYPE> &>(o); return out; } \ 00548 DECLARE_TYPE_TRAITS(PPCLASSTYPE) 00549 00550 #ifdef PL_PYTHON_VERSION 00551 #define DECLARE_OBJECT_PP(PPCLASSTYPE, CLASSTYPE) \ 00552 template<> struct ConvertFromPyObject<PPCLASSTYPE> \ 00553 { \ 00554 static PPCLASSTYPE convert(PyObject* o, \ 00555 bool print_traceback) \ 00556 { return PPCLASSTYPE(ConvertFromPyObject<PP<CLASSTYPE> > \ 00557 ::convert(o, print_traceback)); } \ 00558 }; \ 00559 template<> struct ConvertToPyObject<PPCLASSTYPE> \ 00560 { \ 00561 static PyObject* newPyObject(const PPCLASSTYPE& x) \ 00562 {return ConvertToPyObject<PP<CLASSTYPE> >::newPyObject(x);} \ 00563 }; \ 00564 DECLARE_OBJECT_PP_SERIALIZE(PPCLASSTYPE, CLASSTYPE) 00565 #else //def PL_PYTHON_VERSION 00566 #define DECLARE_OBJECT_PP(PPCLASSTYPE, CLASSTYPE) \ 00567 DECLARE_OBJECT_PP_SERIALIZE(PPCLASSTYPE, CLASSTYPE) 00568 #endif //def PL_PYTHON_VERSION 00569 00570 00571 //##### PLearn::Object ###################################################### 00572 00626 class Object: public PPointable 00627 { 00628 typedef Object inherited; 00629 00630 public: 00631 //##### Public Interface ################################################ 00632 00633 PLEARN_DECLARE_OBJECT(Object); 00634 00644 Object(bool call_build_ = false); 00645 00647 virtual ~Object(); 00648 00649 // We rely on the default compiler-generated copy constructor and 00650 // assignment operator. 00651 00658 virtual void build(); 00659 00680 virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies); 00681 00688 virtual string info() const; 00689 00693 virtual string asString() const; 00694 00698 virtual string asStringRemoteTransmit() const; 00699 00700 //##### Options-Related Functions ####################################### 00701 00712 void readOptionVal(PStream &in, const string &optionname, unsigned int id = UINT_MAX); 00713 00722 void writeOptionVal(PStream &out, const string &optionname) const; 00723 00749 bool parseOptionName(const string& optionname, 00750 Object*& final_object, 00751 OptionList::iterator& option_iter, 00752 string& option_index); 00753 00757 bool parseOptionName(const string& optionname, 00758 const Object*& final_object, 00759 OptionList::iterator& option_iter, 00760 string& option_index) const; 00761 00770 virtual string getOptionsToSave() const; 00771 00776 virtual string getOptionsToRemoteTransmit() const; 00777 00796 void setOption(const string& optionname, const string& value); 00797 00798 #ifdef PL_PYTHON_VERSION 00799 void setOptionFromPython(const string& optionname, const PythonObjectWrapper& value); 00800 #endif //def PL_PYTHON_VERSION 00801 00807 bool hasOption(const string &optionname) const; 00808 00821 string getOption(const string &optionname) const; 00822 00835 virtual void changeOptions(const map<string,string>& name_value); 00836 00838 void changeOption(const string& optionname, const string& value); 00839 00840 00841 //##### Input/Output-Related Functions ################################## 00842 00855 virtual void newwrite(PStream& out) const; 00856 00868 void newread(PStream& in, unsigned int id = UINT_MAX); 00869 00870 00871 //##### Remote Method Invocation ######################################## 00872 00915 virtual void call(const string& methodname, int nargs, PStream& io); 00916 00918 static void prepareToSendResults(PStream& out, int nres); 00919 00926 virtual void run(); 00927 00928 00929 //##### Deprecated Interfaces ########################################### 00930 00945 virtual void write(ostream& out) const; 00946 00960 virtual void read(istream& in); 00961 00963 virtual void oldread(istream& in); 00964 00970 virtual void save(const PPath& filename) const; 00971 00977 virtual void load(const PPath& filename); 00978 00983 Object* deepCopyNoMap(); 00984 00985 #ifdef PL_PYTHON_VERSION 00986 00989 tuple<Object*, CopiesMap> pyDeepCopy(CopiesMap& copies); 00990 #endif //def PL_PYTHON_VERSION 00991 00992 protected: 00993 //##### Protected Member Functions ###################################### 00994 01018 static void declareOptions(OptionList& ol) { } 01019 01099 static void declareMethods(RemoteMethodMap& rmm); 01100 01101 private: 01102 //##### Private Member Functions ######################################## 01103 01114 void build_(); 01115 01118 void remote_save(const string& filepath, const string& io_formatting) const; 01119 }; 01120 01121 01125 void callFunction(const string& funcname, int nargs, PStream& io); 01126 01127 01128 //##### Inline Implementations ############################################## 01129 01142 Object *readObject(PStream &in, unsigned int id = UINT_MAX); 01143 inline Object *readObject(istream &in_) 01144 { 01145 PStream in(&in_); 01146 return readObject(in); 01147 } 01148 01150 Object* loadObject(const PPath &filename); 01151 01155 Object* macroLoadObject(const PPath &filename, map<string,string>& vars); 01156 01158 Object* macroLoadObject(const PPath &filename); 01159 01164 inline Object* newObject(const string& representation) 01165 { 01166 PStream in = openString(representation, PStream::plearn_ascii); 01167 return readObject(in); 01168 } 01169 01170 Object* newObjectFromClassname(const string& classname); 01171 01172 Object* remote_deepCopy(Object* source); 01173 01174 inline PStream &operator>>(PStream &in, Object &o) 01175 { 01176 o.newread(in); 01177 return in; 01178 } 01179 01180 inline PStream &operator<<(PStream &out, const Object &o) 01181 { 01182 o.newwrite(out); 01183 return out; 01184 } 01185 01186 01188 PStream &operator>>(PStream &in, Object * &o); 01189 01190 } // end of namespace PLearn 01191 01193 extern "C" void printobj(PLearn::Object* p); 01194 01195 #endif //!< Object_INC 01196 01197 01198 /* 01199 Local Variables: 01200 mode:c++ 01201 c-basic-offset:4 01202 c-file-style:"stroustrup" 01203 c-file-offsets:((innamespace . 0)(inline-open . 0)) 01204 indent-tabs-mode:nil 01205 fill-column:79 01206 End: 01207 */ 01208 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :