Changeset 971984c in git
- Timestamp:
- Aug 13, 2012, 5:58:09 PM (11 years ago)
- Branches:
- (u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
- Children:
- 75c6680561e0d1daedacd0b1599765c4061fe56d
- Parents:
- 4d55e482cb4dbcbe1ca511d7c34e968c01cf8222
- git-author:
- Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-13 17:58:09+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
r4d55e4 r971984c 33 33 34 34 35 class CountedRef { 36 typedef CountedRef self; 37 38 public: 39 typedef int id_type; 40 41 /// Set Singular type identitfier 42 CountedRef(blackbox& bbx) { 43 CountedRefAccess_id() = setBlackboxStuff(&bbx, "reference"); 44 } 45 CountedRef() { } 46 47 /// Get Singular type identitfier 48 static id_type id() { return CountedRefAccess_id(); } 49 50 /// Check for being reference in Singular interpreter object 51 static BOOLEAN is_ref(leftv arg) { return (arg->Typ() == id()); } 52 private: 53 /// Access identifier (one per class) 54 static id_type& CountedRefAccess_id() { 55 static id_type g_id = 0; 56 return g_id; 57 } 58 59 }; 35 60 /** @class CountedRefData 36 61 * This class stores a reference counter as well as a Singular interpreter object. … … 38 63 * It also stores the Singular token number, once per type. 39 64 **/ 40 class CountedRefData { 41 typedef CountedRefData self; 42 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 65 class CountedRefData: public CountedRef { 66 typedef CountedRefData self; 90 67 91 68 /// Forbit copy construction and normal assignment … … 94 71 95 72 public: 96 typedef int id_type;97 73 typedef unsigned long count_type; 98 74 99 75 /// Construct reference for Singular object 100 CountedRefData(leftv data): m_data(*data), m_count( 1), m_ring(NULL) {76 CountedRefData(leftv data): m_data(*data), m_count(0), m_ring(NULL) { 101 77 102 78 if (RingDependend(data->Typ()) && (currRing != NULL) ) { … … 113 89 ~CountedRefData() { 114 90 assume(m_count == 0); 115 if (m_data.e) omFree(m_data.e);91 if (m_data.e) omFree(m_data.e); 116 92 if (m_ring) --m_ring->ref; 117 93 } … … 130 106 return (op == NONE? TRUE: FALSE); 131 107 } 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()); } 170 private: 108 109 static BOOLEAN construct(leftv result, leftv arg) { 110 self* pRef(is_ref(arg)? static_cast<self*>(arg->Data()): new self(arg)); 111 pRef->reclaim(); 112 113 return set_to(result, pRef, id()); 114 } 115 171 116 /// @name Reference counter management 172 117 //@{ … … 176 121 //@} 177 122 123 leftv get () { 124 leftv result = (leftv)omAlloc0(sizeof(sleftv)); 125 get(*result); 126 return result; 127 } 128 129 void get(sleftv& result) { 130 if (m_ring && (m_ring != currRing)) { 131 Werror("Can only use references from current ring."); 132 return; 133 } 134 leftv next = result.next; 135 memcpy(&result, &m_data, sizeof(sleftv)); 136 result.next = next; 137 } 138 178 139 private: 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 140 /// Reference counter 187 141 count_type m_count; … … 190 144 sleftv m_data; 191 145 146 /// Store ring for ring-dependent objects 192 147 ring m_ring; 193 148 }; 194 149 150 class CountedRefAccessBase { 151 typedef CountedRefAccessBase self; 152 153 public: 154 CountedRefAccessBase(leftv data): 155 m_data(data) {} 156 157 CountedRefAccessBase(const self& rhs): 158 m_data(rhs.m_data) {} 159 160 ~CountedRefAccessBase() {} 161 162 leftv operator->() { return *this; } 163 operator leftv() { return m_data; } 164 165 protected: 166 leftv m_data; 167 }; 168 169 170 class CountedRefAccess: 171 public CountedRefAccessBase { 172 typedef CountedRefAccess self; 173 typedef CountedRefAccessBase base; 174 175 public: 176 CountedRefAccess(CountedRefData* data): 177 m_owns(true), base(data->get()) { } 178 179 180 CountedRefAccess(leftv data): 181 m_owns(CountedRef::is_ref(data)), base(data) { 182 if (m_owns) m_data = static_cast<CountedRefData*>(data->Data())->get(); 183 } 184 185 CountedRefAccess(const self& rhs): 186 m_owns(rhs.m_owns), base(rhs) { 187 188 if (m_owns){ 189 m_data = (leftv)omAlloc0(sizeof(sleftv)); 190 if(rhs.m_data != NULL) memcpy(m_data, rhs.m_data, sizeof(sleftv)); 191 } 192 } 193 194 ~CountedRefAccess() { if (m_owns) omFree(m_data); } 195 196 private: 197 bool m_owns; 198 }; 199 200 class CountedRefCast: 201 public CountedRefAccessBase { 202 typedef CountedRefCast self; 203 typedef CountedRefAccessBase base; 204 public: 205 CountedRefCast(void* data): 206 base(static_cast<CountedRefData*>(data)->get()) { } 207 208 CountedRefCast(leftv data): 209 base(static_cast<CountedRefData*>(data->Data())->get()) { } 210 211 CountedRefCast(const self& rhs): 212 base((leftv)omAlloc0(sizeof(sleftv))) { 213 memcpy(m_data, rhs.m_data, sizeof(sleftv)); 214 } 215 216 ~CountedRefCast() { omFree(m_data); } 217 }; 195 218 196 219 /// blackbox support - initialization … … 203 226 void countedref_Print(blackbox *b, void* ptr) 204 227 { 205 if (ptr != NULL) 206 CountedRefData::access(static_cast<CountedRefData*>(ptr))->Print(); 228 if (ptr != NULL) CountedRefCast(ptr)->Print(); 207 229 } 208 230 … … 210 232 char* countedref_String(blackbox *b, void* ptr) 211 233 { 212 if (ptr != NULL) 213 return CountedRefData::access(static_cast<CountedRefData*>(ptr))->String(); 234 if (ptr != NULL) return CountedRefCast(ptr)->String(); 214 235 } 215 236 … … 217 238 void* countedref_Copy(blackbox*b, void* ptr) 218 239 { 219 return CountedRefData::copy(static_cast<CountedRefData*>(ptr)); 240 if (ptr) static_cast<CountedRefData*>(ptr)->reclaim(); 241 return ptr; 220 242 } 221 243 222 244 /// blackbox support - assign element 223 BOOLEAN countedref_Assign(leftv l, leftv r) 224 { 225 return CountedRefData::assign(l, r); 245 BOOLEAN countedref_Assign(leftv result, leftv arg) 246 { 247 // Case: replace assignment behind reference 248 if (result->Data() != NULL) 249 return iiAssign(CountedRefCast(result), CountedRefAccess(arg)); 250 251 // Case: new reference 252 if(arg->rtyp == IDHDL) 253 return CountedRefData::construct(result, arg); 254 255 Werror("Can only take reference from identifier"); 256 return CountedRefData::set_to(result, NULL, NONE); 226 257 } 227 258 … … 233 264 return CountedRefData::set_to(res, omStrDup("reference"), STRING_CMD); 234 265 235 typedef CountedRefData::access access; 236 return iiExprArith1(res, access(head), op); 266 CountedRefCast value(head); 267 if (op == DEF_CMD){ 268 res->rtyp = value->Typ(); 269 return iiAssign(res, value); 270 } 271 return iiExprArith1(res, value, op); 237 272 } 238 273 … … 240 275 BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg) 241 276 { 242 typedef CountedRefData::access access; 243 return iiExprArith2(res, access(head), op, access(arg)); 277 return iiExprArith2(res, CountedRefCast(head), op, CountedRefAccess(arg)); 244 278 } 245 279 … … 247 281 BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2) 248 282 { 249 typedef CountedRefData::access access;250 return iiExprArith3(res, op, access(head), access(arg1), access(arg2));283 return iiExprArith3(res, op, CountedRefCast(head), 284 CountedRefAccess(arg1), CountedRefAccess(arg2)); 251 285 } 252 286 … … 255 289 BOOLEAN countedref_OpM(int op, leftv res, leftv args) 256 290 { 257 return iiExprArithM(res, CountedRefData::access(args), op); 291 CountedRefCast value(args); 292 value->next = args->next; 293 for(leftv current = args->next; current != NULL; current = current->next) { 294 if(CountedRef::is_ref(current)) { 295 CountedRefData* pRef = static_cast<CountedRefData*>(current->Data()); 296 pRef->get(*current); 297 pRef->release(); 298 assume(pRef->count() > 0); 299 } 300 } 301 args->next = NULL; 302 303 return iiExprArithM(res, value, op); 258 304 } 259 305 … … 261 307 void countedref_destroy(blackbox *b, void* ptr) 262 308 { 263 CountedRefData::destroy(static_cast<CountedRefData*>(ptr)); 309 CountedRefData* pRef = static_cast<CountedRefData*>(ptr); 310 if(ptr && !pRef->release()) 311 delete pRef; 264 312 } 265 313 … … 278 326 bbx->blackbox_OpM = countedref_OpM; 279 327 bbx->data = omAlloc0(newstruct_desc_size()); 280 CountedRef Data::set_id(setBlackboxStuff(bbx,"reference"));328 CountedRef init(*bbx); 281 329 } 282 330
Note: See TracChangeset
for help on using the changeset viewer.