realroot_doc 0.1.1
|
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