source: git/Singular/countedref.cc @ 4d55e4

jengelh-datetimespielwiese
Last change on this file since 4d55e4 was 4d55e4, checked in by Alexander Dreyer <alexander.dreyer@…>, 10 years ago
add: treating ring dependent references
  • Property mode set to 100644
File size: 7.0 KB
Line 
1// -*- c++ -*-
2//*****************************************************************************
3/** @file countedref.cc
4 *
5 * @author Alexander Dreyer
6 * @date 2010-12-15
7 *
8 * This file defines the @c blackbox operations for the countedref type.
9 *
10 * @par Copyright:
11 *   (c) 2010 by The Singular Team, see LICENSE file
12**/
13//*****************************************************************************
14
15
16
17
18
19#include <Singular/mod2.h>
20
21#include <Singular/ipid.h>
22#include <Singular/blackbox.h>
23#include <Singular/newstruct.h>
24
25#include <omalloc/omalloc.h>
26#include <kernel/febase.h>
27#include <kernel/longrat.h>
28#include <Singular/subexpr.h>
29#include <Singular/ipshell.h>
30
31#include "lists.h"
32#include "attrib.h"
33
34
35/** @class CountedRefData
36 * This class stores a reference counter as well as a Singular interpreter object.
37 *
38 * It also stores the Singular token number, once per type.
39 **/
40class CountedRefData {
41 typedef CountedRefData self;
42
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
92  CountedRefData(const self&);
93  self& operator=(const self&);
94
95public:
96  typedef int id_type;
97  typedef unsigned long count_type;
98
99  /// Construct reference for Singular object
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    }
106    if (data->e) {
107      m_data.e = (Subexpr)omAlloc0Bin(sSubexpr_bin);
108      memcpy(m_data.e, data->e, sizeof(*m_data.e));
109    }
110  }
111
112  /// Destructor
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)
121  {
122    if (res->rtyp == IDHDL) {
123      IDDATA((idhdl)res->data) = (char *)data;
124      IDTYP((idhdl)res->data)  = op;
125    }
126    else {
127      res->data = (void *)data;
128      res->rtyp = op;
129    }
130    return (op == NONE? TRUE: FALSE);
131  }
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()); }
170private:
171  /// @name Reference counter management
172  //@{
173  count_type reclaim() { return ++m_count; }
174  count_type release() { return --m_count; }
175  count_type count() const { return m_count; }
176  //@}
177
178private:
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
186  /// Reference counter
187  count_type m_count;
188
189  /// Singular object
190  sleftv m_data;
191
192  ring m_ring;
193};
194
195
196/// blackbox support - initialization
197void* countedref_Init(blackbox*)
198{
199  return NULL;
200}
201
202/// blackbox support - convert to string representation
203void countedref_Print(blackbox *b, void* ptr)
204{
205  if (ptr != NULL)
206    CountedRefData::access(static_cast<CountedRefData*>(ptr))->Print();
207}
208
209/// blackbox support - convert to string representation
210char* countedref_String(blackbox *b, void* ptr)
211{
212  if (ptr != NULL) 
213    return CountedRefData::access(static_cast<CountedRefData*>(ptr))->String();
214}
215
216/// blackbox support - copy element
217void* countedref_Copy(blackbox*b, void* ptr)
218{ 
219  return CountedRefData::copy(static_cast<CountedRefData*>(ptr));
220}
221
222/// blackbox support - assign element
223BOOLEAN countedref_Assign(leftv l, leftv r)
224{
225  return CountedRefData::assign(l, r);
226}
227                                                                     
228
229/// blackbox support - unary operations
230BOOLEAN countedref_Op1(int op, leftv res, leftv head)
231{
232  if(op == TYPEOF_CMD)
233    return CountedRefData::set_to(res, omStrDup("reference"), STRING_CMD);
234
235  typedef CountedRefData::access access;
236  return iiExprArith1(res, access(head), op);
237}
238
239/// blackbox support - binary operations
240BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
241{
242  typedef CountedRefData::access access;
243  return iiExprArith2(res, access(head), op, access(arg));
244}
245
246/// blackbox support - ternary operations
247BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2)
248{
249  typedef CountedRefData::access access;
250  return iiExprArith3(res, op, access(head), access(arg1), access(arg2));
251}
252
253
254/// blackbox support - n-ary operations
255BOOLEAN countedref_OpM(int op, leftv res, leftv args)
256{
257  return iiExprArithM(res, CountedRefData::access(args), op);
258}
259
260/// blackbox support - destruction
261void countedref_destroy(blackbox *b, void* ptr)
262{
263  CountedRefData::destroy(static_cast<CountedRefData*>(ptr));
264}
265
266void countedref_init() 
267{
268  blackbox *bbx = (blackbox*)omAlloc0(sizeof(blackbox));
269  bbx->blackbox_destroy = countedref_destroy;
270  bbx->blackbox_String  = countedref_String;
271  bbx->blackbox_Print  = countedref_Print;
272  bbx->blackbox_Init    = countedref_Init;
273  bbx->blackbox_Copy    = countedref_Copy;
274  bbx->blackbox_Assign  = countedref_Assign;
275  bbx->blackbox_Op1     = countedref_Op1;
276  bbx->blackbox_Op2     = countedref_Op2;
277  bbx->blackbox_Op3     = countedref_Op3;
278  bbx->blackbox_OpM     = countedref_OpM;
279  bbx->data             = omAlloc0(newstruct_desc_size());
280  CountedRefData::set_id(setBlackboxStuff(bbx,"reference"));
281}
282
283extern "C" { void mod_init() { countedref_init(); } }
284
Note: See TracBrowser for help on using the repository browser.