Changeset a9bb74 in git


Ignore:
Timestamp:
Aug 23, 2012, 10:09:11 PM (10 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', '2234726c50d679d6664181a5c72f75a6fd64a787')
Children:
2fbb4e014a0f3dda591b3df6f317ef27d9856de7
Parents:
d8f7a6c10289bac4ed97867b659faac3f58a532d
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-23 22:09:11+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:16+02:00
Message:
fix: got contexts, backreferences of indices, etc. right
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    rd8f7a6 ra9bb74  
    1 // -*- c++ -*-
     1/// -*- c++ -*-
    22//*****************************************************************************
    33/** @file countedref.cc
     
    4141  typedef CountType count_type;
    4242
     43
    4344  CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); }
    4445  CountedRefPtr(const self& rhs): m_ptr(rhs.m_ptr) { reclaim(); }
     46  ~CountedRefPtr() { kill(); }
    4547
    4648  self& operator=(ptr_type ptr) {
     
    5961  ptr_type operator->() { return *this; }
    6062
    61   count_type count() const { return m_ptr->ref; }
    62 
    63 private:
    64   void kill() { if (release()) CountedRefPtr_kill(m_ptr); }
     63  count_type count() const { return (*this? m_ptr->ref: 1); }
     64
     65///private:
     66  void kill() { if (!release()) CountedRefPtr_kill(m_ptr); }
    6567 
    6668  void reclaim() { if(*this) ++m_ptr->ref; }
    67   count_type release() { return (*this? --m_ptr->ref: 0); }
     69  count_type release() { return (*this? --m_ptr->ref: 1); }
     70private:
    6871  ptr_type m_ptr;
    6972};
     
    7477
    7578public:
    76   typedef CountedRefPtr<idhdl*> root_type;
    77   static idhdl* locals() {
    78     static idhdl myroot = NULL;
    79     if (myroot == NULL) {
    80       myroot = enterid(" _shared_data_ ", 0, PACKAGE_CMD, &IDROOT, TRUE);
    81       IDPACKAGE(myroot) = (package)omAlloc0(sizeof(*basePack));
    82       IDPACKAGE(myroot)->idroot = idrec().set(omStrDup("last"), 0, DEF_CMD, FALSE);
    83       IDNEXT(IDPACKAGE(myroot)->idroot) = NULL;
    84     }
    85     return &myroot;
    86   }
    87 
    88   static idhdl newid(int typ, void* data) {
    89     char* name = (char*)omAlloc0(512);
     79  static idhdl idify(leftv head, idhdl* root) {
    9080    static unsigned int counter = 0;
    91     sprintf(name, " :%u:%p:_shared_: ", ++counter, data);
    92 
    93     idhdl* root;
    94 
    95     if (RingDependend(typ))
    96       root = &currRing->idroot;
    97     else {
    98       root = &IDPACKAGE(*locals())->idroot;
    99       ++(IDPACKAGE(*locals())->ref);
    100     }
    101     assume((*root)->get(name, 0) == NULL);
    102     (*root) = (*root)->set(omStrDup(name), 0, typ, FALSE);
    103 
    104     assume((*root) != NULL);
    105     IDDATA(*root) = (char*) data;
    106     ++(IDPACKAGE(*locals())->ref);
    107 
     81    char* name = (char*) omAlloc0(512);
     82    sprintf(name, " :%u:%p:_shared_: ", ++counter, head->data);
     83    if ((*root) == NULL )
     84      enterid(name, 0, head->rtyp, root, TRUE, FALSE);
     85    else
     86      *root = (*root)->set(name, 0, head->rtyp, TRUE);
     87
     88    IDDATA(*root) = (char*) head->data;
    10889    return *root;
    109   }
    110 
    111   static void erase(idhdl handle) {
    112     idhdl* root;
    113     if (RingDependend(IDTYP(handle)))
    114       root = &currRing->idroot;
    115     else {
    116       root = &IDPACKAGE(*locals())->idroot;
    117       (--IDPACKAGE(*locals())->ref);
    118     }
    119     killhdl2(handle, root, currRing);
    120 
    121     if((IDPACKAGE(*locals())->ref) <= 0) {
    122       killhdl2(*root, &IDROOT, currRing);
    123       (*root) = NULL;
    124     }
    125  }
     90  }
     91
     92  static void clearid(idhdl handle, idhdl* root) {
     93    IDDATA(handle)=NULL;
     94    IDTYP(handle)=NONE;
     95    killhdl2(handle, root, NULL);
     96  }
     97  static int& ref_id() {
     98    static int g_ref_id = 0;
     99    return g_ref_id;
     100  }
     101
     102  static int& sh_id() {
     103    static int g_sh_id = 0;
     104    return g_sh_id;
     105  }
     106  static int& idx_id() {
     107    static int g_sh_id = 0;
     108    return g_sh_id;
     109  }
     110
    126111};
    127112
    128113
    129 inline void CountedRefPtr_kill(ring r) { rKill(r); }
     114inline void CountedRefPtr_kill(ring r) { }//rKill(r); }
    130115
    131116
     
    137122
    138123public:
     124  template <class, bool, class> friend class CountedRefPtr;
     125
    139126  /// Default Constructor
    140   RefCounter(): m_count(0) {}
     127  RefCounter(): ref(0) {}
    141128
    142129  /// Copying resets the counter
    143   RefCounter(const self&): m_count(0) {}
     130  RefCounter(const self&): ref(0) {}
    144131
    145132  /// Destructor
    146   ~RefCounter() { assume(m_count == 0); }
    147 
    148   /// @name Reference counter management
    149   //@{
    150   count_type reclaim() { return ++m_count; }
    151   count_type release() { return --m_count; }
    152   count_type count() const { return m_count; }
    153   //@}
     133  ~RefCounter() { assume(ref == 0); }
    154134
    155135private:
    156136  /// Number of references
    157   count_type m_count;
     137  count_type ref;  // naming consistent with other classes
    158138};
    159139
     
    164144  LeftvShallow(): m_data(allocate()) { }
    165145  LeftvShallow(leftv data):
    166     m_data(init(allocate(), data)) { }
     146    m_data(allocate()) { init(data); }
     147
    167148  LeftvShallow(const self& rhs):
    168     m_data(init(allocate(), rhs.m_data)) { }
     149    m_data(allocate()) {
     150    copy(m_data, rhs.m_data);
     151  }
    169152
    170153  ~LeftvShallow() { 
    171     kill();
     154    kill(m_data->e);
    172155    omFree(m_data);
    173156  }
    174157  self& operator=(leftv rhs) {
    175     kill();
    176     init(m_data, rhs);
    177     return *this;
     158    kill(m_data->e);
     159    return init(rhs);
    178160  }
    179161
    180162  self& operator=(const self& rhs) { return (*this) = rhs.m_data; }
     163
     164
    181165
    182166  BOOLEAN get(leftv result) {
     
    184168    result->next = NULL;
    185169    result->CleanUp();
    186     init(result, m_data);
     170
     171    copy(result, m_data);
    187172    result->next = next;
    188173    return FALSE;
     
    194179protected:
    195180  static leftv allocate() { return (leftv)omAlloc0(sizeof(sleftv)); }
    196   static leftv init(leftv result, leftv data) {
     181
     182  self& init(leftv data) {
     183    memcpy(m_data, data, sizeof(sleftv));
     184    data->e = NULL;
     185    m_data->next = NULL;
     186    return *this;
     187  }
     188
     189  static void copy(leftv result, leftv data)  {
    197190    memcpy(result, data, sizeof(sleftv));
    198191    copy(result->e, data->e);
    199     result-> next = NULL;
    200     return result;
    201   }
    202   static void copy(Subexpr& current, Subexpr rhs)  {
     192  }
     193
     194 static void copy(Subexpr& current, Subexpr rhs)  {
    203195    if (rhs == NULL) return;
    204196    current = (Subexpr)memcpy(omAlloc0Bin(sSubexpr_bin), rhs, sizeof(*rhs));
    205197    copy(current->next, rhs->next);
    206198  }
    207   void kill() { kill(m_data->e); }
     199
    208200  static void kill(Subexpr current) {
    209201    if(current == NULL) return;
     
    211203    omFree(current);
    212204  }
     205
    213206protected:
    214207  leftv m_data;
     
    223216public:
    224217  LeftvDeep(): base() {}
    225   LeftvDeep(leftv data): base(data) { }
    226   LeftvDeep(const self& rhs): base(rhs) { }
     218  LeftvDeep(leftv data): base(data) {
     219    if(m_data->rtyp != IDHDL) {
     220      m_data->data = data->CopyD();
     221    }
     222  }
     223
     224  LeftvDeep(leftv data,int,int): base() {  m_data->Copy(data);  }
     225
     226  LeftvDeep(const self& rhs): base(rhs) {
     227    if(m_data->rtyp != IDHDL)
     228      m_data->Copy(rhs.m_data);
     229  }
    227230
    228231  ~LeftvDeep() { m_data->CleanUp(); }
     
    230233  self& operator=(const self& rhs) { return operator=(rhs.m_data); }
    231234  self& operator=(leftv rhs) {
    232     assume(m_data->rtyp == IDHDL);
    233     kill();
    234235    m_data->e = rhs->e;
    235     IDTYP((idhdl)m_data->data) =  rhs->Typ();
    236     IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD();
    237     rhs->e = NULL;
    238    
     236    rhs->e=NULL;
     237    if(m_data->rtyp == IDHDL) {
     238      IDTYP((idhdl)m_data->data) =  rhs->Typ();
     239      IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD();
     240    }
     241    else {
     242      m_data->CleanUp();
     243      m_data->rtyp = rhs->Typ();
     244      m_data->data =  rhs->CopyD();
     245    }
     246
    239247    return *this;
    240248  }
     249
     250   leftv access() { return m_data; }
     251
    241252};
    242 
    243253
    244254/** @class CountedRefData
     
    254264public:
    255265  /// Construct reference for Singular object
    256   explicit CountedRefData(leftv data, BOOLEAN global = TRUE):
    257     base(), m_data(data), m_ring(parent(data)), m_global(global) { }
     266  explicit CountedRefData(leftv data):
     267    base(), m_data(data), m_ring(parent(data)) { }
     268
     269  CountedRefData(leftv data, BOOLEAN global, int):
     270    base(), m_data(data, global,0), m_ring(parent(data)) { }
    258271
    259272  /// Construct deep copy
    260273  CountedRefData(const self& rhs):
    261     base(), m_data(rhs.m_data), m_ring(rhs.m_ring), m_global(rhs.m_global) { }
     274    base(), m_data(rhs.m_data), m_ring(rhs.m_ring)  { }
    262275 
    263276  /// Destruct
     
    266279  /// Replace data
    267280  self& operator=(const self& rhs) {
    268     m_data = rhs.m_data;
    269     m_global = rhs.m_global;
     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    }
    270287    m_ring = rhs.m_ring;
     288
    271289    return *this;
    272290  }
    273  
     291
    274292  /// Replace with other Singular data
    275   void set(leftv rhs, BOOLEAN global = TRUE) {
    276     m_data = rhs;
    277     m_global = global;
     293  void set(leftv rhs) {
     294    if (m_data->rtyp==IDHDL)
     295      m_data = rhs;
     296   else
     297     m_data->Copy(rhs);
     298
    278299    m_ring = parent(rhs);
    279300  }
    280301
    281302  /// Write (shallow) copy to given handle
    282   BOOLEAN get(leftv res) {
    283     reclaim();
    284     BOOLEAN b = broken() || m_data.get(res);
    285     release();
    286     return b;
    287   }
     303  BOOLEAN get(leftv res) { return broken() || m_data.get(res);  }
    288304
    289305  /// Extract (shallow) copy of stored data
    290306  LeftvShallow operator*() { return (broken()? LeftvShallow(): m_data); }
    291307
    292 private:
     308
     309  BOOLEAN rering() {
     310    if (m_ring ^ m_data->RingDependend()) m_ring = (m_ring? NULL: currRing);
     311    return FALSE;
     312  }
     313
     314  /// Get the current context
     315  idhdl* root() { return  (m_ring? &m_ring->idroot: &IDROOT); }
     316
    293317  /// Check whether identifier became invalid
    294   /// @note Assume that local identifiers are available
    295318  BOOLEAN broken() {
    296319    if (m_ring) {
    297320      if (m_ring != currRing)
    298321        return complain("Referenced identifier not from current ring");   
    299       return m_global && brokenid(currRing->idroot) &&
     322
     323      return (m_data->rtyp == IDHDL)  && brokenid(currRing->idroot) &&
    300324        complain("Referenced identifier not available in ring anymore"); 
    301325    }
    302     return m_global &&
    303       brokenid(currPack->idroot) &&
    304       ((currPack == basePack) || brokenid(basePack->idroot)) &&
    305       complain("Referenced identifier not available in current context");
    306   }
    307 
     326
     327   if (m_data->rtyp != IDHDL) return FALSE;
     328   return brokenid(IDROOT) &&
     329     ((currPack == basePack) || brokenid(basePack->idroot)) &&
     330     complain("Referenced identifier not available in current context");
     331  }
     332
     333  BOOLEAN assign(leftv result, leftv arg) {
     334    return get(result) || iiAssign(result, arg) || rering();
     335  }
     336
     337  /// @note Enables write-access via identifier
     338  idhdl idify() {  return CountedRefEnv::idify(m_data.access(), root());  }
     339
     340  /// @note Only call, if @c idify had been called before!
     341  void clearid() {  CountedRefEnv::clearid((idhdl)m_data.access()->data, root());  }
     342
     343  BOOLEAN retrieve(leftv res) {
     344    if (res->data == m_data.access()->data)  {
     345      memcpy(m_data.access(), res, sizeof(sleftv));
     346      res->Init();
     347      return TRUE;
     348    }
     349    return FALSE;
     350  }
     351
     352  CountedRefPtr<ring> Ring() { return m_ring; }
     353
     354private:
    308355  /// Raise error message and return @c TRUE
    309356  BOOLEAN complain(const char* text) {
     
    322369    return (rhs->RingDependend()? currRing: NULL);
    323370  }
    324 
     371protected:
    325372  /// Singular object
    326373  LeftvDeep m_data;
    327374
    328375  /// Store namespace for ring-dependent objects
    329   CountedRefPtr<ring> m_ring;
    330 
    331   /// Marks whether we have to check
    332   bool m_global;
     376  //public:
     377  CountedRefPtr<ring> m_ring;//todo
    333378};
    334379
     
    339384  return NULL;
    340385}
     386
     387
     388inline void CountedRefPtr_kill(CountedRefData* data) { delete data; }
    341389
    342390class CountedRef {
     
    358406
    359407  /// Construct new reference from Singular data 
    360   CountedRef(leftv arg):  m_data(new data_type(arg)) { m_data->reclaim(); }
     408  CountedRef(leftv arg):  m_data(new data_type(arg)) { }
    361409
    362410protected:
    363411  /// Recover previously constructed reference
    364   CountedRef(data_type* arg):  m_data(arg) { assume(arg); m_data->reclaim(); }
     412  CountedRef(data_type* arg):  m_data(arg) { assume(arg); }
    365413
    366414public:
    367415  /// Construct copy
    368   CountedRef(const self& rhs): m_data(rhs.m_data) { m_data->reclaim(); }
     416  CountedRef(const self& rhs): m_data(rhs.m_data) { }
    369417
    370418  /// Replace reference
    371419  self& operator=(const self& rhs) {
    372     destruct();
    373420    m_data = rhs.m_data;
    374     m_data->reclaim();
    375421    return *this;
    376422  }
     
    382428  }
    383429
     430  BOOLEAN assign(leftv result, leftv arg) {
     431    return m_data->assign(result,arg);
     432  }
     433
    384434  /// Extract (shallow) copy of stored data
    385435  LeftvShallow operator*() { return m_data->operator*(); }
     
    387437  /// Construct reference data object from
    388438  BOOLEAN outcast(leftv result) {
    389     m_data->reclaim();
    390439    if (result->rtyp == IDHDL)
    391       IDDATA((idhdl)result->data) = (char *)m_data;
     440      IDDATA((idhdl)result->data) = (char *)(void*)outcast();
    392441    else
    393       result->data = (void *)m_data;
     442      result->data = (void *)outcast();
    394443    return FALSE;
    395444  }
    396445  data_type* outcast() {
    397     m_data->reclaim();
     446    m_data.reclaim();
    398447    return m_data;
    399448  }
     449
    400450  /// Kills a link to the referenced object
    401   void destruct() { if(!m_data->release()) delete m_data; }
     451  void destruct() { m_data.kill(); }
    402452
    403453  /// Kills the link to the referenced object
    404   ~CountedRef() { destruct(); }
     454  ~CountedRef() { }
    405455
    406456  /// Replaces argument by a shallow copy of the references data
    407457  BOOLEAN dereference(leftv arg) {
    408     assume(is_ref(arg));
    409     return m_data->get(arg) || ((arg->next != NULL) && resolve(arg->next));
    410   }
     458    //    assume(is_ref(arg));
     459    m_data.reclaim();
     460    BOOLEAN b= m_data->get(arg) || ((arg->next != NULL) && resolve(arg->next));
     461    m_data.release();
     462    return b;
     463  }
     464
     465  BOOLEAN broken() {return m_data->broken(); }
    411466
    412467  /// Get number of references pointing here, too
    413   BOOLEAN count(leftv res) { return construct(res, m_data->count() - 1); }
    414 
    415   /// Get internal indentifier
    416   BOOLEAN hash(leftv res) { return construct(res, (long)m_data); }
     468  BOOLEAN count(leftv res) { return construct(res, m_data.count() - 1); }
     469
     470  // Get internal indentifier
     471  BOOLEAN hash(leftv res) { return construct(res, (long)(data_type*)m_data); }
    417472
    418473  /// Check for likewise identifiers
     
    453508  }
    454509
     510  //  leftv access() { return m_data->access(); }
    455511protected:
    456512
     
    468524    return FALSE;
    469525  }
     526
    470527  /// Store pointer to actual data
    471   data_type* m_data;
     528  CountedRefPtr<data_type*> m_data;
    472529};
    473530
     
    498555  // Case: replace assignment behind reference
    499556  if (result->Data() != NULL) {
    500     return CountedRef::cast(result).dereference(result) ||
    501       CountedRef::resolve(arg) ||
    502       iiAssign(result, arg);
     557    return CountedRef::resolve(arg) ||
     558      CountedRef::cast(result).assign(result, arg);     
    503559  }
    504560 
     561  // Case: copy reference
     562  if (result->Typ() == arg->Typ())
     563    return CountedRef::cast(arg).outcast(result);
     564
    505565  // Case: new reference
    506   if(arg->rtyp == IDHDL)
    507     return (result->Typ() == arg->Typ()?
    508             CountedRef::cast(arg):
    509             CountedRef(arg)).outcast(result);
     566  if (arg->rtyp == IDHDL)
     567    return CountedRef(arg).outcast(result);
     568
     569  if (arg->rtyp == CountedRefEnv::idx_id()  )
     570    return CountedRef(arg).outcast(result);
    510571
    511572  Werror("Can only take reference from identifier");
    512   return FALSE;
     573  return TRUE;
    513574}
    514575
     
    534595  }
    535596
    536   return CountedRef::cast(head).dereference(head) ||
    537     iiExprArith1(res, head, op == DEF_CMD? head->Typ(): op);
     597  if(op == DEF_CMD) {
     598    res->rtyp = DEF_CMD;
     599    return CountedRef::cast(head).dereference(head) || iiAssign(res, head);
     600  }
     601
     602  return CountedRef::cast(head).dereference(head) || iiExprArith1(res, head, op);
    538603}
    539604
     
    541606BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
    542607{
    543   return countedref_CheckInit(res, head) ||
    544     CountedRef::cast(head).dereference(head) || CountedRef::resolve(arg) ||
     608   return countedref_CheckInit(res, head) ||
     609    CountedRef::cast(head).dereference(head) ||
     610    CountedRef::resolve(arg) ||
    545611    iiExprArith2(res, head, op, arg);
    546612}
     613
     614class CountedRefDataIndexed:
     615  public CountedRefData {
     616  typedef CountedRefData base;
     617  typedef CountedRefDataIndexed self;
     618
     619public:
     620  CountedRefDataIndexed(idhdl handle, CountedRefPtr<base*> back):
     621    base(init(handle)), m_back(back) {
     622    m_ring = back->Ring();
     623  }
     624
     625  CountedRefDataIndexed(const self& rhs): base(rhs), m_back(rhs.m_back) { }
     626
     627  ~CountedRefDataIndexed() { clearid();}
     628
     629  BOOLEAN assign(leftv result, leftv arg) {
     630    return base::assign(result, arg) || m_back->rering();
     631  }
     632
     633private:
     634  static leftv init(idhdl handle) {
     635    assume(handle);
     636    leftv res = (leftv)omAlloc0(sizeof(*res));
     637    res->data =(void*) handle;
     638    res->rtyp =  IDHDL;
     639    return res;
     640  }
     641
     642  CountedRefPtr<CountedRefData*> m_back;
     643};
     644inline void CountedRefPtr_kill(CountedRefDataIndexed* data) { delete data; }
     645
     646
    547647
    548648/// blackbox support - ternary operations
     
    564664
    565665
     666/// blackbox support - assign element
     667BOOLEAN countedref_AssignIndexed(leftv result, leftv arg)
     668{
     669  // Case: replace assignment behind reference
     670  if (result->Data() != NULL) {
     671    CountedRefPtr<CountedRefDataIndexed*> indexed =(CountedRefDataIndexed*)(result->Data());
     672    return CountedRef::resolve(arg) || indexed->assign(result, arg);
     673  }
     674 
     675  // Case: copy reference
     676  if (result->Typ() == arg->Typ())
     677    return CountedRef::cast(arg).outcast(result);
     678
     679  Werror("Cannot generate subscripted shared from plain type. Use shared[i] or shared.attr");
     680  return TRUE;
     681}
     682
     683
     684/// blackbox support - destruction
     685void countedref_destroyIndexed(blackbox *b, void* ptr)
     686{
     687  if (ptr) {
     688    CountedRefPtr<CountedRefDataIndexed*> data =
     689    static_cast<CountedRefDataIndexed*>(ptr);
     690    data.kill();
     691  }
     692}
     693
    566694class CountedRefShared:
    567695  public CountedRef {
    568696  typedef CountedRefShared self;
    569697  typedef CountedRef base;
    570 public:
    571   /// Construct new reference from Singular data 
    572   CountedRefShared(leftv arg):  base(new data_type(wrap(arg), FALSE)) { }
    573 
    574 private:
    575   /// Recover previously constructed shared data
    576   CountedRefShared(data_type* arg):  base(arg) { }
     698
    577699  CountedRefShared(const base& rhs):  base(rhs) { }
    578 public:
     700
     701public:
     702  CountedRefShared(leftv arg):  base(new data_type(arg, FALSE,0)) { }
     703
    579704  /// Construct copy
    580705  CountedRefShared(const self& rhs): base(rhs) { }
    581706
    582   ~CountedRefShared() {  kill(); }
     707  ~CountedRefShared() { }
    583708
    584709  self& operator=(const self& rhs) {
    585     kill();
    586     base::operator=(rhs);
    587     return *this;
     710    return static_cast<self&>(base::operator=(rhs));
    588711  }
    589712
    590713  /// Replace data that reference is pointing to
    591714  self& operator=(leftv rhs) {
    592     m_data->set(rhs, FALSE);
    593     return *this;
    594   }
    595   void destruct() {
    596     kill();
    597     base::destruct();
     715    return static_cast<self&>(base::operator=(rhs));
    598716  }
    599717
    600718  static self cast(leftv arg) { return base::cast(arg); }
    601719  static self cast(void* arg) { return base::cast(arg); }
    602 private:
    603 
    604   static leftv wrap(leftv arg) {
    605     idhdl handle = CountedRefEnv::newid(arg->Typ(), arg->CopyD());
    606     arg->CleanUp();
    607     arg->data = handle;
    608     arg->rtyp = IDHDL;
    609     arg->name = omStrDup(IDID(handle));
    610     return arg;
    611   }
    612 
    613  void kill() {
    614    if (m_data->count() > 1) return;
    615    
    616    LeftvShallow data = base::operator*();
    617    CountedRefEnv::erase((idhdl)data->data);
    618    data->data = NULL;
    619    data->rtyp = NONE;
    620  }
     720
     721  CountedRefPtr<CountedRefDataIndexed*> subscripted() {
     722    return new CountedRefDataIndexed(m_data->idify(), m_data);
     723  }
    621724};
    622725
     726
     727
     728/// blackbox support - binary operations
     729BOOLEAN countedref_Op2Shared(int op, leftv res, leftv head, leftv arg)
     730{
     731  if  ((op == '[') || (op == '.')) {
     732    if (countedref_CheckInit(res, head))  return TRUE;
     733    CountedRefPtr<CountedRefDataIndexed*> indexed = CountedRefShared::cast(head).subscripted();
     734    if(indexed->operator*().get(head)) return TRUE;
     735 
     736    if (CountedRef::resolve(arg) || iiExprArith2(res, head, op, arg)) return
     737      TRUE;
     738
     739    if(indexed->retrieve(res)) {
     740      indexed.reclaim();
     741      res->rtyp = CountedRefEnv::idx_id();
     742      res->data = (void *)indexed;
     743    }
     744    return FALSE;
     745  }
     746
     747  return countedref_Op2(op, res, head, arg);
     748}
    623749
    624750/// blackbox support - n-ary operations
     
    686812  bbx->blackbox_OpM     = countedref_OpM;
    687813  bbx->data             = omAlloc0(newstruct_desc_size());
    688   setBlackboxStuff(bbx, "reference");
     814  CountedRefEnv::ref_id()=setBlackboxStuff(bbx, "reference");
    689815
    690816  /// The @c shared type is "inherited" from @c reference.
     
    693819    (blackbox*)memcpy(omAlloc(sizeof(blackbox)), bbx, sizeof(blackbox));
    694820  bbxshared->blackbox_Assign  = countedref_AssignShared;
    695   bbxshared->blackbox_destroy  = countedref_destroyShared;
    696 
    697   setBlackboxStuff(bbxshared, "shared");
     821  bbxshared->blackbox_destroy = countedref_destroyShared;
     822  bbxshared->blackbox_Op2     = countedref_Op2Shared;
     823  bbxshared->data             = omAlloc0(newstruct_desc_size());
     824  CountedRefEnv::sh_id()=setBlackboxStuff(bbxshared, "shared");
     825
     826  blackbox *bbxindexed =
     827    (blackbox*)memcpy(omAlloc(sizeof(blackbox)), bbx, sizeof(blackbox));
     828  bbxindexed->blackbox_destroy = countedref_destroyIndexed;
     829  bbxindexed->blackbox_Assign = countedref_AssignIndexed;
     830  bbxindexed->data             = omAlloc0(newstruct_desc_size());
     831  CountedRefEnv::idx_id()=setBlackboxStuff(bbxindexed, "shared_subexpr");
     832
    698833}
    699834
Note: See TracChangeset for help on using the changeset viewer.