Changeset 4d55e4 in git for Singular/countedref.cc
- Timestamp:
- Aug 13, 2012, 5:48:48 PM (10 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'ad2543eab51733612ba7d118afc77edca719600e')
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/countedref.cc
ree1465 r4d55e4 33 33 34 34 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 own42 43 leftv operator->() { return *this; }44 operator leftv() { return &m_data; }45 46 private:47 sleftv m_data;48 };49 class ListElementRefData;50 35 /** @class CountedRefData 51 36 * This class stores a reference counter as well as a Singular interpreter object. … … 56 41 typedef CountedRefData self; 57 42 58 /// Forbit copy construction 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 90 91 /// Forbit copy construction and normal assignment 59 92 CountedRefData(const self&); 60 93 self& operator=(const self&); … … 65 98 66 99 /// 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 } 68 106 if (data->e) { 69 107 m_data.e = (Subexpr)omAlloc0Bin(sSubexpr_bin); … … 73 111 74 112 /// 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) 86 121 { 87 122 if (res->rtyp == IDHDL) { … … 95 130 return (op == NONE? TRUE: FALSE); 96 131 } 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 111 136 112 137 /// Set Singular type identitfier … … 116 141 static id_type id() { return access_id(); } 117 142 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); 130 166 } 131 167 132 168 /// Check for being reference in Singular interpreter object 133 169 static BOOLEAN is_ref(leftv arg) { return (arg->Typ() == id()); } 134 170 private: 135 171 /// @name Reference counter management 136 172 //@{ … … 153 189 /// Singular object 154 190 sleftv m_data; 191 192 ring m_ring; 155 193 }; 156 194 … … 165 203 void countedref_Print(blackbox *b, void* ptr) 166 204 { 167 CountedRefData::cast(ptr).get()->Print(); 205 if (ptr != NULL) 206 CountedRefData::access(static_cast<CountedRefData*>(ptr))->Print(); 168 207 } 169 208 … … 171 210 char* countedref_String(blackbox *b, void* ptr) 172 211 { 173 CountedRefData::cast(ptr).get()->String(); 212 if (ptr != NULL) 213 return CountedRefData::access(static_cast<CountedRefData*>(ptr))->String(); 174 214 } 175 215 … … 177 217 void* countedref_Copy(blackbox*b, void* ptr) 178 218 { 179 CountedRefData::cast(ptr).reclaim(); 180 return ptr; 219 return CountedRefData::copy(static_cast<CountedRefData*>(ptr)); 181 220 } 182 221 … … 184 223 BOOLEAN countedref_Assign(leftv l, leftv r) 185 224 { 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); 197 226 } 198 227 … … 202 231 { 203 232 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); 207 237 } 208 238 … … 210 240 BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg) 211 241 { 212 return CountedRefData::cast(head)(op, res, arg); 242 typedef CountedRefData::access access; 243 return iiExprArith2(res, access(head), op, access(arg)); 213 244 } 214 245 … … 216 247 BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2) 217 248 { 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)); 219 251 } 220 252 … … 223 255 BOOLEAN countedref_OpM(int op, leftv res, leftv args) 224 256 { 225 return iiExprArithM(res, CountedRefData:: cast(args, args->next).get(), op);257 return iiExprArithM(res, CountedRefData::access(args), op); 226 258 } 227 259 … … 229 261 void countedref_destroy(blackbox *b, void* ptr) 230 262 { 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)); 236 264 } 237 265
Note: See TracChangeset
for help on using the changeset viewer.