PLearn 0.1
|
00001 // -*- C++ -*- 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 // 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 /* ******************************************************* 00040 * $Id: PP.h 8255 2007-11-14 14:57:45Z nouiz $ 00041 * AUTHORS: Pascal Vincent & Yoshua Bengio 00042 * This file is part of the PLearn library. 00043 ******************************************************* */ 00044 00045 00048 #ifndef SMART_POINTER_INC 00049 #define SMART_POINTER_INC 00050 00051 #include <typeinfo> 00052 #include "TypeTraits.h" 00053 #include "CopiesMap.h" 00054 #include "plerror.h" 00055 00056 namespace PLearn { 00057 using std::string; 00058 00059 class PPointable 00060 { 00061 private: 00062 int refcount; 00063 00064 public: 00065 inline PPointable() 00066 :refcount(0) 00067 {} 00068 00069 inline PPointable(const PPointable& other) 00070 :refcount(0) 00071 {} 00072 00073 inline void ref() const 00074 { const_cast<PPointable*>(this)->refcount++; } 00075 00076 inline void unref() const 00077 { 00078 const_cast<PPointable*>(this)->refcount--; 00079 if(refcount==0) 00080 delete this; 00081 } 00082 00083 inline int usage() const 00084 { return refcount; } 00085 00086 virtual ~PPointable() {} 00087 }; 00088 00089 template<class T> 00090 class PP 00091 { 00092 protected: 00093 T* ptr; 00094 00095 public: 00096 00098 typedef T element_type; 00099 00101 inline PP<T>() 00102 :ptr(0) 00103 {} 00104 00106 inline PP<T>(const T* the_ptr) 00107 { 00108 ptr = const_cast<T*>(the_ptr); 00109 if(ptr) 00110 ptr->ref(); 00111 } 00112 00114 inline PP<T>(const PP<T>& other) 00115 { 00116 ptr = const_cast<T*>((T*)other); 00117 if(ptr) 00118 ptr->ref(); 00119 } 00120 00122 template <class U> 00123 explicit PP<T>(const PP<U>& other) 00124 { 00125 if(other.isNull()) 00126 ptr = 0; 00127 else 00128 { 00131 ptr = static_cast<T*>((U*)other); 00132 00138 ptr = dynamic_cast<T*>((U*)other); 00139 00144 if (!ptr) 00145 PLERROR("In PP constructor from smart pointer " 00146 "of other class (constructing %s from %s)", 00147 typeid(T).name(),typeid(U).name()); 00148 ptr->ref(); 00149 } 00150 } 00151 00152 inline bool isNull() const 00153 { return ptr==0; } 00154 00155 inline bool isNotNull() const 00156 { return ptr!=0; } 00157 00159 inline operator T*() const 00160 { return ptr; } 00161 00163 inline T* operator->() const 00164 { return ptr; } 00165 00167 inline T& operator*() const 00168 { return *ptr; } 00169 00171 inline PP<T>& operator=(const T* otherptr) 00172 { 00173 if(otherptr!=ptr) 00174 { 00175 if(ptr) 00176 ptr->unref(); 00177 ptr = const_cast<T*>(otherptr); 00178 if(ptr) 00179 ptr->ref(); 00180 } 00181 return *this; 00182 } 00183 00185 inline PP<T>& operator=(const PP<T>& other) 00186 { return operator=((T*)other); } 00187 00188 inline bool operator==(const PP<T>& other) const 00189 { return ptr==other.ptr; } 00190 00191 inline bool operator==(const T* other) const 00192 { return ptr==other; } 00193 00194 inline ~PP() 00195 { 00196 if(ptr) 00197 ptr->unref(); 00198 } 00199 00200 }; 00201 00202 template <class T> 00203 inline bool operator==(const T* ptr, const PP<T>& b) 00204 { return ptr==b.ptr; } 00205 00207 // deepCopyField // 00210 template <class T> 00211 inline void deepCopyField(PP<T>& field, CopiesMap& copies) 00212 { 00213 if (field) { 00214 // Check the usage of the object pointed by 'field': it should be > 1, 00215 // because 'field' is a shallow copy. However, it *could* happen that it 00216 // is only 1, if the object that pointed to the same object has been deleted. 00217 // Since this is usually not wanted, we display a warning if this happens. 00218 // Indeed, there is a risk of this causing trouble, because the 'copies' map 00219 // may contain invalid mappings refering to now deleted objects. 00220 if (field->usage() == 1) 00221 PLWARNING("In deepCopyField(PP<T>& field, ...) - The usage() of the underlying object is only 1, this is unusual\n" 00222 "( Did you call inherited::makeDeepCopyFromShallowCopy twice? You can't. )"); 00223 field = field->deepCopy(copies); 00224 } 00225 } 00226 00228 template<class T> 00229 T* deepCopy(PP<T> source, CopiesMap& copies) 00230 { return deepCopy((T*)source, copies); } 00231 00233 00237 template<class T> 00238 inline T* deepCopy(PP<T> source) 00239 { 00240 if (source.isNull()) return NULL; 00241 00242 CopiesMap copies; 00243 return deepCopy(source, copies); 00244 } 00245 00246 00247 template<class T> 00248 class TypeTraits< PP<T> > 00249 { 00250 public: 00251 static string name() 00252 { return string("PP< ") + TypeTraits<T>::name()+" >"; } 00253 00254 static inline unsigned char little_endian_typecode() 00255 { return 0xFF; } 00256 00257 static inline unsigned char big_endian_typecode() 00258 { return 0xFF; } 00259 }; 00260 00261 template <class A, class B> 00262 class MultiMap : public PPointable 00263 { 00264 public: 00265 std::multimap<A,B> map; 00266 }; 00267 00268 00269 template <class T> 00270 T* get_pointer(PP<T> const& p) 00271 { 00272 return p; 00273 } 00274 00275 template <class T> 00276 inline int sizeInBytes(PP<T> x) { 00277 int n = sizeof(T*); 00278 if (x) 00279 n+= sizeInBytes(*x); 00280 return n; 00281 } 00282 00283 } // end of namespace PLearn 00284 00285 #endif 00286 00287 00288 /* 00289 Local Variables: 00290 mode:c++ 00291 c-basic-offset:4 00292 c-file-style:"stroustrup" 00293 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00294 indent-tabs-mode:nil 00295 fill-column:79 00296 End: 00297 */ 00298 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :