00001
00002
00003
00004
00005
00006 #ifndef mmx_shared_object_hpp
00007 #define mmx_shared_object_hpp
00008
00009 #include <cassert>
00010 #include <memory>
00011
00012
00013
00014
00015
00016
00017 namespace mmx {
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define define_operator_rrr(parm0,parm1,parm2,opname,function) \
00027 inline parm0 \
00028 opname(const parm1& x, const parm2& y) { \
00029 parm0 r; function(r.rep(),x.rep(),y.rep()); return r; \
00030 }
00031
00032 #define define_operator_rr_(parm0,parm1,parm2,opname,function) \
00033 inline \
00034 parm0 opname(const parm1& x, const parm2& y) { \
00035 parm0 r; function(r.rep(),x.rep(),y); return r; \
00036 }
00037 #define define_operator_r_r(parm0,parm1,parm2,opname,function) \
00038 inline \
00039 parm0 opname(const parm1& x, const parm2& y) { \
00040 parm0 r; function(r.rep(),x,y.rep()); return r; \
00041 }
00042
00043 #define define_operator__r_(parm0,parm1,parm2,opname,function) \
00044 inline \
00045 parm0 opname(const parm1& x, const parm2& y) { \
00046 parm0 r; function(r,x.rep(),y); return r; \
00047 }
00048
00049
00050 #define define_function_from_inplace(parm0,parm1,parm2,function) \
00051 inline \
00052 void function(parm0& r, const parm1& x, const parm2& y) { \
00053 r=x;function(r,y); \
00054 }
00055
00056 #ifndef assert
00057 #define assert(expr,msg) if (!(expr)) assert (msg);
00058 #endif
00059
00060
00061 struct AsSize {};
00062
00063 template <class R>
00064 class shared_object {
00065
00066 public:
00067 typedef R element_type;
00068
00069
00070 protected:
00071 struct rep
00072
00073 {
00074 int refc;
00075 R obj;
00076
00077 template<class P0>
00078 rep(P0 a) : refc(1), obj(a) {};
00079
00080 template<class P0, class P1>
00081 rep(P0 a, P1 b ) : refc(1), obj(a,b) {};
00082
00083 template<class P0, class P1, class P2>
00084 rep(P0 a, P1 b, P2 c ) : refc(1), obj(a,b,c) {};
00085
00086 template<class P0, class P1, class P2, class P3 >
00087 rep(P0 a, P1 b, P2 c, P3 d) : refc(1), obj(a,b,c,d) {};
00088
00089 rep() : refc(1) {
00090 }
00091
00092 rep(const rep& o) : refc(1), obj(o.obj) { }
00093 ~rep() {}
00094 void* operator new(size_t s)
00095 {return std::allocator<R>().allocate(s); }
00096 void operator delete(void* p)
00097 {std::allocator<R>().deallocate((R*)p,sizeof(rep)); }
00098
00099
00100
00101 };
00102
00103 public:
00104 rep *body;
00105
00106 void leave()
00107 {assert(body->refc>0);
00108
00109 if (! --body->refc) delete body;}
00110 void divorce()
00111 {assert(body->refc>1); --body->refc; body= new rep(*body);}
00112
00113 typedef R object_type;
00114 typedef R* iterator;
00115 typedef const R* const_iterator;
00116
00117 template<class P0>
00118 shared_object(P0 a) : body(new rep(a)){};
00119 template<class P0, class P1>
00120 shared_object(P0 a, P1 b) : body(new rep(a,b)){};
00121 template<class P0, class P1, class P2>
00122 shared_object(P0 a, P1 b, P2 c) : body(new rep(a,b,c)){};
00123 template<class P0, class P1, class P2, class P3>
00124 shared_object(P0 a, P1 b, P2 c, P3 d) : body(new rep(a,b,c,d)){};
00125 shared_object() : body(new rep()) {
00126
00127 }
00128 shared_object(const R& obj_arg) : body(new rep(obj_arg)) {}
00129 shared_object(const shared_object& s) : body(s.body) {++body->refc;}
00130 shared_object(rep * s) : body(s) {++body->refc;}
00131 ~shared_object() {leave(); }
00132
00133 shared_object& operator= (const shared_object& s)
00134 {
00135 if (this!=&s) {s.body->refc++; leave(); body=s.body;}
00136 return *this;
00137 }
00138
00139
00140
00141 iterator operator-> () { if (body->refc > 1) divorce(); return &body->obj; }
00142 R& operator* () { if (body->refc > 1) divorce(); return body->obj; }
00143
00144 const_iterator operator-> () const { return &body->obj; }
00145 const R& operator* () const { return body->obj; }
00146
00147 int ref() const {return body->refc;}
00148 int ref() {return body->refc;}
00149
00150 };
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 template< class R>
00164 struct rep_view
00165 {
00166 #define NOREFCOUNT
00167 #ifdef NOREFCOUNT
00168 R data;
00169 R & rep() {return data;}
00170 const R & rep() const {return data;}
00171 #else
00172 shared_object<R> data;
00173 R & rep() {return *data;}
00174 const R & rep() const {return *data;}
00175 #endif
00176 };
00177
00179 template<class R>
00180 inline R & rep(R & r) {return r;}
00181
00183 template<class R>
00184 inline const R & rep(const R & r) {return r;}
00185
00187 template<class R>
00188 inline R & rep(shared_object<R> & r) {return *r;}
00189
00191 template<class R>
00192 inline const R & rep(const shared_object<R> & r) {return *r;}
00193
00195
00201 template<class T>
00202 struct ReferTo
00203 {
00205 typedef T value_type;
00206 };
00207
00209
00215 template<class T>
00216 struct ReferTo<shared_object<T> >
00217 {
00219 typedef T value_type;
00220 };
00221
00222
00223
00224 }
00225
00226 #endif // mmx_shared_object_hpp
00227