realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/shared_object.hpp
Go to the documentation of this file.
00001 /********************************************************************
00002  *   This file is part of the source code of the realroot library.
00003  *   Author(s): B. Mourrain, GALAAD, INRIA
00004  *   $Id: shared_object.hpp,v 1.1 2005/07/11 11:23:12 mourrain Exp $
00005  ********************************************************************/
00006 #ifndef mmx_shared_object_hpp
00007 #define mmx_shared_object_hpp
00008 //--------------------------------------------------------------------
00009 #include <cassert>
00010 #include <memory>
00011 #include <utility>
00012 #include <iterator>
00013 #include <algorithm>
00014 #include <set>
00015 #include <typeinfo>
00016 //======================================================================
00017 namespace mmx {
00018 
00019 #define define_operator_rrr(parm0,parm1,parm2,opname,function)  \
00020 inline parm0                                                    \
00021 opname(const parm1& x, const parm2& y) {                        \
00022   parm0 r; function(r.rep(),x.rep(),y.rep()); return r;         \
00023 }
00024 
00025 #define define_operator_rr_(parm0,parm1,parm2,opname,function)  \
00026 inline                                                          \
00027 parm0 opname(const parm1& x, const parm2& y) {                  \
00028   parm0 r; function(r.rep(),x.rep(),y); return r;               \
00029 }
00030 #define define_operator_r_r(parm0,parm1,parm2,opname,function)  \
00031 inline                                                          \
00032 parm0 opname(const parm1& x, const parm2& y) {                  \
00033   parm0 r; function(r.rep(),x,y.rep()); return r;               \
00034 }
00035 
00036 #define define_operator__r_(parm0,parm1,parm2,opname,function)  \
00037 inline                                                          \
00038 parm0 opname(const parm1& x, const parm2& y) {                  \
00039   parm0 r; function(r,x.rep(),y); return r;                     \
00040 }
00041 
00042 
00043 #define define_function_from_inplace(parm0,parm1,parm2,function)             \
00044 inline                                                          \
00045 void function(parm0& r, const parm1& x, const parm2& y) {       \
00046   r=x;function(r,y);                                            \
00047 }
00048 
00049 #ifndef assert
00050 #define assert(expr,msg) if (!(expr)) assert (msg);
00051 #endif
00052 
00053 //======================================================================
00054 struct AsSize {};
00055 //--------------------------------------------------------------------
00056 template <class R>
00057 class shared_object {
00058 
00059 public:
00060   typedef R element_type;
00061   //  typedef typename FUNC_ARG(element_type) func_arg;
00062 
00063 protected:
00064   struct rep
00065   //    : generic_rep
00066   {
00067     int refc;
00068     R obj;
00069 
00070     template<class P0>
00071     rep(P0 a) : refc(1), obj(a) {};
00072 
00073     template<class P0, class P1>
00074     rep(P0 a, P1 b ) : refc(1), obj(a,b) {};
00075 
00076     template<class P0, class P1, class P2>
00077     rep(P0 a, P1 b, P2 c ) : refc(1), obj(a,b,c) {};
00078     
00079     template<class P0, class P1, class P2, class P3 >
00080     rep(P0 a, P1 b, P2 c, P3 d) : refc(1), obj(a,b,c,d) {};
00081 
00082     rep() : refc(1) {//std::cout<<"build data "<< refc<<std::endl;
00083     }
00084 
00085     rep(const rep& o) : refc(1), obj(o.obj)  { }
00086     ~rep() {}
00087     void*   operator new(size_t s)
00088       {return std::allocator<R>().allocate(s); }
00089     void  operator delete(void* p)
00090     {std::allocator<R>().deallocate((R*)p,sizeof(rep)); }
00091 
00092 //     static const int TYPE=3000;
00093 //     int Type() {return TYPE;}
00094   };
00095 
00096 public:
00097    rep *body;
00098 
00099    void leave()
00100   {assert(body->refc>0);
00101     //std::cout<<"Leave  "<<body<<" "<<body->refc<<std::endl; 
00102     if (! --body->refc) delete body;}
00103    void divorce()
00104     {assert(body->refc>1); --body->refc; body= new rep(*body);}
00105 
00106   typedef R object_type;
00107   typedef R* iterator;
00108   typedef const R* const_iterator;
00109 
00110   template<class P0>
00111   shared_object(P0 a) : body(new rep(a)){};
00112   template<class P0, class P1>
00113   shared_object(P0 a, P1 b) : body(new rep(a,b)){};
00114   template<class P0, class P1, class P2>
00115   shared_object(P0 a, P1 b, P2 c) : body(new rep(a,b,c)){};
00116   template<class P0, class P1, class P2, class P3>
00117   shared_object(P0 a, P1 b, P2 c, P3 d) : body(new rep(a,b,c,d)){};
00118   shared_object() : body(new rep())  {
00119     //std::cout<<"body   "<<body<<" "<<body->refc<<std::endl; 
00120   }
00121   shared_object(const R& obj_arg) : body(new rep(obj_arg)) {}
00122   shared_object(const shared_object& s) : body(s.body) {++body->refc;}
00123   shared_object(rep * s) : body(s) {++body->refc;}
00124   ~shared_object() {leave(); }
00125 
00126   shared_object& operator= (const shared_object& s)
00127     {
00128       if (this!=&s) {s.body->refc++; leave(); body=s.body;}
00129       return *this;
00130     }
00131 
00132   void swap(shared_object& s2) { std::swap(body,s2.body); }
00133 
00134   iterator operator-> () { if (body->refc > 1) divorce(); return &body->obj; }
00135   R&  operator*  () { if (body->refc > 1) divorce(); return  body->obj; }
00136 
00137   const_iterator operator-> () const { return &body->obj; }
00138   const R&  operator*  () const { return  body->obj; }
00139 
00140   int ref() const   {return body->refc;}
00141   int ref()         {return body->refc;}
00142 
00143 };
00144 
00145 // template<typename R> inline
00146 // R view_as (generic g)
00147 // {
00148 //   typedef  typename R::rep_type REP;
00149 //   if (gentype(g) != shared_object<REP>::rep::TYPE)
00150 //     std::cerr<<"generic  of type "<<gentype(g)
00151 //           <<"is not an obj of required type "
00152 //      << shared_object<REP>::rep::TYPE<<std::endl;
00153 //   shared_object<REP> x((typename shared_object<REP>::rep*)g.rep);
00154 //   return  R(x);//(REP*)g.rep);
00155 // }
00156 template< class R>
00157   struct rep_view
00158   {
00159 #define NOREFCOUNT
00160 #ifdef  NOREFCOUNT
00161     R data;
00162     R &       rep()       {return data;}
00163     const R & rep() const {return data;}
00164 #else
00165     shared_object<R> data;
00166     R &       rep()       {return *data;}
00167     const R & rep() const {return *data;}
00168 #endif
00169   };
00170 //----------------------------------------------------------------------
00172 template<class R>
00173 inline       R & rep(R & r)       {return r;}
00174 
00176 template<class R>
00177 inline const R & rep(const R & r) {return r;}
00178 
00180 template<class R>
00181 inline       R & rep(shared_object<R> & r)       {return *r;}
00182 
00184 template<class R>
00185 inline const R & rep(const shared_object<R> & r) {return *r;}
00186 
00188 
00194 template<class T>
00195 struct ReferTo
00196 {
00198   typedef T value_type;
00199 };
00200 
00202 
00208 template<class T>
00209 struct ReferTo<shared_object<T> >
00210 {
00212   typedef T value_type;
00213 };
00214 
00215 
00216 //======================================================================
00217 } //namespace mmx
00218 //======================================================================
00219 #endif // mmx_shared_object_hpp
00220