My Project
Loading...
Searching...
No Matches
countedref.h
Go to the documentation of this file.
1// -*- c++ -*-
2//*****************************************************************************
3/** @file countedref.h
4 *
5 * This file defines reusable classes supporting reference counted interpreter
6 * objects and initiates the @c blackbox operations for high-level types
7 * 'reference' and 'shared'.
8 *
9 * @note This works was supported by the "Industrial Algebra" project.
10 *
11 * @author Alexander Dreyer
12 * @date 2012-08-15
13 *
14 * @par Copyright:
15 * (c) 2012 by The Singular Team, see LICENSE file
16**/
17//*****************************************************************************
18
19
20#ifndef SINGULAR_COUNTEDREF_H_
21#define SINGULAR_COUNTEDREF_H_
22
23#include "omalloc/omalloc.h"
24#include "kernel/structs.h"
25#include "Singular/subexpr.h"
26#include "Singular/idrec.h"
27#include "Singular/ipid.h"
28/** @class CountedRefPtr
29 * This class implements a smart pointer which handles pointer-style access
30 * to a reference-counted structure and destructing the latter after use.
31 *
32 * The template arguments, include the pointer type @c PtrType, and two
33 * integral (bool) properties: use @c Nondestructive to disallow destruction
34 * and @c NeverNull to assume, that @c PtrType cannot be @c NULL.
35 * Finally, @c CountType allows you to select a typ to represent the internal reference count.
36 *
37 * @note The class of @c PtrType must have an accessible integral attribute @c ref.
38 * For convenience use @c RefCounter as public base.
39 * In addition you must overload @c void CountedRefPtr_kill(PtrType) accordingly.
40 **/
41template <class PtrType, bool Nondestructive = false, bool NeverNull = false,
42 class CountType = short>
45
46public:
47 //{ @name Name template arguments
48 typedef PtrType ptr_type;
49 typedef CountType count_type;
50 enum { nondestructive = Nondestructive, never_null = NeverNull };
51 //}
52
53 /// Default constructor @note: exisis only if @c NeverNull is false
55
56 /// Convert from pointer
58
59 /// Convert from compatible smart pointer
60 template <bool Never>
62 m_ptr(rhs.m_ptr) { reclaim(); }
63
64 /// Construct refernce copy
65 CountedRefPtr(const self& rhs):
66 m_ptr(rhs.m_ptr) { reclaim(); }
67
68 /// Unlink one reference
70
71 //{ @name Replace data behind reference
72 self& operator=(const self& rhs) { return operator=(rhs.m_ptr); }
74 release();
75 m_ptr = ptr;
76 reclaim();
77 return *this;
78 }
79 //}
80
81 /// Checking equality
82 bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; }
83
84 //{ @name Pointer-style interface
85 bool operator==(ptr_type ptr) const { return m_ptr == ptr; }
86 operator bool() const { return NeverNull || m_ptr; }
87 operator const ptr_type() const { return m_ptr; }
88 operator ptr_type() { return m_ptr; }
89 const ptr_type operator->() const { return *this; }
90 ptr_type operator->() { return *this; }
91 //}
92
93 /// @name Reference count interface
94 //@{
95 count_type count() const { return (*this? m_ptr->ref: 0); }
96 void reclaim() { if (*this) ++m_ptr->ref; }
97 void release() {
98 if (*this && (--m_ptr->ref <= 0) && !nondestructive)
100 }
101 //@}
102
103private:
104 /// Store actual pointer
106};
107
108/** @class RefCounter
109 * This class implements implements a refernce counter which we can use
110 * as a public base of objects managed by @CountedRefPtr.
111 **/
113
114public:
115 /// Name numerical type for enumbering
116 typedef short count_type;
117
118 /// Allow our smart pointer to access internals
119 template <class, bool, bool, class> friend class CountedRefPtr;
120
121 /// Any Constructor resets the counter
122 RefCounter(...): ref(0) {}
123
124 /// Destructor
125 ~RefCounter() { assume(ref == 0); }
126
127private:
128 /// Number of references
129 count_type ref; // naming consistent with other classes
130};
131
132
133template <class PtrType>
135
136template <class PtrType>
138 public RefCounter {
139public:
140 friend class CountedRefWeakPtr<PtrType>;
142
143private:
144 CountedRefIndirectPtr(PtrType ptr): m_ptr(ptr) { }
145 CountedRefIndirectPtr& operator=(PtrType ptr) { m_ptr = ptr; return *this; }
146
147 PtrType m_ptr;
148};
149
150template <class PtrType>
151inline void CountedRefPtr_kill(CountedRefIndirectPtr<PtrType>* pval) { delete pval; }
152
153template <class PtrType>
156
157public:
158
159 /// @name Name template arguments
160 //@{ Name template arguments
161 typedef PtrType ptr_type;
163 //@}
164
165 /// Construct unassigned weak reference
167
168 /// Convert from pointer
170
171 /// Construct copy
173
174 /// Unlink one reference (handled by CountedRefPtr)
176
177 /// Mark weak reference as invalid
178 void invalidate() { *this = NULL; }
179
180 /// Test whether reference was never used
181 bool unassigned() const { return !m_indirect; }
182 /// Pointer-style interface
183 //@{
184 operator bool() const { return operator->(); }
185 self& operator=(const self& rhs) {
187 return *this;
188 }
190 if (!m_indirect)
192 else
193 m_indirect->m_ptr = ptr;
194 return *this;
195 }
196 bool operator==(ptr_type ptr) const {
197 return m_indirect &&(m_indirect->m_ptr == ptr);
198 }
199 bool operator!=(ptr_type rhs) const { return !operator==(rhs); }
200 const ptr_type operator->() const { return (m_indirect? m_indirect->m_ptr: NULL); }
202 //@}
203private:
205};
206
207
208
209/** @class LeftvHelper
210 * This class implements some recurrent code sniplets to be used with
211 * @c leftv and @c idhdl.implements a refernce counter which we can use
212 **/
214public:
215 static leftv idify(leftv head, idhdl* root) {
216 idhdl handle = newid(head, root);
217 leftv res = (leftv)omAlloc0(sizeof(*res));
218 res->data =(void*) handle;
219 res->rtyp = IDHDL;
220 return res;
221 }
222
223 static idhdl newid(leftv head, idhdl* root) {
224
225 STATIC_VAR unsigned int counter = 0;
226 char* name = (char*) omAlloc0(512);
227 sprintf(name, " :%u:%p:_shared_: ", ++counter, head->data);
228 if ((*root) == NULL )
229 enterid(name, 0, head->rtyp, root, TRUE, FALSE);
230 else
231 *root = (*root)->set(name, 0, head->rtyp, TRUE);
232
233 IDDATA(*root) = (char*) head->data;
234 return *root;
235 }
236
237 static void clearid(idhdl handle, idhdl* root) {
238 IDDATA(handle)=NULL;
239 IDTYP(handle)=NONE;
240 killhdl2(handle, root, NULL);
241 }
242
243 template <class Type>
244 static Type* cpy(Type* result, Type* data) {
245 return (Type*)memcpy(result, data, sizeof(Type));
246 }
247 template <class Type>
248 static Type* cpy(Type* data) {
249 return cpy((Type*)omAlloc0(sizeof(Type)), data);
250 }
251 template <class Type>
252 static Type* recursivecpy(Type* data) {
253 if (data == NULL) return data;
254 Type* result = cpy(data);
255 result->next = recursivecpy(data->next);
256 return result;
257 }
258 template <class Type>
259 static Type* shallowcpy(Type* result, Type* data) {
260 cpy(result, data)->e = recursivecpy(data->e);
261 return result;
262 }
263 template <class Type>
264 static Type* shallowcpy(Type* data) {
265 return shallowcpy((Type*) omAlloc0(sizeof(Type)), data);
266 }
267 template <class Type>
268 static void recursivekill(Type* current) {
269 if(current == NULL) return;
270 recursivekill(current->next);
271 omFree(current);
272 }
273 static leftv allocate() { return (leftv)omAlloc0(sizeof(sleftv)); }
274
275};
276
277/** @class LeftvShallow
278 * Ths class wraps @c leftv by taking into acount memory allocation, destruction
279 * as well as shallowly copying of a given @c leftv, i.e. we just copy auxiliary
280 * information (like subexpressions), but not the actual data.
281 *
282 * @note This is useful to avoid invalidating @c leftv while operating on th
283 **/
285 public LeftvHelper {
287
288public:
289 /// Just allocate (all-zero) @c leftv
291 /// Shallow copy the input data
293 /// Construct (shallow) copy of @c *this
294 LeftvShallow(const self& rhs): m_data(shallowcpy(rhs.m_data)) { }
295
296 /// Destruct
299 omFree(m_data);
300 }
301
302 /// Assign shallow copy of the input
305 shallowcpy(m_data, rhs);
306 return *this;
307 }
308 /// Assign (shallow) copy of @c *this
309 self& operator=(const self& rhs) { return (*this) = rhs.m_data; }
310
311 /// @name Pointer-style access
312 //@{
313 /*const*/ leftv operator->() const { return m_data; }
314 /*^ warning: 'const' type qualifier on return type has no effect!!! */
315 leftv operator->() { return m_data; }
316 //@]
317
318protected:
319 /// The actual data pointer
321};
322
323/** @class LeftvDeep
324 * This class wraps @c leftv by taking into acount memory allocation, destruction
325 * as well as deeply copying of a given @c leftv, i.e. we also take over
326 * ownership of the @c leftv data.
327 *
328 * We have two variants:
329 + LeftvDeep(leftv): treats referenced identifiers as "the data"
330 + LeftvDeep(leftv, copy_tag): takes care of a full copy of identifier's data
331 *
332 * @note It invalidats @c leftv on input.
333 **/
335 public LeftvHelper {
337
338 /// @name Do not permit copying (avoid inconsistence)
339 //@{
342 //@}
343
344public:
345 /// Allocate all-zero object by default
347
348 /// Store a deep copy of the data
349 /// @ note Occupies the provided @c leftv and invalidates the latter
350 LeftvDeep(leftv data): m_data(cpy(data)) {
351 data->e = NULL; // occupy subexpression
352 if(!isid()) m_data->data=data->CopyD();
353 }
354
355 /// Construct even deeper copy:
356 /// Skip identifier (if any) and take care of the data on our own
357 struct copy_tag {};
359
360 /// Really clear data
362
363 /// @name Access via shallow copy to avoid invalidating the stored handle
364 //@{
365 operator LeftvShallow() { return m_data; }
366 LeftvShallow operator*() {return *this; }
367 //@}
368
369 /// Determine whether we point to the same data
370 bool like(const self& rhs) const { return m_data->data == rhs.m_data->data; }
371
372 /// Reassign a new deep copy by occupieing another @c leftv
373 /// @note clears @c *this in the first
375 if(isid()) {
376 m_data->e = rhs->e;
377 rhs->e = NULL;
378 IDTYP((idhdl)m_data->data) = rhs->Typ();
379 IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD();
380 }
381 else {
382 m_data->CleanUp();
383 m_data->Copy(rhs);
384 }
385 return *this;
386 }
387
388 /// Check a given context for our identifier
389 BOOLEAN brokenid(idhdl context) const {
390 assume(isid());
391 return (context == NULL) ||
392 ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context)));
393 }
394
395 /// Put a shallow copy to given @c leftv
397 leftv next = result->next;
398 result->next = NULL;
399 result->CleanUp();
400
402 result->next = next;
403
404 /// @note @c attrib should read the attributes of the identifier
405 if (isid()) {
406 result->attribute = ((idhdl)m_data->data)->attribute;
407 result->flag = ((idhdl)m_data->data)->flag;
408
409 }
410 return FALSE;
411 }
412
413 /// Get additional data (e.g. subexpression data) from likewise instances
415 if (res->data == m_data->data) {
416 if(m_data->e != res->e) recursivekill(m_data->e);
417 cpy(m_data, res);
418 res->Init();
419 return TRUE;
420 }
421 return FALSE;
422 }
423
424
425 /// Check for being an identifier
426 BOOLEAN isid() const { return m_data->rtyp==IDHDL;}
427 /// Test whether we reference to ring-dependent data
429 /// Check whether (all-zero) initialized data was never assigned.
430 BOOLEAN unassigned() const { return m_data->Typ()==0; }
431
432 /// Wrap data by identifier, if not done yet
435 ++(((idhdl)res->data)->ref);
436 return res;
437 }
438
439 /// Erase identifier handles by @c *this
440 /// @note Assumes that we reference an identifier and that we own the latter.
441 /// This is useful to clear the result of a subsequent call of @c idify.
442 void clearid(idhdl* root) {
443 assume(isid());
444 if (--((idhdl)m_data->data)->ref <= 0) // clear only if we own
446 }
447
448private:
449 /// Store the actual data
451};
452
453/// Initialize @c blackbox types 'reference' and 'shared', or both
456
457inline void
459{
462}
463
464
465#endif /*SINGULAR_COUNTEDREF_H_ */
466
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
CanonicalForm head(const CanonicalForm &f)
CountedRefIndirectPtr & operator=(PtrType ptr)
Definition: countedref.h:145
CountedRefIndirectPtr(PtrType ptr)
Definition: countedref.h:144
This class implements a smart pointer which handles pointer-style access to a reference-counted struc...
Definition: countedref.h:43
count_type count() const
Store actual pointer.
Definition: countedref.h:95
ptr_type operator->()
Definition: countedref.h:90
ptr_type m_ptr
Store actual pointer.
Definition: countedref.h:105
self & operator=(const self &rhs)
Definition: countedref.h:72
self & operator=(ptr_type ptr)
Definition: countedref.h:73
const ptr_type operator->() const
Definition: countedref.h:89
CountedRefPtr(ptr_type ptr)
Convert from pointer.
Definition: countedref.h:57
void release()
Store actual pointer.
Definition: countedref.h:97
CountedRefPtr self
Definition: countedref.h:44
void reclaim()
Store actual pointer.
Definition: countedref.h:96
CountType count_type
Definition: countedref.h:49
bool operator==(const self &rhs) const
Checking equality.
Definition: countedref.h:82
~CountedRefPtr()
Unlink one reference.
Definition: countedref.h:69
CountedRefPtr(const CountedRefPtr< ptr_type, !nondestructive, Never, count_type > &rhs)
Convert from compatible smart pointer.
Definition: countedref.h:61
CountedRefPtr()
Default constructor.
Definition: countedref.h:54
CountedRefPtr(const self &rhs)
Construct refernce copy.
Definition: countedref.h:65
bool operator==(ptr_type ptr) const
Definition: countedref.h:85
PtrType ptr_type
Definition: countedref.h:48
CountedRefWeakPtr(const self &rhs)
Construct copy.
Definition: countedref.h:172
CountedRefWeakPtr self
Definition: countedref.h:155
CountedRefPtr< CountedRefIndirectPtr< ptr_type > * > ptrptr_type
Construct unassigned weak reference.
Definition: countedref.h:162
bool unassigned() const
Test whether reference was never used.
Definition: countedref.h:181
CountedRefWeakPtr()
Construct unassigned weak reference.
Definition: countedref.h:166
CountedRefWeakPtr(ptr_type ptr)
Convert from pointer.
Definition: countedref.h:169
ptr_type operator->()
Construct unassigned weak reference.
Definition: countedref.h:201
PtrType ptr_type
Construct unassigned weak reference.
Definition: countedref.h:161
bool operator==(ptr_type ptr) const
Construct unassigned weak reference.
Definition: countedref.h:196
self & operator=(ptr_type ptr)
Construct unassigned weak reference.
Definition: countedref.h:189
~CountedRefWeakPtr()
Unlink one reference (handled by CountedRefPtr)
Definition: countedref.h:175
void invalidate()
Mark weak reference as invalid.
Definition: countedref.h:178
ptrptr_type m_indirect
Construct unassigned weak reference.
Definition: countedref.h:204
const ptr_type operator->() const
Construct unassigned weak reference.
Definition: countedref.h:200
bool operator!=(ptr_type rhs) const
Construct unassigned weak reference.
Definition: countedref.h:199
self & operator=(const self &rhs)
Construct unassigned weak reference.
Definition: countedref.h:185
This class wraps leftv by taking into acount memory allocation, destruction as well as deeply copying...
Definition: countedref.h:335
LeftvDeep(leftv data)
Store a deep copy of the data @ note Occupies the provided leftv and invalidates the latter.
Definition: countedref.h:350
LeftvShallow operator*()
Store the actual data.
Definition: countedref.h:366
void clearid(idhdl *root)
Erase identifier handles by *this.
Definition: countedref.h:442
BOOLEAN isid() const
Check for being an identifier.
Definition: countedref.h:426
BOOLEAN ringed()
Test whether we reference to ring-dependent data.
Definition: countedref.h:428
BOOLEAN brokenid(idhdl context) const
Check a given context for our identifier.
Definition: countedref.h:389
LeftvDeep(leftv data, copy_tag)
Allocate all-zero object by default.
Definition: countedref.h:358
~LeftvDeep()
Really clear data.
Definition: countedref.h:361
BOOLEAN unassigned() const
Check whether (all-zero) initialized data was never assigned.
Definition: countedref.h:430
self & operator=(leftv rhs)
Reassign a new deep copy by occupieing another leftv.
Definition: countedref.h:374
LeftvDeep self
Definition: countedref.h:336
LeftvDeep()
Allocate all-zero object by default.
Definition: countedref.h:346
self & operator=(const self &)
Allocate all-zero object by default.
BOOLEAN retrieve(leftv res)
Get additional data (e.g. subexpression data) from likewise instances.
Definition: countedref.h:414
bool like(const self &rhs) const
Determine whether we point to the same data.
Definition: countedref.h:370
leftv idify(idhdl *root)
Wrap data by identifier, if not done yet.
Definition: countedref.h:433
BOOLEAN put(leftv result)
Put a shallow copy to given leftv.
Definition: countedref.h:396
LeftvDeep(const self &)
Allocate all-zero object by default.
leftv m_data
Store the actual data.
Definition: countedref.h:450
Construct even deeper copy: Skip identifier (if any) and take care of the data on our own.
Definition: countedref.h:357
This class implements some recurrent code sniplets to be used with leftv and idhdl....
Definition: countedref.h:213
static Type * shallowcpy(Type *data)
Definition: countedref.h:264
static void recursivekill(Type *current)
Definition: countedref.h:268
static Type * cpy(Type *result, Type *data)
Definition: countedref.h:244
static idhdl newid(leftv head, idhdl *root)
Definition: countedref.h:223
static leftv allocate()
Definition: countedref.h:273
static Type * recursivecpy(Type *data)
Definition: countedref.h:252
static void clearid(idhdl handle, idhdl *root)
Definition: countedref.h:237
static leftv idify(leftv head, idhdl *root)
Definition: countedref.h:215
static Type * cpy(Type *data)
Definition: countedref.h:248
static Type * shallowcpy(Type *result, Type *data)
Definition: countedref.h:259
Ths class wraps leftv by taking into acount memory allocation, destruction as well as shallowly copyi...
Definition: countedref.h:285
leftv operator->()
The actual data pointer.
Definition: countedref.h:315
leftv m_data
The actual data pointer.
Definition: countedref.h:320
LeftvShallow()
Just allocate (all-zero) leftv.
Definition: countedref.h:290
~LeftvShallow()
Destruct.
Definition: countedref.h:297
leftv operator->() const
The actual data pointer.
Definition: countedref.h:313
LeftvShallow self
Definition: countedref.h:286
LeftvShallow(leftv data)
Shallow copy the input data.
Definition: countedref.h:292
self & operator=(leftv rhs)
Assign shallow copy of the input.
Definition: countedref.h:303
LeftvShallow(const self &rhs)
Construct (shallow) copy of *this.
Definition: countedref.h:294
self & operator=(const self &rhs)
Assign (shallow) copy of *this.
Definition: countedref.h:309
This class implements implements a refernce counter which we can use as a public base of objects mana...
Definition: countedref.h:112
~RefCounter()
Destructor.
Definition: countedref.h:125
RefCounter(...)
Any Constructor resets the counter.
Definition: countedref.h:122
count_type ref
Number of references.
Definition: countedref.h:129
short count_type
Name numerical type for enumbering.
Definition: countedref.h:116
Definition: idrec.h:35
idhdl set(const char *s, int lev, int t, BOOLEAN init=TRUE)
Definition: ipid.cc:237
Class used for (list of) interpreter objects.
Definition: subexpr.h:83
void * CopyD(int t)
Definition: subexpr.cc:710
int Typ()
Definition: subexpr.cc:1019
int rtyp
Definition: subexpr.h:91
BOOLEAN RingDependend()
Definition: subexpr.cc:418
void Copy(leftv e)
Definition: subexpr.cc:685
void * data
Definition: subexpr.h:88
void CleanUp(ring r=currRing)
Definition: subexpr.cc:348
Subexpr e
Definition: subexpr.h:105
void countedref_reference_load()
Initialize blackbox types 'reference' and 'shared', or both.
Definition: countedref.cc:700
void CountedRefPtr_kill(CountedRefIndirectPtr< PtrType > *pval)
Definition: countedref.h:151
void countedref_init()
Definition: countedref.h:458
void countedref_shared_load()
Definition: countedref.cc:724
return result
Definition: facAbsBiFact.cc:75
CanonicalForm res
Definition: facAbsFact.cc:60
#define STATIC_VAR
Definition: globaldefs.h:7
void killhdl2(idhdl h, idhdl *ih, ring r)
Definition: ipid.cc:445
idhdl enterid(const char *s, int lev, int t, idhdl *root, BOOLEAN init, BOOLEAN search)
Definition: ipid.cc:279
#define IDNEXT(a)
Definition: ipid.h:118
#define IDDATA(a)
Definition: ipid.h:126
#define IDTYP(a)
Definition: ipid.h:119
ListNode * next
Definition: janet.h:31
#define assume(x)
Definition: mod2.h:389
#define omFree(addr)
Definition: omAllocDecl.h:261
#define omAlloc0(size)
Definition: omAllocDecl.h:211
#define NULL
Definition: omList.c:12
idrec * idhdl
Definition: ring.h:21
sleftv * leftv
Definition: structs.h:57
int name
New type name for int.
Definition: templateForC.h:21
#define IDHDL
Definition: tok.h:31
#define NONE
Definition: tok.h:221