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