Changeset e318c0 in git


Ignore:
Timestamp:
Sep 5, 2012, 3:18:48 PM (10 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'ad2543eab51733612ba7d118afc77edca719600e')
Children:
cda275f5c6745c233d1ee5261720c388c5286ec9
Parents:
a010d6eaa276986ef854adc014c99f570301d549
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-09-05 15:18:48+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:17+02:00
Message:
Introducing weak reference for back-referenceing data

chg: more strict (added private+friend)
Location:
Singular
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    ra010d6 re318c0  
    352352  public RefCounter {
    353353  typedef CountedRefData self;
    354   typedef CountedRefPtr<self*, false, true> self_ptr;
     354  typedef CountedRefWeakPtr<self*> back_ptr;
    355355  typedef RefCounter base;
    356356
    357357  /// Generate object linked to other reference (e.g. for subscripts)
    358   CountedRefData(leftv wrapped, self_ptr back):
    359     base(), m_data(wrapped), m_ring(back->m_ring), m_back(back) {  }
    360 
    361   /// @name  isallow copying to avoid inconsistence
     358  CountedRefData(leftv wrapped, back_ptr back):
     359    base(), m_data(wrapped), m_ring(back->m_ring), m_back(back) {
     360  }
     361
     362  /// @name Disallow copying to avoid inconsistence
    362363  //@{
    363364  self& operator=(const self&);
    364365  CountedRefData(const self&);
    365366  //@}
     367
    366368public:
    367369  typedef LeftvDeep::copy_tag copy_tag;
    368370
    369371  /// Fix smart pointer type to referenced data
    370   typedef self_ptr ptr_type;
     372  typedef back_ptr::ptr_type ptr_type;
    371373
    372374  /// Fix smart pointer type to ring
     
    386388
    387389  /// Destruct
    388   ~CountedRefData() {  if (m_back)  m_data.clearid(root()); }
    389 
    390   /// Generate
    391   ptr_type subscripted() {
    392     return new self(m_data.idify(root()),
    393                     m_back? m_back: ptr_type(this));
    394   }
    395 
     390  ~CountedRefData() {
     391    if (!m_back.unassigned()) {
     392      if (m_back == this)
     393        m_back.invalidate();
     394      else
     395        m_data.clearid(root());
     396    }
     397  }
     398
     399  /// Generate object for indexing
     400  ptr_type subscripted() { return new self(m_data.idify(root()), weakref()); }
     401
     402  /// Gerenate  weak (but managed) reference to @c *this
     403  back_ptr weakref() {
     404    if (m_back.unassigned())
     405      m_back = this;
     406    return m_back;
     407  }
    396408  /// Replace with other Singular data
    397409  self& operator=(leftv rhs) {
     
    410422  BOOLEAN rering() {
    411423    if (m_ring ^ m_data.ringed()) m_ring = (m_ring? NULL: currRing);
    412     return (m_back && m_back->rering());
     424    return (m_back && (m_back != this) && m_back->rering());
    413425  }
    414426
     
    418430  /// Check whether identifier became invalid
    419431  BOOLEAN broken() const {
     432    if (!m_back.unassigned() && !m_back)
     433      return complain("Back-reference broken");   
     434
    420435    if (m_ring) {
    421436      if (m_ring != currRing)
     
    466481
    467482  /// Reference to actual object for indexed structures 
    468   ptr_type m_back;
     483  back_ptr m_back;
    469484};
    470485
     
    492507
    493508  /// Fix smart pointer type to referenced data
    494   typedef data_type::ptr_type data_ptr;
     509  typedef CountedRefPtr<CountedRefData*> data_ptr;
    495510
    496511  /// Check whether argument is already a reference type
  • Singular/countedref.h

    ra010d6 re318c0  
    2626 *
    2727 * The template arguments, include the pointer type @c PtrType, and two
    28  * integral (bool) properties: use @c isWeak to disallow destruction
     28 * integral (bool) properties: use @c Nondestructive to disallow destruction
    2929 * and @c NeverNull to assume, that @c PtrType cannot be @c NULL.
    3030 * Finally, @c CountType allows you to select a typ to represent the internal reference count.
     
    3434 * In addition you must overload @c void CountedRefPtr_kill(PtrType) accordingly.
    3535 **/
    36 template <class PtrType, bool isWeak = false, bool NeverNull = false, class CountType = short>
     36template <class PtrType, bool Nondestructive = false, bool NeverNull = false,
     37          class CountType = short>
    3738class CountedRefPtr {
    3839  typedef CountedRefPtr self;
     
    4243  typedef PtrType ptr_type;
    4344  typedef CountType count_type;
    44   enum { is_weak = isWeak, never_null = NeverNull };
     45  enum { nondestructive = Nondestructive, never_null = NeverNull };
    4546  //}
    4647
     
    5354  /// Convert from compatible smart pointer
    5455  template <bool Never>
    55   CountedRefPtr(const CountedRefPtr<ptr_type, !is_weak, Never, count_type>& rhs):
     56  CountedRefPtr(const CountedRefPtr<ptr_type, !nondestructive, Never, count_type>& rhs):
    5657    m_ptr(rhs.m_ptr) { reclaim(); }
    5758
     
    8586  //}
    8687
    87   //{ @name Reference count interface
     88  /// @name Reference count interface
     89  //@{
    8890  count_type count() const { return (*this? m_ptr->ref: 0); }
    8991  void reclaim() { if (*this) ++m_ptr->ref; }
    9092  void release() {
    91     if (*this && (--m_ptr->ref <= 0) && !is_weak)
     93    if (*this && (--m_ptr->ref <= 0) && !nondestructive)
    9294      CountedRefPtr_kill(m_ptr);
    9395  }
    94   //}
     96  //@}
    9597
    9698private:
     
    127129  count_type ref;  // naming consistent with other classes
    128130};
    129 #if 0
    130 class CountedRefEnv {
    131   typedef CountedRefEnv self;
    132 
    133 public:
    134   static leftv idify(leftv head, idhdl* root) {
    135     idhdl handle = newid(head, root);
    136     leftv res = (leftv)omAlloc0(sizeof(*res));
    137     res->data =(void*) handle;
    138     res->rtyp = IDHDL;
    139     return res;
    140   }
    141 
    142   static idhdl newid(leftv head, idhdl* root) {
    143 
    144     static unsigned int counter = 0;
    145     char* name = (char*) omAlloc0(512);
    146     sprintf(name, " :%u:%p:_shared_: ", ++counter, head->data);
    147     if ((*root) == NULL )
    148       enterid(name, 0, head->rtyp, root, TRUE, FALSE);
     131
     132
     133template <class PtrType>
     134class CountedRefWeakPtr;
     135
     136template <class PtrType>
     137class CountedRefIndirectPtr:
     138  public RefCounter {
     139public:
     140  friend class CountedRefWeakPtr<PtrType>;
     141private:
     142  CountedRefIndirectPtr(PtrType ptr): m_ptr(ptr) { }
     143  CountedRefIndirectPtr& operator=(PtrType ptr) { m_ptr = ptr; return *this; }
     144  PtrType m_ptr;
     145};
     146
     147template <class PtrType>
     148inline void CountedRefPtr_kill(CountedRefIndirectPtr<PtrType>* pval) { delete pval; }
     149
     150template <class PtrType>
     151class CountedRefWeakPtr {
     152  typedef CountedRefWeakPtr self;
     153
     154public:
     155
     156  /// @name Name template arguments
     157  //@{ Name template arguments
     158  typedef PtrType ptr_type;
     159  typedef CountedRefPtr<CountedRefIndirectPtr<ptr_type>*> ptrptr_type;
     160  //@}
     161
     162  /// Construct unassigned weak reference
     163  CountedRefWeakPtr(): m_indirect(NULL) { }
     164
     165  /// Convert from pointer
     166  CountedRefWeakPtr(ptr_type ptr): m_indirect(new CountedRefIndirectPtr<ptr_type>(ptr)) { }
     167
     168  /// Construct copy
     169  CountedRefWeakPtr(const self& rhs):  m_indirect(rhs.m_indirect) { }
     170
     171  /// Unlink one reference (handled by CountedRefPtr)
     172  ~CountedRefWeakPtr() { }
     173
     174  /// Mark weak reference as invalid
     175  void invalidate() {  *this = NULL; }
     176
     177  /// Test whether reference was never used
     178  bool unassigned() const { return !m_indirect; }
     179
     180  /// Pointer-style interface
     181  //@{
     182  operator bool() const {  return operator->(); }
     183  self& operator=(const self& rhs) {
     184    m_indirect = rhs;
     185    return *this;
     186  }
     187  self& operator=(ptr_type ptr) {
     188    if (!m_indirect)
     189      m_indirect = new CountedRefIndirectPtr<ptr_type>(ptr);
    149190    else
    150       *root = (*root)->set(name, 0, head->rtyp, TRUE);
    151 
    152     IDDATA(*root) = (char*) head->data;
    153     return *root;
    154   }
    155 
    156   static void clearid(idhdl handle, idhdl* root) {
    157     IDDATA(handle)=NULL;
    158     IDTYP(handle)=NONE;
    159     killhdl2(handle, root, NULL);
    160   }
    161   static int& ref_id() {
    162     static int g_ref_id = 0;
    163     return g_ref_id;
    164   }
    165 
    166   static int& sh_id() {
    167     static int g_sh_id = 0;
    168     return g_sh_id;
    169   }
    170 };
    171 #endif
    172 /// Overloading ring destruction
    173 inline void CountedRefPtr_kill(ring r) { rKill(r); }
    174 
     191      m_indirect->m_ptr = ptr;
     192    return *this;
     193  }
     194  bool operator==(ptr_type ptr) const {
     195    return m_indirect &&(m_indirect->m_ptr == ptr);
     196  }
     197  bool operator!=(ptr_type rhs) const { return !operator==(rhs); }
     198  const ptr_type operator->() const { return (m_indirect? m_indirect->m_ptr: NULL); }
     199  ptr_type operator->() {   return (m_indirect? m_indirect->m_ptr:NULL); }
     200  //@}
     201
     202private:
     203  ptrptr_type m_indirect;
     204};
     205
     206
     207
     208
     209/** @class LeftvHelper
     210 * This class implements some recurrent code sniplets to be used with
     211 * @c leftv and @c idhdl.implements a refernce counter which we can use
     212 **/
    175213class LeftvHelper {
    176214public:
Note: See TracChangeset for help on using the changeset viewer.