Changeset 971984c in git


Ignore:
Timestamp:
Aug 13, 2012, 5:58:09 PM (10 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'cbf866d4f8c3861325311c042cb2033c053453b2')
Children:
75c6680561e0d1daedacd0b1599765c4061fe56d
Parents:
4d55e482cb4dbcbe1ca511d7c34e968c01cf8222
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-13 17:58:09+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:15+02:00
Message:
Improved interface

chg: simplified redundant interface
fix: left-hand side of assignment may also be a reference
new: M-ary operations for references; def(reference)
chg: compile-time de-reference where possible
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    r4d55e4 r971984c  
    3333
    3434
     35class CountedRef {
     36  typedef CountedRef self;
     37
     38public:
     39  typedef int id_type;
     40
     41  /// Set Singular type identitfier
     42  CountedRef(blackbox& bbx) { 
     43    CountedRefAccess_id() = setBlackboxStuff(&bbx, "reference");
     44  }
     45  CountedRef() { }
     46
     47  /// Get Singular type identitfier
     48  static id_type id() { return CountedRefAccess_id(); }
     49
     50  /// Check for being reference in Singular interpreter object
     51  static BOOLEAN is_ref(leftv arg) { return (arg->Typ() == id()); }
     52private:
     53  /// Access identifier (one per class)
     54  static id_type& CountedRefAccess_id() {
     55    static id_type g_id = 0;
     56    return g_id;
     57  }
     58
     59};
    3560/** @class CountedRefData
    3661 * This class stores a reference counter as well as a Singular interpreter object.
     
    3863 * It also stores the Singular token number, once per type.
    3964 **/
    40 class CountedRefData {
    41  typedef CountedRefData self;
    42 
    43 public:
    44   class access {
    45     typedef access self;
    46 
    47   public:
    48     access(CountedRefData* data):
    49       m_data(NULL), m_owns(true) { init(&data->m_data, data->m_ring);  }
    50 
    51 
    52     access(leftv data):
    53       m_data(data), m_owns(is_ref(data)) {
    54       if(m_owns)
    55         init((CountedRefData*)(data->Data()));
    56     }
    57 
    58     access(const self& rhs):
    59       m_data(rhs.m_data), m_owns(rhs.m_owns) {
    60 
    61       if (m_owns){
    62         m_data = (leftv)omAlloc0(sizeof(sleftv));
    63         if(rhs.m_data != NULL) memcpy(m_data, rhs.m_data, sizeof(sleftv));
    64       }
    65     }
    66  
    67     ~access() {  if (m_owns)  omFree(m_data);  }
    68  
    69     leftv operator->() { return *this; }
    70     operator leftv() {  return m_data;  }
    71 
    72   private:
    73 
    74     void init(CountedRefData* all) { init(&(all->m_data), all->m_ring); }
    75 
    76     void init(leftv data, ring ringdata) {
    77       m_data = (leftv)omAlloc0(sizeof(sleftv));
    78       if (RingDependend(data->Typ()) && (ringdata != currRing)) {
    79         Werror("Can only use references from current ring.");
    80         return;
    81       }
    82       memcpy(m_data, data, sizeof(sleftv));
    83       data->next = NULL;
    84     }
    85     leftv m_data;
    86     bool m_owns;
    87   };
    88 
    89 
     65class CountedRefData: public CountedRef {
     66  typedef CountedRefData self;
    9067
    9168  /// Forbit copy construction and normal assignment
     
    9471
    9572public:
    96   typedef int id_type;
    9773  typedef unsigned long count_type;
    9874
    9975  /// Construct reference for Singular object
    100   CountedRefData(leftv data): m_data(*data), m_count(1), m_ring(NULL) {
     76  CountedRefData(leftv data): m_data(*data), m_count(0), m_ring(NULL) {
    10177
    10278    if (RingDependend(data->Typ())  && (currRing != NULL) ) {
     
    11389  ~CountedRefData()  {
    11490    assume(m_count == 0);
    115     if(m_data.e) omFree(m_data.e);
     91    if (m_data.e) omFree(m_data.e);
    11692    if (m_ring) --m_ring->ref;
    11793  }
     
    130106    return (op == NONE? TRUE: FALSE);
    131107  }
    132   static BOOLEAN none(leftv result) { return set_to(result, NULL, NONE); }
    133 
    134 
    135 
    136 
    137   /// Set Singular type identitfier
    138   static void set_id(id_type new_id) {  access_id() = new_id;  }
    139 
    140   /// Get Singular type identitfier
    141   static id_type id() { return access_id(); }
    142 
    143   static void* copy(self* ptr) {
    144     if (ptr) ptr->reclaim();
    145     return ptr;
    146   }
    147 
    148 
    149   static void destroy(self* ptr) {
    150     if(ptr && !ptr->release())
    151       delete ptr;
    152   }
    153 
    154   static BOOLEAN assign(leftv result, leftv arg) {
    155     // Case: replace assignment behind reference
    156     if (result->Data() != NULL)
    157       return iiAssign(access(result), arg);
    158 
    159     // Case: new reference
    160     if(arg->rtyp == IDHDL)
    161       return set_to(result, (is_ref(arg)? (self*)copy(static_cast<self*>(arg->Data())):
    162                              new self(arg)), id());
    163      
    164     Werror("Can only take reference from identifier");
    165     return none(result);
    166   }
    167 
    168   /// Check for being reference in Singular interpreter object
    169   static BOOLEAN is_ref(leftv arg) { return (arg->Typ() == id()); }
    170 private:
     108
     109  static BOOLEAN construct(leftv result, leftv arg) {
     110    self* pRef(is_ref(arg)? static_cast<self*>(arg->Data()): new self(arg));
     111    pRef->reclaim();
     112
     113    return set_to(result, pRef, id());
     114  }
     115
    171116  /// @name Reference counter management
    172117  //@{
     
    176121  //@}
    177122
     123  leftv get () {
     124    leftv result = (leftv)omAlloc0(sizeof(sleftv));
     125    get(*result);
     126    return result;
     127  }
     128
     129  void get(sleftv& result) {
     130    if (m_ring && (m_ring != currRing)) {
     131      Werror("Can only use references from current ring.");
     132      return;
     133    }
     134    leftv next = result.next;
     135    memcpy(&result, &m_data, sizeof(sleftv));
     136    result.next = next;
     137  }
     138
    178139private:
    179 
    180   /// Access identifier (one per class)
    181   static id_type& access_id() {
    182     static id_type g_id = 0;
    183     return g_id;
    184   }
    185 
    186140  /// Reference counter
    187141  count_type m_count;
     
    190144  sleftv m_data;
    191145
     146  /// Store ring for ring-dependent objects
    192147  ring m_ring;
    193148};
    194149
     150class CountedRefAccessBase {
     151  typedef CountedRefAccessBase self;
     152
     153 public:
     154  CountedRefAccessBase(leftv data):
     155    m_data(data) {}
     156
     157  CountedRefAccessBase(const self& rhs):
     158    m_data(rhs.m_data) {}
     159
     160  ~CountedRefAccessBase() {}
     161
     162  leftv operator->() { return *this; }
     163  operator leftv() {  return m_data;  }
     164
     165 protected:
     166   leftv m_data;
     167 };
     168
     169
     170 class CountedRefAccess:
     171   public CountedRefAccessBase {
     172    typedef CountedRefAccess self;
     173    typedef CountedRefAccessBase base;
     174
     175  public:
     176    CountedRefAccess(CountedRefData* data):
     177      m_owns(true), base(data->get())  { }
     178
     179
     180    CountedRefAccess(leftv data):
     181      m_owns(CountedRef::is_ref(data)), base(data) {
     182      if (m_owns) m_data = static_cast<CountedRefData*>(data->Data())->get();
     183    }
     184
     185    CountedRefAccess(const self& rhs):
     186      m_owns(rhs.m_owns), base(rhs) {
     187
     188      if (m_owns){
     189        m_data = (leftv)omAlloc0(sizeof(sleftv));
     190        if(rhs.m_data != NULL) memcpy(m_data, rhs.m_data, sizeof(sleftv));
     191      }
     192    }
     193
     194    ~CountedRefAccess() {  if (m_owns) omFree(m_data);  }
     195
     196  private:
     197    bool m_owns;
     198};
     199
     200class CountedRefCast:
     201  public CountedRefAccessBase {
     202    typedef CountedRefCast self;
     203    typedef CountedRefAccessBase base;
     204  public:
     205    CountedRefCast(void* data):
     206      base(static_cast<CountedRefData*>(data)->get()) { }
     207
     208    CountedRefCast(leftv data):
     209      base(static_cast<CountedRefData*>(data->Data())->get()) { }
     210
     211    CountedRefCast(const self& rhs):
     212      base((leftv)omAlloc0(sizeof(sleftv))) {
     213      memcpy(m_data, rhs.m_data, sizeof(sleftv));
     214    }
     215
     216    ~CountedRefCast() {  omFree(m_data);  }
     217};
    195218
    196219/// blackbox support - initialization
     
    203226void countedref_Print(blackbox *b, void* ptr)
    204227{
    205   if (ptr != NULL)
    206     CountedRefData::access(static_cast<CountedRefData*>(ptr))->Print();
     228  if (ptr != NULL) CountedRefCast(ptr)->Print();
    207229}
    208230
     
    210232char* countedref_String(blackbox *b, void* ptr)
    211233{
    212   if (ptr != NULL)
    213     return CountedRefData::access(static_cast<CountedRefData*>(ptr))->String();
     234  if (ptr != NULL) return CountedRefCast(ptr)->String();
    214235}
    215236
     
    217238void* countedref_Copy(blackbox*b, void* ptr)
    218239{
    219   return CountedRefData::copy(static_cast<CountedRefData*>(ptr));
     240  if (ptr) static_cast<CountedRefData*>(ptr)->reclaim();
     241  return ptr;
    220242}
    221243
    222244/// blackbox support - assign element
    223 BOOLEAN countedref_Assign(leftv l, leftv r)
    224 {
    225   return CountedRefData::assign(l, r);
     245BOOLEAN countedref_Assign(leftv result, leftv arg)
     246{
     247  // Case: replace assignment behind reference
     248  if (result->Data() != NULL)
     249    return iiAssign(CountedRefCast(result), CountedRefAccess(arg));
     250 
     251  // Case: new reference
     252  if(arg->rtyp == IDHDL)
     253    return CountedRefData::construct(result, arg);
     254 
     255  Werror("Can only take reference from identifier");
     256  return CountedRefData::set_to(result, NULL, NONE);
    226257}
    227258                                                                     
     
    233264    return CountedRefData::set_to(res, omStrDup("reference"), STRING_CMD);
    234265
    235   typedef CountedRefData::access access;
    236   return iiExprArith1(res, access(head), op);
     266  CountedRefCast value(head);
     267  if (op == DEF_CMD){
     268    res->rtyp = value->Typ();
     269    return iiAssign(res, value);
     270  }
     271  return iiExprArith1(res, value, op);
    237272}
    238273
     
    240275BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
    241276{
    242   typedef CountedRefData::access access;
    243   return iiExprArith2(res, access(head), op, access(arg));
     277  return iiExprArith2(res, CountedRefCast(head), op, CountedRefAccess(arg));
    244278}
    245279
     
    247281BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2)
    248282{
    249   typedef CountedRefData::access access;
    250   return iiExprArith3(res, op, access(head), access(arg1), access(arg2));
     283  return iiExprArith3(res, op, CountedRefCast(head),
     284                      CountedRefAccess(arg1), CountedRefAccess(arg2));
    251285}
    252286
     
    255289BOOLEAN countedref_OpM(int op, leftv res, leftv args)
    256290{
    257   return iiExprArithM(res, CountedRefData::access(args), op);
     291  CountedRefCast value(args);
     292  value->next = args->next;
     293  for(leftv current = args->next; current != NULL; current = current->next) {
     294    if(CountedRef::is_ref(current)) {
     295      CountedRefData* pRef = static_cast<CountedRefData*>(current->Data());
     296      pRef->get(*current);
     297      pRef->release();
     298      assume(pRef->count() > 0);
     299    } 
     300  }
     301  args->next = NULL;
     302
     303  return iiExprArithM(res, value, op);
    258304}
    259305
     
    261307void countedref_destroy(blackbox *b, void* ptr)
    262308{
    263   CountedRefData::destroy(static_cast<CountedRefData*>(ptr));
     309  CountedRefData* pRef = static_cast<CountedRefData*>(ptr);
     310  if(ptr && !pRef->release())
     311    delete pRef;
    264312}
    265313
     
    278326  bbx->blackbox_OpM     = countedref_OpM;
    279327  bbx->data             = omAlloc0(newstruct_desc_size());
    280   CountedRefData::set_id(setBlackboxStuff(bbx,"reference"));
     328  CountedRef init(*bbx);
    281329}
    282330
Note: See TracChangeset for help on using the changeset viewer.