Changeset babfe48 in git for Singular/countedref.cc


Ignore:
Timestamp:
Aug 22, 2012, 1:43:54 PM (12 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'spielwiese', '17f1d200f27c5bd38f5dfc6e8a0879242279d1d8')
Children:
d8f7a6c10289bac4ed97867b659faac3f58a532d
Parents:
180efc06f46eb5c71b54411dc6be57f125ad2ca0
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-22 13:43:54+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:16+02:00
Message:
Handling noninitialized and shared(ll[i])=rhs

add: replace operation for simple access of list elements
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    r180efc0 rbabfe48  
    3333
    3434
     35template <class PtrType, bool NeverNull = false, class CountType = short>
     36class CountedRefPtr {
     37  typedef CountedRefPtr self;
     38
     39public:
     40  typedef PtrType ptr_type;
     41  typedef CountType count_type;
     42
     43  CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); }
     44  CountedRefPtr(const self& rhs): m_ptr(rhs.m_ptr) { reclaim(); }
     45
     46  self& operator=(ptr_type ptr) {
     47    kill();
     48    m_ptr = ptr;
     49    reclaim();
     50    return *this;
     51  }
     52  self& operator=(const self& rhs) { return operator=(rhs.m_ptr); }
     53
     54  bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; }
     55  bool operator==(ptr_type ptr) const { return m_ptr == ptr; }
     56
     57  operator bool() const { return NeverNull || m_ptr; }
     58  operator ptr_type() { return m_ptr; }
     59  ptr_type operator->() { return *this; }
     60
     61  count_type count() const { return m_ptr->ref; }
     62
     63private:
     64  void kill() { if (release()) CountedRefPtr_kill(m_ptr); }
     65 
     66  void reclaim() { if(*this) ++m_ptr->ref; }
     67  count_type release() { return (*this? --m_ptr->ref: 0); }
     68  ptr_type m_ptr;
     69};
     70
     71
    3572class CountedRefEnv {
    3673  typedef CountedRefEnv self;
    3774
    3875public:
    39 
     76  typedef CountedRefPtr<idhdl*> root_type;
    4077  static idhdl* locals() {
    4178    static idhdl myroot = NULL;
     
    5289
    5390    idhdl* root = locals();
     91    short ref = ++(*root)->ref;
     92
    5493    assume((*root)->get(name, 0) == NULL);
    55     short ref = (*root)->ref;
    56     *root = (*root)->set(name, 0, typ, FALSE);
    57     (*root)->ref = ++ref;;
    58 
     94    (*root) = (*root)->set(name, 0, typ, FALSE);
     95    assume((*root) != NULL);
    5996    IDDATA(*root) = (char*) data;
     97    (*root)->ref = ref;
    6098
    6199    return *root;
     
    65103
    66104    idhdl* root = locals();
    67     short ref = (*root)->ref;
     105    short ref = --((*root)->ref);
    68106    killhdl2(handle, root, currRing);
    69     (*root)->ref = --ref;
    70     if(ref > 0) { return;}
    71 
    72     killhdl2(*root, &IDROOT, currRing);
    73     (*root) = NULL;
     107    (*root)->ref = ref;
     108
     109    if(ref <= 0) {
     110      killhdl2(*root, &IDROOT, currRing);
     111      (*root) = NULL;
     112    }
    74113 }
    75114};
     115
     116
     117inline void CountedRefPtr_kill(ring r) { rKill(r); }
    76118
    77119
     
    176218  self& operator=(const self& rhs) { return operator=(rhs.m_data); }
    177219  self& operator=(leftv rhs) {
    178     m_data->CleanUp();
    179     m_data->Copy(rhs);
     220    assume(m_data->rtyp == IDHDL);
     221    kill();
     222    m_data->e = rhs->e;
     223    IDTYP((idhdl)m_data->data) =  rhs->Typ();
     224    IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD();
     225    rhs->e = NULL;
     226   
    180227    return *this;
    181228  }
     
    195242public:
    196243  /// Construct reference for Singular object
    197   explicit CountedRefData(leftv data, idhdl* ctx = &IDROOT):
    198     base(), m_data(data), m_context(ctx) { context(); }
     244  explicit CountedRefData(leftv data, BOOLEAN global = TRUE):
     245    base(), m_data(data), m_ring(parent(data)), m_global(global) { }
    199246
    200247  /// Construct deep copy
    201248  CountedRefData(const self& rhs):
    202     base(), m_data(rhs.m_data), m_context(rhs.m_context) { }
     249    base(), m_data(rhs.m_data), m_ring(rhs.m_ring), m_global(rhs.m_global) { }
    203250 
    204251  /// Destruct
     
    208255  self& operator=(const self& rhs) {
    209256    m_data = rhs.m_data;
    210     m_context = rhs.m_context;
     257    m_global = rhs.m_global;
     258    m_ring = rhs.m_ring;
    211259    return *this;
    212260  }
    213261 
    214262  /// Replace with other Singular data
    215   void set(leftv rhs, idhdl* ctx = &IDROOT) {
     263  void set(leftv rhs, BOOLEAN global = TRUE) {
    216264    m_data = rhs;
    217     m_context = ctx;
    218     context();
     265    m_global = global;
     266    m_ring = parent(rhs);
    219267  }
    220268
     
    232280private:
    233281  /// Check whether identifier became invalid
    234   /// @note Sergio Leone memorial function
     282  /// @note Assume that local identifiers are available
    235283  BOOLEAN broken() {
    236     if( (m_context == CountedRefEnv::locals()) || (m_context == &currRing->idroot))
    237       return FALSE;                  // the good,
    238 
    239     if (m_data->RingDependend())     // the bad,
    240       return complain("Referenced identifier not available in current ring");
    241 
    242     return (brokenid(m_context) &&   // and the ugly (case)
    243             ((m_context == &basePack->idroot) || brokenid())) &&
    244       complain("Referenced identifier not found in current context");
    245   }
    246 
    247   /// Determine corresponding context
    248   /// @note for ring-dependent object we always store @c currRing's root as marker
    249   void context() { if (m_data->RingDependend()) m_context = &currRing->idroot; }
    250 
    251   ///
     284    if (m_ring) {
     285      if (m_ring != currRing)
     286        return complain("Referenced identifier not from current ring");   
     287      return m_global && brokenid(currRing->idroot) &&
     288        complain("Referenced identifier not available in ring anymore"); 
     289    }
     290    return m_global &&
     291      brokenid(currPack->idroot) &&
     292      ((currPack == basePack) || brokenid(basePack->idroot)) &&
     293      complain("Referenced identifier not available in current context");
     294  }
     295
     296  /// Raise error message and return @c TRUE
    252297  BOOLEAN complain(const char* text) {
    253298    Werror(text);
    254299    return TRUE;
    255300  }
    256   BOOLEAN brokenid(idhdl* root = &basePack->idroot) {
    257     idhdl handle = (idhdl) m_data->data;
    258     for(idhdl current = *root; current != NULL; current = IDNEXT(current))
    259       if (current == handle) return FALSE;
    260     return TRUE;
    261   }
    262 
     301
     302  /// Check a given context for our identifier
     303  BOOLEAN brokenid(idhdl context) {
     304    return (context == NULL) ||
     305      ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context)));
     306  }
     307
     308  /// Store ring for ring-dependent objects
     309  static ring parent(leftv rhs) {
     310    return (rhs->RingDependend()? currRing: NULL);
     311  }
    263312
    264313  /// Singular object
     
    266315
    267316  /// Store namespace for ring-dependent objects
    268   idhdl* m_context;
     317  CountedRefPtr<ring> m_ring;
     318
     319  /// Marks whether we have to check
     320  bool m_global;
    269321};
    270322
     
    448500  return FALSE;
    449501}
    450                                                                      
     502
     503BOOLEAN countedref_CheckInit(leftv res, leftv arg)
     504{
     505  if (arg->Data() != NULL) return FALSE;
     506  res->rtyp = NONE;
     507  Werror("Noninitialized access");
     508  return TRUE;
     509}
     510                                                                 
    451511/// blackbox support - unary operations
    452512BOOLEAN countedref_Op1(int op, leftv res, leftv head)
    453513{
    454   if (head->Data() == NULL) return FALSE;
    455514  if(op == TYPEOF_CMD)
    456515    return blackboxDefaultOp1(op, res, head);
    457516
     517  if (countedref_CheckInit(res, head)) return TRUE;
     518
     519  if(op == head->Typ()) {
     520    res->rtyp = op;
     521    return iiAssign(res, head);
     522  }
     523
    458524  return CountedRef::cast(head).dereference(head) ||
    459     iiExprArith1(res, head, (op == DEF_CMD? head->Typ(): op));
     525    iiExprArith1(res, head, op == DEF_CMD? head->Typ(): op);
    460526}
    461527
     
    463529BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
    464530{
    465   if (head->Data() == NULL) return FALSE;
    466   return CountedRef::cast(head).dereference(head) || CountedRef::resolve(arg) ||
     531  return countedref_CheckInit(res, head) ||
     532    CountedRef::cast(head).dereference(head) || CountedRef::resolve(arg) ||
    467533    iiExprArith2(res, head, op, arg);
    468534}
     
    471537BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2)
    472538{
    473   if (head->Data() == NULL) return FALSE;
    474   return  CountedRef::cast(head).dereference(head) ||
     539  return countedref_CheckInit(res, head) ||
     540    CountedRef::cast(head).dereference(head) ||
    475541    CountedRef::resolve(arg1) || CountedRef::resolve(arg2) ||
    476542    iiExprArith3(res, op, head, arg1, arg2);
     
    478544
    479545
    480 /// blackbox support - n-ary operations
    481 BOOLEAN countedref_OpM(int op, leftv res, leftv args)
    482 {
    483   if (args->Data() == NULL) return FALSE;
    484 
    485   if(op == SYSTEM_CMD) {
    486     if (args->next) {
    487       leftv next = args->next;
    488       args->next = NULL;
    489       CountedRef obj = CountedRef::cast(args);
    490       char* name = (next->Typ() == STRING_CMD?
    491                     (char*) next->Data(): (char*)next->Name());
    492       if (strcmp(name, "count") == 0) return obj.count(res);
    493       if (strcmp(name, "hash") == 0) return obj.hash(res);
    494       if (strcmp(name, "same") == 0)
    495         return (next->next == NULL) ||  obj.same(res, next->next);
    496       if ((strcmp(name, "like") == 0) || (strcmp(name, "likewise") == 0))
    497         return (next->next == NULL) ||  obj.likewise(res, next->next);
    498       if (strcmp(name, "name") == 0) return obj.name(res);
    499       if ((strcmp(name, "type") == 0) || (strcmp(name, "typeof") == 0))
    500         return obj.type(res);
    501       return TRUE;
    502     }
    503     return TRUE;
    504   }
    505   return CountedRef::cast(args).dereference(args) || iiExprArithM(res, args, op);
    506 }
    507546
    508547/// blackbox support - destruction
     
    519558public:
    520559  /// Construct new reference from Singular data 
    521   CountedRefShared(leftv arg):  base(new data_type(wrap(arg), CountedRefEnv::locals())) { }
     560  CountedRefShared(leftv arg):  base(new data_type(wrap(arg), FALSE)) { }
    522561
    523562private:
     
    539578  /// Replace data that reference is pointing to
    540579  self& operator=(leftv rhs) {
    541     m_data->set(wrap(rhs), CountedRefEnv::locals());
     580    m_data->set(rhs, FALSE);
    542581    return *this;
    543582  }
     
    571610
    572611
     612/// blackbox support - n-ary operations
     613BOOLEAN countedref_OpM(int op, leftv res, leftv args)
     614{
     615  if (args->Data() == NULL) return FALSE;
     616
     617  if(op == SYSTEM_CMD) {
     618    if (args->next) {
     619      leftv next = args->next;
     620      args->next = NULL;
     621      CountedRef obj = CountedRef::cast(args);
     622      char* name = (next->Typ() == STRING_CMD?
     623                    (char*) next->Data(): (char*)next->Name());
     624      next = next->next;
     625      if (next) {
     626        if (strcmp(name, "same") == 0) return obj.same(res, next);
     627        if (strncmp(name, "like", 4) == 0) return obj.likewise(res, next);
     628      }
     629      if (strncmp(name, "count", 5) == 0) return obj.count(res);
     630      if (strcmp(name, "hash") == 0) return obj.hash(res);
     631      if (strcmp(name, "name") == 0) return obj.name(res);
     632      if (strncmp(name, "type", 4) == 0) return obj.type(res);
     633    }
     634    return TRUE;
     635  }
     636  return CountedRef::cast(args).dereference(args) || iiExprArithM(res, args, op);
     637}
    573638/// blackbox support - assign element
    574639BOOLEAN countedref_AssignShared(leftv result, leftv arg)
     
    581646  }
    582647 
    583   /// Case: new shared data
     648  /// Case: new reference to already shared data
    584649  if (result->Typ() == arg->Typ())
    585650    return CountedRefShared::cast(arg).outcast(result);
    586651
     652  /// Case: new shared data
    587653  return CountedRefShared(arg).outcast(result);
    588654}
Note: See TracChangeset for help on using the changeset viewer.