synaps/base/shared_object.h

00001 /********************************************************************
00002  *   This file is part of the source code of the SYNAPS library.
00003  *   Author(s): B. Mourrain, GALAAD, INRIA
00004  *   $Id: shared_object.h,v 1.1 2005/07/11 11:23:12 mourrain Exp $
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 //#include <synaps/base/const_ref_or_val.h>
00019 /********************************************************************/
00020 __BEGIN_NAMESPACE_SYNAPS
00021 //--------------------------------------------------------------------
00022 
00023 template <class R>
00024 class shared_object {
00025 
00026 public:
00027   typedef R element_type;
00028   //  typedef typename FUNC_ARG(element_type) func_arg;
00029 
00030 protected:
00031   struct rep
00032   //    : generic_rep
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 //     static const int TYPE=3000;
00059 //     int Type() {return TYPE;}
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 // template<typename R> inline
00108 // R view_as (generic g)
00109 // {
00110 //   typedef  typename R::rep_type REP;
00111 //   if (gentype(g) != shared_object<REP>::rep::TYPE)
00112 //     std::cerr<<"generic  of type "<<gentype(g)
00113 //           <<"is not an obj of required type "
00114 //      << shared_object<REP>::rep::TYPE<<std::endl;
00115 //   shared_object<REP> x((typename shared_object<REP>::rep*)g.rep);
00116 //   return  R(x);//(REP*)g.rep);
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 

SYNAPS DOCUMENTATION
logo