Changeset 4d55e4 in git


Ignore:
Timestamp:
Aug 13, 2012, 5:48:48 PM (10 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', '96ce329119711a2b80858c8365abd29f8460bbfa')
Children:
971984cfbe4d595f6502922bcb6117ba46acd6d2
Parents:
ee146561a971486feae903f01025f795b11dbaed
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-13 17:48:48+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:15+02:00
Message:
add: treating ring dependent references
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    ree1465 r4d55e4  
    3333
    3434
    35 class sleftv_shallow {
    36   typedef sleftv_shallow self;
    37 public:
    38   sleftv_shallow(sleftv& data): m_data(data) { }
    39   sleftv_shallow(const self& rhs): m_data(rhs.m_data) {}
    40 
    41   ~sleftv_shallow() { }// do not need the clean up, do not own
    42  
    43   leftv operator->() { return *this; }
    44   operator leftv() { return &m_data; }
    45 
    46 private:
    47   sleftv m_data;
    48 };
    49 class ListElementRefData;
    5035/** @class CountedRefData
    5136 * This class stores a reference counter as well as a Singular interpreter object.
     
    5641 typedef CountedRefData self;
    5742
    58   /// Forbit copy construction
     43public:
     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
     90
     91  /// Forbit copy construction and normal assignment
    5992  CountedRefData(const self&);
    6093  self& operator=(const self&);
     
    6598
    6699  /// Construct reference for Singular object
    67   CountedRefData(leftv data): m_data(*data), m_count(1) {
     100  CountedRefData(leftv data): m_data(*data), m_count(1), m_ring(NULL) {
     101
     102    if (RingDependend(data->Typ())  && (currRing != NULL) ) {
     103      m_ring = currRing;
     104      ++m_ring->ref;
     105    }
    68106    if (data->e) {
    69107      m_data.e = (Subexpr)omAlloc0Bin(sSubexpr_bin);
     
    73111
    74112  /// Destructor
    75   ~CountedRefData()  { if(m_data.e) omFree(m_data.e); };
    76 
    77   sleftv_shallow get() {
    78     return sleftv_shallow(m_data);
    79   }
    80 
    81   static BOOLEAN construct(leftv res, leftv arg) {
    82     return extract(res, (is_ref(arg)? (self*)arg->Data(): new self(arg)), id());
    83   }
    84 
    85   static BOOLEAN extract(leftv res, void* data, int op)
     113  ~CountedRefData()  {
     114    assume(m_count == 0);
     115    if(m_data.e) omFree(m_data.e);
     116    if (m_ring) --m_ring->ref;
     117  }
     118
     119
     120  static BOOLEAN set_to(leftv res, void* data, int op)
    86121  {
    87122    if (res->rtyp == IDHDL) {
     
    95130    return (op == NONE? TRUE: FALSE);
    96131  }
    97   /// @name Forward operations
    98   //@{
    99   BOOLEAN operator()(int op, leftv result, leftv arg){
    100       return iiExprArith2(result, get(), op,
    101                         (is_ref(arg)? cast(arg).get(): arg));
    102    
    103   }
    104 
    105   BOOLEAN operator()(int op, leftv result, leftv arg1, leftv arg2) {
    106     return iiExprArith3(result, op, get(),
    107                         (is_ref(arg1)? cast(arg1).get(): arg1),
    108                         (is_ref(arg2)? cast(arg2).get(): arg2));
    109   }
    110   //@}
     132  static BOOLEAN none(leftv result) { return set_to(result, NULL, NONE); }
     133
     134
     135
    111136
    112137  /// Set Singular type identitfier
     
    116141  static id_type id() { return access_id(); }
    117142
    118   /// Extract Singular interpreter object
    119   static self& cast(leftv value, leftv next=NULL) {
    120     assume((value != NULL) && is_ref(value));
    121     return cast((void*)value->Data(), next);
    122   }
    123 
    124   /// Extract reference from Singular interpreter object data
    125   static self& cast(void* data, leftv next=NULL) {
    126     assume(data != NULL);
    127     self* result = static_cast<CountedRefData*>(data);
    128     result->m_data.next=next;   /// @todo resolve refs in tail
    129     return *result;
     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);
    130166  }
    131167
    132168  /// Check for being reference in Singular interpreter object
    133169  static BOOLEAN is_ref(leftv arg) { return (arg->Typ() == id()); }
    134 
     170private:
    135171  /// @name Reference counter management
    136172  //@{
     
    153189  /// Singular object
    154190  sleftv m_data;
     191
     192  ring m_ring;
    155193};
    156194
     
    165203void countedref_Print(blackbox *b, void* ptr)
    166204{
    167   CountedRefData::cast(ptr).get()->Print();
     205  if (ptr != NULL)
     206    CountedRefData::access(static_cast<CountedRefData*>(ptr))->Print();
    168207}
    169208
     
    171210char* countedref_String(blackbox *b, void* ptr)
    172211{
    173   CountedRefData::cast(ptr).get()->String();
     212  if (ptr != NULL)
     213    return CountedRefData::access(static_cast<CountedRefData*>(ptr))->String();
    174214}
    175215
     
    177217void* countedref_Copy(blackbox*b, void* ptr)
    178218{
    179   CountedRefData::cast(ptr).reclaim();
    180   return ptr;
     219  return CountedRefData::copy(static_cast<CountedRefData*>(ptr));
    181220}
    182221
     
    184223BOOLEAN countedref_Assign(leftv l, leftv r)
    185224{
    186   if (l->Data() == NULL)        // Case: new reference
    187   {
    188     if(r->rtyp != IDHDL) {
    189       Werror("Can only take reference from identifier");
    190       return CountedRefData::extract(l, NULL, NONE);
    191     }
    192     return CountedRefData::construct(l, r);
    193   }
    194 
    195   // Case: replace assignment behind reference
    196   return iiAssign(CountedRefData::cast(l).get(), r);
     225  return CountedRefData::assign(l, r);
    197226}
    198227                                                                     
     
    202231{
    203232  if(op == TYPEOF_CMD)
    204     return CountedRefData::extract(res, omStrDup("reference"), STRING_CMD);
    205 
    206   return iiExprArith1(res, CountedRefData::cast(head).get(), op);
     233    return CountedRefData::set_to(res, omStrDup("reference"), STRING_CMD);
     234
     235  typedef CountedRefData::access access;
     236  return iiExprArith1(res, access(head), op);
    207237}
    208238
     
    210240BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
    211241{
    212   return CountedRefData::cast(head)(op, res, arg);
     242  typedef CountedRefData::access access;
     243  return iiExprArith2(res, access(head), op, access(arg));
    213244}
    214245
     
    216247BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2)
    217248{
    218    return CountedRefData::cast(head)(op, res, arg1, arg2);
     249  typedef CountedRefData::access access;
     250  return iiExprArith3(res, op, access(head), access(arg1), access(arg2));
    219251}
    220252
     
    223255BOOLEAN countedref_OpM(int op, leftv res, leftv args)
    224256{
    225   return iiExprArithM(res, CountedRefData::cast(args, args->next).get(), op);
     257  return iiExprArithM(res, CountedRefData::access(args), op);
    226258}
    227259
     
    229261void countedref_destroy(blackbox *b, void* ptr)
    230262{
    231   if (ptr) {
    232     CountedRefData* pRef = static_cast<CountedRefData*>(ptr);
    233     if(!pRef->release())
    234       delete pRef;
    235   }
     263  CountedRefData::destroy(static_cast<CountedRefData*>(ptr));
    236264}
    237265
Note: See TracChangeset for help on using the changeset viewer.