PLearn 0.1
PP.h
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines