Changeset 2fbb4e0 in git for Singular/countedref.cc
- Timestamp:
- Aug 29, 2012, 6:23:42 PM (12 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- f8852177b833def200699ea2f50f0328ff40ce94
- Parents:
- a9bb741e5bd039dd27b862fdf1ca1f5b0f092216
- git-author:
- Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-08-29 18:23:42+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
ra9bb74 r2fbb4e0 32 32 #include "attrib.h" 33 33 34 35 template <class PtrType, bool NeverNull = false, class CountType = short> 34 /** @class CountedRefPtr 35 * This class implements a smart pointer which handles pointer-style access 36 * to a reference-counted structure and destructing the latter after use. 37 * 38 * The template arguments, include the pointer type @c PtrType, and two 39 * integral (bool) properties: use @c isWeak to disallow destruction 40 * and @c NeverNull to assume, that @c PtrType cannot be @c NULL. 41 * Finally, @c CountType allows you to select a typ to represent the internal reference count. 42 * 43 * @note The class of @c PtrType must have an accessible integral attribute @c ref. 44 * For convenience use @c RefCounter as public base. 45 * In addition you must overload @c void CountedRefPtr_kill(PtrType) accordingly. 46 **/ 47 template <class PtrType, bool isWeak = false, bool NeverNull = false, class CountType = short> 36 48 class CountedRefPtr { 37 49 typedef CountedRefPtr self; 38 50 39 51 public: 52 //{ @name Name template arguments 40 53 typedef PtrType ptr_type; 41 54 typedef CountType count_type; 42 43 55 enum { is_weak = isWeak, never_null = NeverNull }; 56 //} 57 58 /// Convert from pointer 44 59 CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); } 45 CountedRefPtr(const self& rhs): m_ptr(rhs.m_ptr) { reclaim(); } 46 ~CountedRefPtr() { kill(); } 47 60 61 /// Convert from compatible smart pointer 62 template <bool Never> 63 CountedRefPtr(const CountedRefPtr<ptr_type, !is_weak, Never, count_type>& rhs): 64 m_ptr(rhs.m_ptr) { reclaim(); } 65 66 /// Construct refernce copy 67 CountedRefPtr(const self& rhs): 68 m_ptr(rhs.m_ptr) { reclaim(); } 69 70 /// Unlink one reference 71 ~CountedRefPtr() { release(); } 72 73 //{ @name Replace data behind reference 74 self& operator=(const self& rhs) { return operator=(rhs.m_ptr); } 48 75 self& operator=(ptr_type ptr) { 49 kill();76 release(); 50 77 m_ptr = ptr; 51 78 reclaim(); 52 79 return *this; 53 80 } 54 self& operator=(const self& rhs) { return operator=(rhs.m_ptr); } 55 81 //} 82 83 /// Checking equality 56 84 bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; } 85 86 //{ @name Pointer-style interface 57 87 bool operator==(ptr_type ptr) const { return m_ptr == ptr; } 58 59 88 operator bool() const { return NeverNull || m_ptr; } 89 operator const ptr_type() const { return m_ptr; } 60 90 operator ptr_type() { return m_ptr; } 91 const ptr_type operator->() const { return *this; } 61 92 ptr_type operator->() { return *this; } 62 93 //} 94 95 //{ @name Reference count interface 63 96 count_type count() const { return (*this? m_ptr->ref: 1); } 64 65 ///private: 66 void kill() { if (!release()) CountedRefPtr_kill(m_ptr); } 67 68 void reclaim() { if(*this) ++m_ptr->ref; } 69 count_type release() { return (*this? --m_ptr->ref: 1); } 97 void reclaim() { if (*this) ++m_ptr->ref; } 98 void release() { 99 if (*this && (--m_ptr->ref <= 0) && !is_weak) 100 CountedRefPtr_kill(m_ptr); 101 } 102 //} 103 70 104 private: 105 /// Store actual pointer 71 106 ptr_type m_ptr; 72 107 }; 73 108 109 110 /** @class RefCounter 111 * This class implements implements a refernce counter which we can use 112 * as a public base of objects managed by @CountedRefPtr. 113 **/ 114 class RefCounter { 115 116 public: 117 /// Name numerical type for enumbering 118 typedef short count_type; 119 120 /// Allow our smart pointer to access internals 121 template <class, bool, bool, class> friend class CountedRefPtr; 122 123 /// Any Constructor resets the counter 124 RefCounter(...): ref(0) {} 125 126 /// Destructor 127 ~RefCounter() { assume(ref == 0); } 128 129 private: 130 /// Number of references 131 count_type ref; // naming consistent with other classes 132 }; 74 133 75 134 class CountedRefEnv { … … 111 170 }; 112 171 113 114 inline void CountedRefPtr_kill(ring r) { }//rKill(r); } 115 116 117 class RefCounter { 118 typedef RefCounter self; 119 120 /// Name numerical type for enumbering 121 typedef unsigned long count_type; 122 123 public: 124 template <class, bool, class> friend class CountedRefPtr; 125 126 /// Default Constructor 127 RefCounter(): ref(0) {} 128 129 /// Copying resets the counter 130 RefCounter(const self&): ref(0) {} 131 132 /// Destructor 133 ~RefCounter() { assume(ref == 0); } 134 135 private: 136 /// Number of references 137 count_type ref; // naming consistent with other classes 138 }; 172 /// Overloading ring destruction 173 inline void CountedRefPtr_kill(ring r) { rKill(r); } 174 139 175 140 176 class LeftvShallow { … … 175 211 176 212 /// Access to object 213 const leftv operator->() const { return m_data; } 177 214 leftv operator->() { return m_data; } 178 215 … … 249 286 250 287 leftv access() { return m_data; } 251 252 288 }; 253 289 … … 279 315 /// Replace data 280 316 self& operator=(const self& rhs) { 281 if (m_data->rtyp==IDHDL) 282 m_data = rhs.m_data; 283 else { 284 LeftvShallow sh(rhs.m_data); 285 m_data->Copy(sh.operator->()); 286 } 317 m_data = rhs.m_data; 287 318 m_ring = rhs.m_ring; 288 289 319 return *this; 290 320 } … … 304 334 305 335 /// Extract (shallow) copy of stored data 306 LeftvShallow operator*() { return (broken()? LeftvShallow(): m_data); }336 LeftvShallow operator*() const { return (broken()? LeftvShallow(): LeftvShallow(m_data)); } 307 337 308 338 … … 316 346 317 347 /// Check whether identifier became invalid 318 BOOLEAN broken() {348 BOOLEAN broken() const { 319 349 if (m_ring) { 320 350 if (m_ring != currRing) … … 350 380 } 351 381 352 CountedRefPtr<ring > Ring() { return m_ring; }382 CountedRefPtr<ring, true> Ring() { return m_ring; } 353 383 354 384 private: 355 385 /// Raise error message and return @c TRUE 356 BOOLEAN complain(const char* text) {386 BOOLEAN complain(const char* text) const { 357 387 Werror(text); 358 388 return TRUE; … … 360 390 361 391 /// Check a given context for our identifier 362 BOOLEAN brokenid(idhdl context) {392 BOOLEAN brokenid(idhdl context) const { 363 393 return (context == NULL) || 364 394 ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context))); … … 374 404 375 405 /// Store namespace for ring-dependent objects 376 //public: 377 CountedRefPtr<ring> m_ring;//todo 406 CountedRefPtr<ring, true> m_ring; 378 407 }; 379 408 … … 438 467 BOOLEAN outcast(leftv result) { 439 468 if (result->rtyp == IDHDL) 440 IDDATA((idhdl)result->data) = (char *) (void*)outcast();469 IDDATA((idhdl)result->data) = (char *)outcast(); 441 470 else 442 471 result->data = (void *)outcast(); … … 449 478 450 479 /// Kills a link to the referenced object 451 void destruct() { m_data. kill(); }480 void destruct() { m_data.release(); } 452 481 453 482 /// Kills the link to the referenced object … … 489 518 BOOLEAN name(leftv res) { return construct(res, operator*()->Name()); } 490 519 491 /// Recover the actual object from Singular interpreter object520 /// Recover the actual object from raw Singular data 492 521 static self cast(void* data) { 493 522 assume(data != NULL); … … 495 524 } 496 525 497 /// Recover the actual object from raw Singular data526 /// Recover the actual object from Singular interpreter object 498 527 static self cast(leftv arg) { 499 528 assume((arg != NULL) && is_ref(arg)); … … 508 537 } 509 538 510 // leftv access() { return m_data->access(); }511 539 protected: 512 513 540 /// Construct integer value 514 541 static BOOLEAN construct(leftv res, long data) { … … 564 591 565 592 // Case: new reference 566 if (arg->rtyp == IDHDL) 567 return CountedRef(arg).outcast(result); 568 569 if (arg->rtyp == CountedRefEnv::idx_id() ) 593 if ((arg->rtyp == IDHDL) || CountedRef::is_ref(arg)) 570 594 return CountedRef(arg).outcast(result); 571 595 … … 636 660 leftv res = (leftv)omAlloc0(sizeof(*res)); 637 661 res->data =(void*) handle; 638 res->rtyp = 662 res->rtyp = IDHDL; 639 663 return res; 640 664 } … … 688 712 CountedRefPtr<CountedRefDataIndexed*> data = 689 713 static_cast<CountedRefDataIndexed*>(ptr); 690 data. kill();714 data.release(); 691 715 } 692 716 }
Note: See TracChangeset
for help on using the changeset viewer.