Changeset babfe48 in git
- Timestamp:
- Aug 22, 2012, 1:43:54 PM (11 years ago)
- Branches:
- (u'spielwiese', 'e7cc1ebecb61be8b9ca6c18016352af89940b21a')
- Children:
- d8f7a6c10289bac4ed97867b659faac3f58a532d
- Parents:
- 180efc06f46eb5c71b54411dc6be57f125ad2ca0
- git-author:
- Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-22 13:43:54+02:00
- git-committer:
- Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:16+02:00
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/countedref.cc
r180efc0 rbabfe48 33 33 34 34 35 template <class PtrType, bool NeverNull = false, class CountType = short> 36 class CountedRefPtr { 37 typedef CountedRefPtr self; 38 39 public: 40 typedef PtrType ptr_type; 41 typedef CountType count_type; 42 43 CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); } 44 CountedRefPtr(const self& rhs): m_ptr(rhs.m_ptr) { reclaim(); } 45 46 self& operator=(ptr_type ptr) { 47 kill(); 48 m_ptr = ptr; 49 reclaim(); 50 return *this; 51 } 52 self& operator=(const self& rhs) { return operator=(rhs.m_ptr); } 53 54 bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; } 55 bool operator==(ptr_type ptr) const { return m_ptr == ptr; } 56 57 operator bool() const { return NeverNull || m_ptr; } 58 operator ptr_type() { return m_ptr; } 59 ptr_type operator->() { return *this; } 60 61 count_type count() const { return m_ptr->ref; } 62 63 private: 64 void kill() { if (release()) CountedRefPtr_kill(m_ptr); } 65 66 void reclaim() { if(*this) ++m_ptr->ref; } 67 count_type release() { return (*this? --m_ptr->ref: 0); } 68 ptr_type m_ptr; 69 }; 70 71 35 72 class CountedRefEnv { 36 73 typedef CountedRefEnv self; 37 74 38 75 public: 39 76 typedef CountedRefPtr<idhdl*> root_type; 40 77 static idhdl* locals() { 41 78 static idhdl myroot = NULL; … … 52 89 53 90 idhdl* root = locals(); 91 short ref = ++(*root)->ref; 92 54 93 assume((*root)->get(name, 0) == NULL); 55 short ref = (*root)->ref; 56 *root = (*root)->set(name, 0, typ, FALSE); 57 (*root)->ref = ++ref;; 58 94 (*root) = (*root)->set(name, 0, typ, FALSE); 95 assume((*root) != NULL); 59 96 IDDATA(*root) = (char*) data; 97 (*root)->ref = ref; 60 98 61 99 return *root; … … 65 103 66 104 idhdl* root = locals(); 67 short ref = (*root)->ref;105 short ref = --((*root)->ref); 68 106 killhdl2(handle, root, currRing); 69 (*root)->ref = --ref; 70 if(ref > 0) { return;} 71 72 killhdl2(*root, &IDROOT, currRing); 73 (*root) = NULL; 107 (*root)->ref = ref; 108 109 if(ref <= 0) { 110 killhdl2(*root, &IDROOT, currRing); 111 (*root) = NULL; 112 } 74 113 } 75 114 }; 115 116 117 inline void CountedRefPtr_kill(ring r) { rKill(r); } 76 118 77 119 … … 176 218 self& operator=(const self& rhs) { return operator=(rhs.m_data); } 177 219 self& operator=(leftv rhs) { 178 m_data->CleanUp(); 179 m_data->Copy(rhs); 220 assume(m_data->rtyp == IDHDL); 221 kill(); 222 m_data->e = rhs->e; 223 IDTYP((idhdl)m_data->data) = rhs->Typ(); 224 IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD(); 225 rhs->e = NULL; 226 180 227 return *this; 181 228 } … … 195 242 public: 196 243 /// Construct reference for Singular object 197 explicit CountedRefData(leftv data, idhdl* ctx = &IDROOT):198 base(), m_data(data), m_ context(ctx) { context();}244 explicit CountedRefData(leftv data, BOOLEAN global = TRUE): 245 base(), m_data(data), m_ring(parent(data)), m_global(global) { } 199 246 200 247 /// Construct deep copy 201 248 CountedRefData(const self& rhs): 202 base(), m_data(rhs.m_data), m_ context(rhs.m_context) { }249 base(), m_data(rhs.m_data), m_ring(rhs.m_ring), m_global(rhs.m_global) { } 203 250 204 251 /// Destruct … … 208 255 self& operator=(const self& rhs) { 209 256 m_data = rhs.m_data; 210 m_context = rhs.m_context; 257 m_global = rhs.m_global; 258 m_ring = rhs.m_ring; 211 259 return *this; 212 260 } 213 261 214 262 /// Replace with other Singular data 215 void set(leftv rhs, idhdl* ctx = &IDROOT) {263 void set(leftv rhs, BOOLEAN global = TRUE) { 216 264 m_data = rhs; 217 m_ context = ctx;218 context();265 m_global = global; 266 m_ring = parent(rhs); 219 267 } 220 268 … … 232 280 private: 233 281 /// Check whether identifier became invalid 234 /// @note Sergio Leone memorial function282 /// @note Assume that local identifiers are available 235 283 BOOLEAN broken() { 236 if( (m_context == CountedRefEnv::locals()) || (m_context == &currRing->idroot)) 237 return FALSE; // the good, 238 239 if (m_data->RingDependend()) // the bad, 240 return complain("Referenced identifier not available in current ring"); 241 242 return (brokenid(m_context) && // and the ugly (case) 243 ((m_context == &basePack->idroot) || brokenid())) && 244 complain("Referenced identifier not found in current context"); 245 } 246 247 /// Determine corresponding context 248 /// @note for ring-dependent object we always store @c currRing's root as marker 249 void context() { if (m_data->RingDependend()) m_context = &currRing->idroot; } 250 251 /// 284 if (m_ring) { 285 if (m_ring != currRing) 286 return complain("Referenced identifier not from current ring"); 287 return m_global && brokenid(currRing->idroot) && 288 complain("Referenced identifier not available in ring anymore"); 289 } 290 return m_global && 291 brokenid(currPack->idroot) && 292 ((currPack == basePack) || brokenid(basePack->idroot)) && 293 complain("Referenced identifier not available in current context"); 294 } 295 296 /// Raise error message and return @c TRUE 252 297 BOOLEAN complain(const char* text) { 253 298 Werror(text); 254 299 return TRUE; 255 300 } 256 BOOLEAN brokenid(idhdl* root = &basePack->idroot) { 257 idhdl handle = (idhdl) m_data->data; 258 for(idhdl current = *root; current != NULL; current = IDNEXT(current)) 259 if (current == handle) return FALSE; 260 return TRUE; 261 } 262 301 302 /// Check a given context for our identifier 303 BOOLEAN brokenid(idhdl context) { 304 return (context == NULL) || 305 ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context))); 306 } 307 308 /// Store ring for ring-dependent objects 309 static ring parent(leftv rhs) { 310 return (rhs->RingDependend()? currRing: NULL); 311 } 263 312 264 313 /// Singular object … … 266 315 267 316 /// Store namespace for ring-dependent objects 268 idhdl* m_context; 317 CountedRefPtr<ring> m_ring; 318 319 /// Marks whether we have to check 320 bool m_global; 269 321 }; 270 322 … … 448 500 return FALSE; 449 501 } 450 502 503 BOOLEAN countedref_CheckInit(leftv res, leftv arg) 504 { 505 if (arg->Data() != NULL) return FALSE; 506 res->rtyp = NONE; 507 Werror("Noninitialized access"); 508 return TRUE; 509 } 510 451 511 /// blackbox support - unary operations 452 512 BOOLEAN countedref_Op1(int op, leftv res, leftv head) 453 513 { 454 if (head->Data() == NULL) return FALSE;455 514 if(op == TYPEOF_CMD) 456 515 return blackboxDefaultOp1(op, res, head); 457 516 517 if (countedref_CheckInit(res, head)) return TRUE; 518 519 if(op == head->Typ()) { 520 res->rtyp = op; 521 return iiAssign(res, head); 522 } 523 458 524 return CountedRef::cast(head).dereference(head) || 459 iiExprArith1(res, head, (op == DEF_CMD? head->Typ(): op));525 iiExprArith1(res, head, op == DEF_CMD? head->Typ(): op); 460 526 } 461 527 … … 463 529 BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg) 464 530 { 465 if (head->Data() == NULL) return FALSE;466 returnCountedRef::cast(head).dereference(head) || CountedRef::resolve(arg) ||531 return countedref_CheckInit(res, head) || 532 CountedRef::cast(head).dereference(head) || CountedRef::resolve(arg) || 467 533 iiExprArith2(res, head, op, arg); 468 534 } … … 471 537 BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2) 472 538 { 473 if (head->Data() == NULL) return FALSE;474 returnCountedRef::cast(head).dereference(head) ||539 return countedref_CheckInit(res, head) || 540 CountedRef::cast(head).dereference(head) || 475 541 CountedRef::resolve(arg1) || CountedRef::resolve(arg2) || 476 542 iiExprArith3(res, op, head, arg1, arg2); … … 478 544 479 545 480 /// blackbox support - n-ary operations481 BOOLEAN countedref_OpM(int op, leftv res, leftv args)482 {483 if (args->Data() == NULL) return FALSE;484 485 if(op == SYSTEM_CMD) {486 if (args->next) {487 leftv next = args->next;488 args->next = NULL;489 CountedRef obj = CountedRef::cast(args);490 char* name = (next->Typ() == STRING_CMD?491 (char*) next->Data(): (char*)next->Name());492 if (strcmp(name, "count") == 0) return obj.count(res);493 if (strcmp(name, "hash") == 0) return obj.hash(res);494 if (strcmp(name, "same") == 0)495 return (next->next == NULL) || obj.same(res, next->next);496 if ((strcmp(name, "like") == 0) || (strcmp(name, "likewise") == 0))497 return (next->next == NULL) || obj.likewise(res, next->next);498 if (strcmp(name, "name") == 0) return obj.name(res);499 if ((strcmp(name, "type") == 0) || (strcmp(name, "typeof") == 0))500 return obj.type(res);501 return TRUE;502 }503 return TRUE;504 }505 return CountedRef::cast(args).dereference(args) || iiExprArithM(res, args, op);506 }507 546 508 547 /// blackbox support - destruction … … 519 558 public: 520 559 /// Construct new reference from Singular data 521 CountedRefShared(leftv arg): base(new data_type(wrap(arg), CountedRefEnv::locals())) { }560 CountedRefShared(leftv arg): base(new data_type(wrap(arg), FALSE)) { } 522 561 523 562 private: … … 539 578 /// Replace data that reference is pointing to 540 579 self& operator=(leftv rhs) { 541 m_data->set( wrap(rhs), CountedRefEnv::locals());580 m_data->set(rhs, FALSE); 542 581 return *this; 543 582 } … … 571 610 572 611 612 /// blackbox support - n-ary operations 613 BOOLEAN countedref_OpM(int op, leftv res, leftv args) 614 { 615 if (args->Data() == NULL) return FALSE; 616 617 if(op == SYSTEM_CMD) { 618 if (args->next) { 619 leftv next = args->next; 620 args->next = NULL; 621 CountedRef obj = CountedRef::cast(args); 622 char* name = (next->Typ() == STRING_CMD? 623 (char*) next->Data(): (char*)next->Name()); 624 next = next->next; 625 if (next) { 626 if (strcmp(name, "same") == 0) return obj.same(res, next); 627 if (strncmp(name, "like", 4) == 0) return obj.likewise(res, next); 628 } 629 if (strncmp(name, "count", 5) == 0) return obj.count(res); 630 if (strcmp(name, "hash") == 0) return obj.hash(res); 631 if (strcmp(name, "name") == 0) return obj.name(res); 632 if (strncmp(name, "type", 4) == 0) return obj.type(res); 633 } 634 return TRUE; 635 } 636 return CountedRef::cast(args).dereference(args) || iiExprArithM(res, args, op); 637 } 573 638 /// blackbox support - assign element 574 639 BOOLEAN countedref_AssignShared(leftv result, leftv arg) … … 581 646 } 582 647 583 /// Case: new shared data648 /// Case: new reference to already shared data 584 649 if (result->Typ() == arg->Typ()) 585 650 return CountedRefShared::cast(arg).outcast(result); 586 651 652 /// Case: new shared data 587 653 return CountedRefShared(arg).outcast(result); 588 654 }
Note: See TracChangeset
for help on using the changeset viewer.