Changeset 2fbb4e0 in git for Singular/countedref.cc


Ignore:
Timestamp:
Aug 29, 2012, 6:23:42 PM (12 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
f8852177b833def200699ea2f50f0328ff40ce94
Parents:
a9bb741e5bd039dd27b862fdf1ca1f5b0f092216
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-29 18:23:42+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:16+02:00
Message:
fix: const qualifiers and simplified ref counting
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    ra9bb74 r2fbb4e0  
    3232#include "attrib.h"
    3333
    34 
    35 template <class PtrType, bool NeverNull = false, class CountType = short>
     34/** @class CountedRefPtr
     35 * This class implements a smart pointer which handles pointer-style access
     36 * to a reference-counted structure and destructing the latter after use.
     37 *
     38 * The template arguments, include the pointer type @c PtrType, and two
     39 * integral (bool) properties: use @c isWeak to disallow destruction
     40 * and @c NeverNull to assume, that @c PtrType cannot be @c NULL.
     41 * Finally, @c CountType allows you to select a typ to represent the internal reference count.
     42 *
     43 * @note The class of @c PtrType must have an accessible integral attribute @c ref.
     44 * For convenience use @c RefCounter as public base.
     45 * In addition you must overload @c void CountedRefPtr_kill(PtrType) accordingly.
     46 **/
     47template <class PtrType, bool isWeak = false, bool NeverNull = false, class CountType = short>
    3648class CountedRefPtr {
    3749  typedef CountedRefPtr self;
    3850
    3951public:
     52  //{ @name Name template arguments
    4053  typedef PtrType ptr_type;
    4154  typedef CountType count_type;
    42 
    43 
     55  enum { is_weak = isWeak, never_null = NeverNull };
     56  //}
     57
     58  /// Convert from pointer
    4459  CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); }
    45   CountedRefPtr(const self& rhs): m_ptr(rhs.m_ptr) { reclaim(); }
    46   ~CountedRefPtr() { kill(); }
    47 
     60
     61  /// Convert from compatible smart pointer
     62  template <bool Never>
     63  CountedRefPtr(const CountedRefPtr<ptr_type, !is_weak, Never, count_type>& rhs):
     64    m_ptr(rhs.m_ptr) { reclaim(); }
     65
     66  /// Construct refernce copy
     67  CountedRefPtr(const self& rhs):
     68    m_ptr(rhs.m_ptr) { reclaim(); }
     69
     70  /// Unlink one reference
     71  ~CountedRefPtr() { release(); }
     72
     73  //{ @name Replace data behind reference
     74  self& operator=(const self& rhs) { return operator=(rhs.m_ptr); }
    4875  self& operator=(ptr_type ptr) {
    49     kill();
     76    release();
    5077    m_ptr = ptr;
    5178    reclaim();
    5279    return *this;
    5380  }
    54   self& operator=(const self& rhs) { return operator=(rhs.m_ptr); }
    55 
     81  //}
     82
     83  /// Checking equality
    5684  bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; }
     85
     86  //{ @name Pointer-style interface
    5787  bool operator==(ptr_type ptr) const { return m_ptr == ptr; }
    58 
    5988  operator bool() const { return NeverNull || m_ptr; }
     89  operator const ptr_type() const { return m_ptr; }
    6090  operator ptr_type() { return m_ptr; }
     91  const ptr_type operator->() const { return *this; }
    6192  ptr_type operator->() { return *this; }
    62 
     93  //}
     94
     95  //{ @name Reference count interface
    6396  count_type count() const { return (*this? m_ptr->ref: 1); }
    64 
    65 ///private:
    66   void kill() { if (!release()) CountedRefPtr_kill(m_ptr); }
    67  
    68   void reclaim() { if(*this) ++m_ptr->ref; }
    69   count_type release() { return (*this? --m_ptr->ref: 1); }
     97  void reclaim() { if (*this) ++m_ptr->ref; }
     98  void release() {
     99    if (*this && (--m_ptr->ref <= 0) && !is_weak)
     100      CountedRefPtr_kill(m_ptr);
     101  }
     102  //}
     103
    70104private:
     105  /// Store actual pointer
    71106  ptr_type m_ptr;
    72107};
    73108
     109
     110/** @class RefCounter
     111 * This class implements implements a refernce counter which we can use
     112 * as a public base of objects managed by @CountedRefPtr.
     113 **/
     114class RefCounter {
     115
     116public:
     117  /// Name numerical type for enumbering
     118  typedef short count_type;
     119
     120  /// Allow our smart pointer to access internals
     121  template <class, bool, bool, class> friend class CountedRefPtr;
     122
     123  /// Any Constructor resets the counter
     124  RefCounter(...): ref(0) {}
     125
     126  /// Destructor
     127  ~RefCounter() { assume(ref == 0); }
     128
     129private:
     130  /// Number of references
     131  count_type ref;  // naming consistent with other classes
     132};
    74133
    75134class CountedRefEnv {
     
    111170};
    112171
    113 
    114 inline void CountedRefPtr_kill(ring r) { }//rKill(r); }
    115 
    116 
    117 class RefCounter {
    118   typedef RefCounter self;
    119 
    120   /// Name numerical type for enumbering
    121   typedef unsigned long count_type;
    122 
    123 public:
    124   template <class, bool, class> friend class CountedRefPtr;
    125 
    126   /// Default Constructor
    127   RefCounter(): ref(0) {}
    128 
    129   /// Copying resets the counter
    130   RefCounter(const self&): ref(0) {}
    131 
    132   /// Destructor
    133   ~RefCounter() { assume(ref == 0); }
    134 
    135 private:
    136   /// Number of references
    137   count_type ref;  // naming consistent with other classes
    138 };
     172/// Overloading ring destruction
     173inline void CountedRefPtr_kill(ring r) { rKill(r); }
     174
    139175
    140176class LeftvShallow {
     
    175211
    176212  /// Access to object
     213  const leftv operator->() const { return m_data;  }
    177214  leftv operator->() { return m_data;  }
    178215
     
    249286
    250287   leftv access() { return m_data; }
    251 
    252288};
    253289
     
    279315  /// Replace data
    280316  self& operator=(const self& rhs) {
    281    if (m_data->rtyp==IDHDL)
    282       m_data = rhs.m_data;
    283    else {
    284       LeftvShallow sh(rhs.m_data);
    285       m_data->Copy(sh.operator->());
    286     }
     317    m_data = rhs.m_data;
    287318    m_ring = rhs.m_ring;
    288 
    289319    return *this;
    290320  }
     
    304334
    305335  /// Extract (shallow) copy of stored data
    306   LeftvShallow operator*() { return (broken()? LeftvShallow(): m_data); }
     336  LeftvShallow operator*() const { return (broken()? LeftvShallow(): LeftvShallow(m_data)); }
    307337
    308338
     
    316346
    317347  /// Check whether identifier became invalid
    318   BOOLEAN broken() {
     348  BOOLEAN broken() const {
    319349    if (m_ring) {
    320350      if (m_ring != currRing)
     
    350380  }
    351381
    352   CountedRefPtr<ring> Ring() { return m_ring; }
     382  CountedRefPtr<ring, true> Ring() { return m_ring; }
    353383
    354384private:
    355385  /// Raise error message and return @c TRUE
    356   BOOLEAN complain(const char* text) {
     386  BOOLEAN complain(const char* text) const  {
    357387    Werror(text);
    358388    return TRUE;
     
    360390
    361391  /// Check a given context for our identifier
    362   BOOLEAN brokenid(idhdl context) {
     392  BOOLEAN brokenid(idhdl context) const {
    363393    return (context == NULL) ||
    364394      ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context)));
     
    374404
    375405  /// Store namespace for ring-dependent objects
    376   //public:
    377   CountedRefPtr<ring> m_ring;//todo
     406  CountedRefPtr<ring, true> m_ring;
    378407};
    379408
     
    438467  BOOLEAN outcast(leftv result) {
    439468    if (result->rtyp == IDHDL)
    440       IDDATA((idhdl)result->data) = (char *)(void*)outcast();
     469      IDDATA((idhdl)result->data) = (char *)outcast();
    441470    else
    442471      result->data = (void *)outcast();
     
    449478
    450479  /// Kills a link to the referenced object
    451   void destruct() { m_data.kill(); }
     480  void destruct() { m_data.release(); }
    452481
    453482  /// Kills the link to the referenced object
     
    489518  BOOLEAN name(leftv res) { return construct(res, operator*()->Name()); }
    490519
    491   /// Recover the actual object from Singular interpreter object
     520  /// Recover the actual object from raw Singular data
    492521  static self cast(void* data) {
    493522    assume(data != NULL);
     
    495524  }
    496525
    497   /// Recover the actual object from raw Singular data
     526  /// Recover the actual object from Singular interpreter object
    498527  static self cast(leftv arg) {
    499528    assume((arg != NULL) && is_ref(arg));
     
    508537  }
    509538
    510   //  leftv access() { return m_data->access(); }
    511539protected:
    512 
    513540  /// Construct integer value
    514541  static BOOLEAN construct(leftv res, long data) {
     
    564591
    565592  // Case: new reference
    566   if (arg->rtyp == IDHDL)
    567     return CountedRef(arg).outcast(result);
    568 
    569   if (arg->rtyp == CountedRefEnv::idx_id()  )
     593  if ((arg->rtyp == IDHDL) || CountedRef::is_ref(arg))
    570594    return CountedRef(arg).outcast(result);
    571595
     
    636660    leftv res = (leftv)omAlloc0(sizeof(*res));
    637661    res->data =(void*) handle;
    638     res->rtyp =  IDHDL;
     662    res->rtyp = IDHDL;
    639663    return res;
    640664  }
     
    688712    CountedRefPtr<CountedRefDataIndexed*> data =
    689713    static_cast<CountedRefDataIndexed*>(ptr);
    690     data.kill();
     714    data.release();
    691715  }
    692716}
Note: See TracChangeset for help on using the changeset viewer.