00001
00002
00003
00004
00005
00006 #ifndef synaps_util_shared_object_H
00007 #define synaps_util_shared_object_H
00008
00009 #include <synaps/init.h>
00010 #include <cassert>
00011 #include <memory>
00012 #include <utility>
00013 #include <iterator>
00014 #include <algorithm>
00015 #include <set>
00016 #include <typeinfo>
00017 #include <synaps/init.h>
00018
00019
00020 __BEGIN_NAMESPACE_SYNAPS
00021
00022
00023 template <class R>
00024 class shared_object {
00025
00026 public:
00027 typedef R element_type;
00028
00029
00030 protected:
00031 struct rep
00032
00033 {
00034 int refc;
00035 R obj;
00036
00037 template<class P0>
00038 rep(P0 a) : refc(1), obj(a) {};
00039
00040 template<class P0, class P1>
00041 rep(P0 a, P1 b ) : refc(1), obj(a,b) {};
00042
00043 template<class P0, class P1, class P2>
00044 rep(P0 a, P1 b, P2 c ) : refc(1), obj(a,b,c) {};
00045
00046 template<class P0, class P1, class P2, class P3 >
00047 rep(P0 a, P1 b, P2 c, P3 d) : refc(1), obj(a,b,c,d) {};
00048
00049 rep() : refc(1) { }
00050
00051 rep(const rep& o) : refc(1), obj(o.obj) { }
00052 ~rep() {}
00053 void* operator new(size_t s)
00054 {return std::allocator<R>().allocate(s); }
00055 void operator delete(void* p)
00056 {std::allocator<R>().deallocate((R*)p,sizeof(rep)); }
00057
00058
00059
00060 };
00061
00062 public:
00063 rep *body;
00064
00065 void leave()
00066 {assert(body->refc>0);if (! --body->refc) delete body;}
00067 void divorce()
00068 {assert(body->refc>1); --body->refc; body= new rep(*body);}
00069
00070 typedef R object_type;
00071 typedef R* iterator;
00072 typedef const R* const_iterator;
00073
00074 template<class P0>
00075 shared_object(P0 a) : body(new rep(a)){};
00076 template<class P0, class P1>
00077 shared_object(P0 a, P1 b) : body(new rep(a,b)){};
00078 template<class P0, class P1, class P2>
00079 shared_object(P0 a, P1 b, P2 c) : body(new rep(a,b,c)){};
00080 template<class P0, class P1, class P2, class P3>
00081 shared_object(P0 a, P1 b, P2 c, P3 d) : body(new rep(a,b,c,d)){};
00082 shared_object() : body(new rep()) { }
00083 shared_object(const R& obj_arg) : body(new rep(obj_arg)) { }
00084 shared_object(const shared_object& s) : body(s.body) {++body->refc;}
00085 shared_object(rep * s) : body(s) {++body->refc;}
00086 ~shared_object() {leave(); }
00087
00088 shared_object& operator= (const shared_object& s)
00089 {
00090 if (this!=&s) {s.body->refc++; leave(); body=s.body;}
00091 return *this;
00092 }
00093
00094 void swap(shared_object& s2) { std::swap(body,s2.body); }
00095
00096 iterator operator-> () { if (body->refc > 1) divorce(); return &body->obj; }
00097 R& operator* () { if (body->refc > 1) divorce(); return body->obj; }
00098
00099 const_iterator operator-> () const { return &body->obj; }
00100 const R& operator* () const { return body->obj; }
00101
00102 int ref() const {return body->refc;}
00103 int ref() {return body->refc;}
00104
00105 };
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 template< class R>
00119 struct rep_view
00120 {
00121 #define NOREFCOUNT
00122 #ifdef NOREFCOUNT
00123 R data;
00124 R & rep() {return data;}
00125 const R & rep() const {return data;}
00126 #else
00127 shared_object<R> data;
00128 R & rep() {return *data;}
00129 const R & rep() const {return *data;}
00130 #endif
00131 };
00132
00134 template<class R>
00135 inline R & rep(R & r) {return r;}
00136
00138 template<class R>
00139 inline const R & rep(const R & r) {return r;}
00140
00142 template<class R>
00143 inline R & rep(shared_object<R> & r) {return *r;}
00144
00146 template<class R>
00147 inline const R & rep(const shared_object<R> & r) {return *r;}
00148
00150
00156 template<class T>
00157 struct ReferTo
00158 {
00160 typedef T value_type;
00161 };
00162
00164
00170 template<class T>
00171 struct ReferTo<shared_object<T> >
00172 {
00174 typedef T value_type;
00175 };
00176
00177 __END_NAMESPACE_SYNAPS
00178
00179
00180 #endif // synaps_util_shared_object_H
00181