Changeset fc70ac in git
- Timestamp:
- Aug 17, 2012, 3:23:05 PM (12 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- d2a236583625dd880d06a25cf10d02aefee3ba89
- Parents:
- 75c6680561e0d1daedacd0b1599765c4061fe56d
- git-author:
- Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-17 15:23:05+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
r75c668 rfc70ac 39 39 40 40 }; 41 idhdl* getmyroot() { 42 static idhdl myroot = NULL; 43 if (myroot == NULL) { 44 myroot = enterid(" _shared_data_ ", 0, PACKAGE_CMD, &IDROOT, TRUE); 45 } 46 return &myroot; 47 } 41 48 42 49 class RefCounter { … … 51 58 52 59 /// Copying resets the counter 53 RefCounter(const self& rhs): m_count(0) {}60 RefCounter(const self&): m_count(0) {} 54 61 55 62 /// Destructor … … 70 77 class LeftvShallow { 71 78 typedef LeftvShallow self; 72 73 public: 74 LeftvShallow(leftv data): m_data(*data) { copy(&m_data.e, data->e); } 75 LeftvShallow(const self& rhs): m_data(rhs.m_data) { copy(&m_data.e, rhs.m_data.e); } 76 77 ~LeftvShallow() { kill(m_data.e); } 79 80 public: 81 LeftvShallow(): m_data(allocate()) { } 82 LeftvShallow(leftv data): 83 m_data(init(allocate(), data)) { } 84 LeftvShallow(const self& rhs): 85 m_data(init(allocate(), rhs.m_data)) { } 86 87 ~LeftvShallow() { 88 kill(); 89 omFree(m_data); 90 } 91 self& operator=(leftv rhs) { 92 kill(); 93 init(m_data, rhs); 94 return *this; 95 } 96 97 self& operator=(const self& rhs) { return (*this) = rhs.m_data; } 78 98 79 99 BOOLEAN get(leftv result) { … … 81 101 result->next = NULL; 82 102 result->CleanUp(); 83 memcpy(result, &m_data, sizeof(m_data)); 84 copy(&result->e, m_data.e); 103 init(result, m_data); 85 104 result->next = next; 86 105 return FALSE; 87 106 } 88 107 89 /// Read-only access to object 90 const leftv operator->() { return &m_data; } 91 92 private: 93 static void copy(Subexpr* result, Subexpr rhs) { 94 for (Subexpr* current = result; rhs != NULL; 95 current = &(*current)->next, rhs = rhs->next) 96 *current = (Subexpr)memcpy(omAlloc0Bin(sSubexpr_bin), rhs, sizeof(*rhs)); 97 } 98 99 static void kill(Subexpr rhs) { 100 for (Subexpr next; rhs!=NULL; rhs = next, next = rhs->next) { 101 next = rhs->next; 102 omFree(rhs); 103 } 104 } 105 sleftv m_data; 106 }; 108 /// Access to object 109 leftv operator->() { return m_data; } 110 111 protected: 112 static leftv allocate() { return (leftv)omAlloc0(sizeof(sleftv)); } 113 static leftv init(leftv result, leftv data) { 114 memcpy(result, data, sizeof(sleftv)); 115 copy(result->e, data->e); 116 result-> next = NULL; 117 return result; 118 } 119 static void copy(Subexpr& current, Subexpr rhs) { 120 if (rhs == NULL) return; 121 current = (Subexpr)memcpy(omAlloc0Bin(sSubexpr_bin), rhs, sizeof(*rhs)); 122 copy(current->next, rhs->next); 123 } 124 void kill() { kill(m_data->e); } 125 static void kill(Subexpr current) { 126 if(current == NULL) return; 127 kill(current->next); 128 omFree(current); 129 } 130 protected: 131 leftv m_data; 132 }; 133 134 135 class LeftvDeep: 136 public LeftvShallow { 137 typedef LeftvDeep self; 138 typedef LeftvShallow base; 139 140 public: 141 LeftvDeep(): base() {} 142 LeftvDeep(leftv data): base(data) { } 143 LeftvDeep(const self& rhs): base(rhs) { } 144 145 ~LeftvDeep() { m_data->CleanUp(); } 146 147 self& operator=(const self& rhs) { return operator=(rhs.m_data); } 148 self& operator=(leftv rhs) { 149 m_data->CleanUp(); 150 m_data->Copy(rhs); 151 return *this; 152 } 153 }; 154 107 155 108 156 /** @class CountedRefData … … 116 164 typedef RefCounter base; 117 165 118 /// Forbit copy construction and normal assignment119 CountedRefData(const self&);120 self& operator=(const self&);121 122 166 public: 123 167 /// Construct reference for Singular object 124 CountedRefData(leftv data): base(), m_data(data), m_ring(NULL) { 125 if (RingDependend(data->Typ()) && (currRing != NULL) ) { 126 m_ring = currRing; 127 ++m_ring->ref; 128 } 129 130 } 131 132 static idhdl* id_root; 133 134 /// Destructor 168 explicit CountedRefData(leftv data, idhdl* ctx = &IDROOT): 169 base(), m_data(data), m_context(ctx) { context(); } 170 171 /// Construct deep copy 172 CountedRefData(const self& rhs): 173 base(), m_data(rhs.m_data), m_context(rhs.m_context) { } 174 175 /// Destruct 135 176 ~CountedRefData() { } 136 177 137 BOOLEAN get(leftv result) { 138 if (m_ring && (m_ring != currRing)) { 139 Werror("Can only use references from current ring."); 140 return TRUE; 141 } 142 // dereferencing only makes sense, if something else points here, too. 143 assume(count() > 1); 144 return m_data.get(result); 145 } 146 147 LeftvShallow get() { 148 if (m_ring && (m_ring != currRing)) 149 Werror("Can only use references from current ring."); 150 151 return LeftvShallow(m_data); 152 } 178 /// Replace data 179 self& operator=(const self& rhs) { 180 m_data = rhs.m_data; 181 m_context = rhs.m_context; 182 return *this; 183 } 184 185 /// Replace with other Singular data 186 void set(leftv rhs, idhdl* ctx = &IDROOT) { 187 m_data = rhs; 188 m_context = ctx; 189 context(); 190 } 191 192 /// Write (shallow) copy to given handle 193 BOOLEAN get(leftv res) { 194 reclaim(); 195 BOOLEAN b = broken() || m_data.get(res); 196 release(); 197 return b; 198 } 199 200 /// Extract (shallow) copy of stored data 201 LeftvShallow operator*() { return (broken()? LeftvShallow(): m_data); } 153 202 154 203 private: 204 /// Check whether identifier became invalid 205 /// @note Sergio Leone memorial function 206 BOOLEAN broken() { 207 if( (m_context == getmyroot()) || (m_context == &currRing->idroot)) 208 return FALSE; // the good, 209 210 if (m_data->RingDependend()) // the bad, 211 return complain("Referenced identifier not available in current ring"); 212 213 return (brokenid(m_context) && // and the ugly (case) 214 ((m_context == &basePack->idroot) || brokenid())) && 215 complain("Referenced identifier not found in current context"); 216 } 217 218 /// Determine corresponding context 219 /// @note for ring-dependent object we always store @c currRing's root as marker 220 void context() { if (m_data->RingDependend()) m_context = &currRing->idroot; } 221 222 /// 223 BOOLEAN complain(const char* text) { 224 Werror(text); 225 return TRUE; 226 } 227 BOOLEAN brokenid(idhdl* root = &basePack->idroot) { 228 idhdl handle = (idhdl) m_data->data; 229 for(idhdl current = *root; current != NULL; current = IDNEXT(current)) 230 if (current == handle) return FALSE; 231 return TRUE; 232 } 233 155 234 156 235 /// Singular object 157 Leftv Shallowm_data;158 159 /// Store ringfor ring-dependent objects160 ring m_ring;236 LeftvDeep m_data; 237 238 /// Store namespace for ring-dependent objects 239 idhdl* m_context; 161 240 }; 162 241 … … 179 258 180 259 /// Check whether argument is already a reference type 181 static BOOLEAN is_ref(int typ) { 260 static BOOLEAN is_ref(leftv arg) { 261 int typ = arg->Typ(); 182 262 return ((typ > MAX_TOK) && 183 263 (getBlackboxStuff(typ)->blackbox_Init == countedref_Init)); 184 264 } 185 265 186 /// Construct reference data object from 187 static BOOLEAN construct(leftv result, leftv arg) { 188 data_type* data = (result->Typ() == arg->Typ()? 189 static_cast<data_type*>(arg->Data()): new data_type(arg)); 190 data->reclaim(); 266 /// Construct new reference from Singular data 267 CountedRef(leftv arg): m_data(new data_type(arg)) { m_data->reclaim(); } 268 269 protected: 270 /// Recover previously constructed reference 271 CountedRef(data_type* arg): m_data(arg) { assume(arg); m_data->reclaim(); } 272 273 public: 274 /// Construct copy 275 CountedRef(const self& rhs): m_data(rhs.m_data) { m_data->reclaim(); } 276 277 /// Replace reference 278 self& operator=(const self& rhs) { 279 destruct(); 280 m_data = rhs.m_data; 281 m_data->reclaim(); 282 return *this; 283 } 284 285 /// Replace data that reference is pointing to 286 self& operator=(leftv rhs) { 287 m_data->set(rhs); 288 return *this; 289 } 290 291 /// Extract (shallow) copy of stored data 292 LeftvShallow operator*() { return m_data->operator*(); } 293 294 /// Construct reference data object from 295 BOOLEAN outcast(leftv result) { 296 m_data->reclaim(); 191 297 if (result->rtyp == IDHDL) 192 IDDATA((idhdl)result->data) = (char *) data;298 IDDATA((idhdl)result->data) = (char *)m_data; 193 299 else 194 result->data = (void *)data; 195 return (data == NULL? TRUE: FALSE); 196 } 300 result->data = (void *)m_data; 301 return FALSE; 302 } 303 data_type* outcast() { 304 m_data->reclaim(); 305 return m_data; 306 } 307 /// Kills a link to the referenced object 308 void destruct() { if(!m_data->release()) delete m_data; } 197 309 198 310 /// Kills the link to the referenced object 199 static void destruct(data_type* data) { 200 if(data && !data->release()) { 201 delete data; 202 } 203 } 311 ~CountedRef() { destruct(); } 312 313 BOOLEAN dereference(leftv arg) { 314 assume(is_ref(arg)); 315 return m_data->get(arg) || ((arg->next != NULL) && resolve(arg->next)); 316 } 317 204 318 205 319 /// Get the actual object 206 320 /// @note It may change leftv. It is common practice, so we are fine with it. 207 static BOOLEAN dereference(leftv arg) { 208 assume((arg != NULL) && is_ref(arg->Typ())); 209 do { 210 assume(arg->Data() != NULL); 211 data_type* data = static_cast<data_type*>(arg->Data()); 212 if(data->get(arg)) return TRUE; 213 } while (is_ref(arg->Typ())); 214 return resolve_tail(arg); 321 322 static self cast(void* data) { 323 assume(data != NULL); 324 return self(static_cast<data_type*>(data)); 325 } 326 327 static self cast(leftv arg) { 328 assume((arg != NULL) && is_ref(arg)); 329 return self::cast(arg->Data()); 215 330 } 216 331 … … 219 334 static BOOLEAN resolve(leftv arg) { 220 335 assume(arg != NULL); 221 while (is_ref(arg->Typ())) { if(dereference(arg)) return TRUE; }; 222 return resolve_tail(arg); 223 } 224 225 private: 226 /// Dereference (is needed) subsequent objects of sequences 227 static BOOLEAN resolve_tail(leftv arg) { 228 for(leftv next = arg->next; next != NULL; next = next->next) 229 if(resolve(next)) 230 return TRUE; 231 return FALSE; 232 } 336 while (is_ref(arg)) { if(CountedRef::cast(arg).dereference(arg)) return TRUE; }; 337 return (arg->next != NULL) && resolve(arg->next); 338 } 339 340 //private: 341 protected: 342 /// Store pointer to actual data 343 data_type* m_data; 233 344 }; 234 345 … … 236 347 void countedref_Print(blackbox *b, void* ptr) 237 348 { 238 if (ptr != NULL) static_cast<CountedRefData*>(ptr)->get()->Print(); 349 if (ptr == NULL) return; 350 (*CountedRef::cast(ptr))->Print(); 239 351 } 240 352 … … 242 354 char* countedref_String(blackbox *b, void* ptr) 243 355 { 244 if (ptr != NULL) return static_cast<CountedRefData*>(ptr)->get()->String(); 356 if (ptr == NULL) return NULL; 357 return (*CountedRef::cast(ptr))->String(); 245 358 } 246 359 … … 248 361 void* countedref_Copy(blackbox*b, void* ptr) 249 362 { 250 if (ptr) static_cast<CountedRefData*>(ptr)->reclaim();251 return ptr;363 if (ptr) return CountedRef::cast(ptr).outcast(); 364 return NULL; 252 365 } 253 366 … … 256 369 { 257 370 // Case: replace assignment behind reference 258 if (result->Data() != NULL) 259 return CountedRef::dereference(result) || CountedRef::resolve(arg) || 371 if (result->Data() != NULL) { 372 return CountedRef::cast(result).dereference(result) || 373 CountedRef::resolve(arg) || 260 374 iiAssign(result, arg); 375 } 261 376 262 377 // Case: new reference 263 378 if(arg->rtyp == IDHDL) 264 return CountedRef::construct(result, arg); 265 379 return (result->Typ() == arg->Typ()? 380 CountedRef::cast(arg): 381 CountedRef(arg)).outcast(result); 382 266 383 Werror("Can only take reference from identifier"); 267 384 return FALSE; … … 274 391 return blackboxDefaultOp1(op, res, head); 275 392 276 return CountedRef:: dereference(head) ||393 return CountedRef::cast(head).dereference(head) || 277 394 iiExprArith1(res, head, (op == DEF_CMD? head->Typ(): op)); 278 395 } … … 281 398 BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg) 282 399 { 283 return CountedRef::dereference(head) || CountedRef::resolve(arg) || 400 401 return CountedRef::cast(head).dereference(head) || CountedRef::resolve(arg) || 284 402 iiExprArith2(res, head, op, arg); 285 403 } … … 288 406 BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2) 289 407 { 290 return CountedRef::dereference(head) ||408 return CountedRef::cast(head).dereference(head) || 291 409 CountedRef::resolve(arg1) || CountedRef::resolve(arg2) || 292 410 iiExprArith3(res, op, head, arg1, arg2); … … 297 415 BOOLEAN countedref_OpM(int op, leftv res, leftv args) 298 416 { 299 return CountedRef:: dereference(args) || iiExprArithM(res, args, op);417 return CountedRef::cast(args).dereference(args) || iiExprArithM(res, args, op); 300 418 } 301 419 … … 303 421 void countedref_destroy(blackbox *b, void* ptr) 304 422 { 305 CountedRef::destruct(static_cast<CountedRefData*>(ptr)); 306 } 423 if (ptr) CountedRef::cast(ptr).destruct(); 424 } 425 426 427 class CountedRefShared: 428 public CountedRef { 429 typedef CountedRefShared self; 430 typedef CountedRef base; 431 public: 432 /// Construct new reference from Singular data 433 CountedRefShared(leftv arg): base(new data_type(wrap(arg), getmyroot())) { } 434 435 private: 436 /// Recover previously constructed shared data 437 CountedRefShared(data_type* arg): base(arg) { } 438 CountedRefShared(const base& rhs): base(rhs) { } 439 public: 440 /// Construct copy 441 CountedRefShared(const self& rhs): base(rhs) { } 442 443 ~CountedRefShared() { kill(); } 444 445 self& operator=(const self& rhs) { 446 kill(); 447 base::operator=(rhs); 448 return *this; 449 } 450 451 /// Replace data that reference is pointing to 452 self& operator=(leftv rhs) { 453 m_data->set(wrap(rhs), getmyroot()); 454 return *this; 455 } 456 void destruct() { 457 kill(); 458 base::destruct(); 459 } 460 461 static self cast(leftv arg) { return base::cast(arg); } 462 static self cast(void* arg) { return base::cast(arg); } 463 private: 464 465 static leftv wrap(leftv arg) { 466 char* name = (char*)omAlloc0(512); 467 static unsigned int counter = 0; 468 idhdl* myroot=getmyroot(); 469 sprintf(name, " :%u:%p:_shared_: ", ++counter, arg->Data()); 470 assume((*myroot)->get(name, 0) == NULL); 471 idhdl handle = (*myroot)->set(name, 0, arg->Typ(), FALSE); 472 ++(*myroot)->ref; 473 474 IDDATA(handle) = (char*) arg->CopyD(); 475 arg->CleanUp(); 476 arg->data = handle; 477 arg->rtyp = IDHDL; 478 arg->name = name; 479 480 return arg; 481 } 482 483 void kill() { 484 if (m_data->count() > 1) return; 485 486 LeftvShallow data = base::operator*(); 487 idhdl* myroot = getmyroot(); 488 killhdl2((idhdl)(data->data), myroot, currRing); 489 data->data = NULL; 490 data->rtyp = NONE; 491 492 if(--((*myroot)->ref)) { 493 killhdl2(*myroot, &IDROOT, currRing); 494 (*myroot) = NULL; 495 } 496 } 497 }; 307 498 308 499 … … 310 501 BOOLEAN countedref_AssignShared(leftv result, leftv arg) 311 502 { 312 // Case: replace assignment behind reference 313 if (result->Data() != NULL) 314 return CountedRef::dereference(result) || CountedRef::resolve(arg) || 315 iiAssign(result, arg); 503 /// Case: replace assignment behind reference 504 if ((result->Data()) != NULL) { 505 if (CountedRefShared::resolve(arg)) return TRUE; 506 CountedRefShared::cast(result) = arg; 507 return FALSE; 508 } 316 509 317 318 if(CountedRef::resolve(arg)) 319 return TRUE; 320 321 char* name=(char*)omAlloc0(512); 322 static unsigned long counter = 0; 323 do { 324 sprintf(name, "_shareddata_%s_%s_%d\0", result->Name(), arg->Name(), ++counter); 325 } 326 while(ggetid(name)); 327 idhdl handle = enterid(name, 0, arg->Typ(), &IDROOT, FALSE); 328 omFree(name); 329 if (handle==NULL) { 330 Werror("Initializing shared failed"); 331 return TRUE; 332 } 333 334 IDDATA(handle) = (char*)arg->CopyD(); 335 arg->data = handle; 336 arg->rtyp = IDHDL; 337 338 return CountedRef::construct(result, arg); 510 /// Case: new shared data 511 if (result->Typ() == arg->Typ()) 512 return CountedRefShared::cast(arg).outcast(result); 513 514 return CountedRefShared(arg).outcast(result); 339 515 } 340 516 … … 342 518 void countedref_destroyShared(blackbox *b, void* ptr) 343 519 { 344 CountedRefData* data = static_cast<CountedRefData*>(ptr); 345 346 if(data && !data->release()) { 347 leftv tmp = (leftv) omAlloc0(sizeof(*tmp)); 348 data->get(tmp); 349 killid(IDID((idhdl)(tmp->data)), &IDROOT); 350 delete data; 351 } 352 520 if (ptr) CountedRefShared::cast(ptr).destruct(); 353 521 } 354 522 … … 369 537 setBlackboxStuff(bbx, "reference"); 370 538 539 /// The @c shared type is "inherited" from @c reference. 540 /// It just uses another constructor (to make its own copy of the). 371 541 blackbox *bbxshared = 372 542 (blackbox*)memcpy(omAlloc(sizeof(blackbox)), bbx, sizeof(blackbox)); 373 543 bbxshared->blackbox_Assign = countedref_AssignShared; 374 bbxshared->blackbox_destroy = countedref_destroyShared; 544 bbxshared->blackbox_destroy = countedref_destroyShared; 545 375 546 setBlackboxStuff(bbxshared, "shared"); 376 547 }
Note: See TracChangeset
for help on using the changeset viewer.