Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
AbsPtr.h
Go to the documentation of this file.
1#ifndef ABSCONT_H
2#define ABSCONT_H
3/*
4Copyright (c) 1999-2004 I. B. Smirnov
5
6The file can be used, copied, modified, and distributed
7according to the terms of GNU Lesser General Public License version 2.1
8as published by the Free Software Foundation,
9and provided that the above copyright notice, this permission notice,
10and notices about any modifications of the original text
11appear in all copies and in supporting documentation.
12The file is provided "as is" without express or implied warranty.
13*/
14
15#include <iostream>
16#include <cstring>
17#include <limits.h>
18#include <typeinfo>
20
21//#define IMPLICIT_X_STAR
22
23#define USE_DOUBLE_PTR_IN_PASSIVEPTR
24// New option. Makes passive ptr keeping address of counter and address
25// of object. This allow to avoid dynamic casts while still allowing
26// the class RegPassivePtr be virtual.
27
28//#define USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
29// for debug of the option above. At each access it checks
30// that the object address in ptr is equal to the address
31// restored from the counter.
32
33#define USE_DELETE_AT_ZERO_COUNT
34// to switch on option for emulation of shared pointer.
35// But it only gives possibility to emulate it by the passive pointer,
36// but does not make passive pointer equival to shared one.
37// You should assign 1 to s_allow_del_at_zero_count of each particular object,
38// which should be deleted.
39
40//#define SKIP_CHECKS_NULL // skip checks of smart pointers
41// (that they are not NULL) at
42// dereferencing via getver(), *, and ->.
43// In all cases at the normal execution the object should not be NULL
44// for these operators.
45// Skiping checks, we assume that they are not NULL
46// (and risk to have bad undetected errors at the execution time).
47// This option is incerted due to curiosity about for how much
48// the checks delay the program.
49// For Monte Carlo simulation the result was a few percent.
50// Therefore the use (uncommenting) of this macro for the purposes
51// other than similar curiosity does NOT have any sense.
52
53// To be addressed by active pointer an object of a class
54// should have a function copy() which clones the object and returns
55// the new address, and may have have a function print()
56// which prints it to a stream.
57// The copy() is declared pure just to ensure that the user does not
58// forget to define it in derivative.
59
60#define COPY_TYPE_CHECK // make execution longer, but allows
61// to detect missings of copy functions in classes referred by
62// active pointers.
63
64#define USE_GETSETTERS_IN_PASSIVEPTR // new option allowing to use
65// getters and setters in the passive pointer
66// instead or in addition to direct access to auxiliary parameters.
67// It allows to control correctness of input values and also to use
68// fields if the next option is switched on. But note that using fields
69// can increase the size of the code.
70// Switching this option on does not forbid to use direct access to
71// these parameters.
72
73#define USE_PRIVATE_PARAM_IN_PASSIVEPTR // allows to change parameters
74 // only through getters and setters.
75// Obviously, switching this option on requires switching on the previous
76// option, which is controlled by the following:
77#if defined(USE_PRIVATE_PARAM_IN_PASSIVEPTR) && \
78 !defined(USE_GETSETTERS_IN_PASSIVEPTR)
79"options incompatible\n"; // any line to trigger compiler diagnostic
80#endif
81
82#define USE_CHAR_CONTROL_VARIABLES // instead of int control variables
83// enables to use char control variables (except two static ones),
84// which could be optimal
85// both for memory and speed, but that it is really optimal
86// is not checked so far.
87
88//#define USE_BIT_FIELDS // instead of int control variables
89// allowes to pack control auxiliary
90// variables presented in passive pointer into bit fields.
91// It is assumed that the passive pointer objects and the whole
92// programs using it could be smaller in size with this option switched on.
93// But be informed that according to Stroustrup this is not always the fact:
94// this reduces the data but increases the executable code size.
95// Also the performance could be
96// decreased due to necessity to unpack these thinigs each time at their use.
97// This option does not compatible with the previous one.
98// So only one of them can be switched on, which is checked by the following:
99
100//#define USE_BIT_OPERA // Instead of the two previous options
101// allowes to pack control auxiliary
102// variables presented in passive pointer into bit fields
103// and to use bit operations.
104// Currently under debug.
105#if defined(USE_CHAR_CONTROL_VARIABLES) && defined(USE_BIT_FIELDS)
106"options incompatible\n"; // any line to trigger compiler diagnostic
107#endif
108#if defined(USE_CHAR_CONTROL_VARIABLES) && defined(USE_BIT_OPERA)
109"options incompatible\n"; // any line to trigger compiler diagnostic
110#endif
111#if defined(USE_BIT_FIELDS) && defined(USE_BIT_OPERA)
112"options incompatible\n"; // any line to trigger compiler diagnostic
113#endif
114
115#define USE_CHAR_GETSETTERS_PARAMETERS // related to type of parameters
116 // in gatters and setters.
117// If this macro is enabled, the parameters are "char".
118// Otherwise the parameters and int.
119// What is faster I do not know at the moment
120// They are not bool since in many instanses they can have the values
121// of 0, 1, or 2 (and the author does not like bool type at all).
122#if defined(USE_CHAR_CONTROL_VARIABLES) && \
123 !defined(USE_CHAR_GETSETTERS_PARAMETERS)
124"options incompatible\n"; // any line to trigger compiler diagnostic
125#endif
126
127namespace Heed {
128
129template <class X>
131 public:
132 static X* copy(const X* f) {
133#ifdef DEBUG_ACTIVEPTR
134 mcout << "static X* StandardCopyDefinition::copy(const X* f)\n";
135#endif
136 // If to allow the type of copy function be any (void* for example,
137 // it needs to convert it. This seems there is no reason to allow this.
138#ifndef COPY_TYPE_CHECK
139 return f->copy();
140#else
141 X* p = f->copy();
142#ifdef DEBUG_ACTIVEPTR
143 mcout << "X* StandardCopyDefinition::copy(const X* f): f->copy() returned "
144 << p << '\n';
145 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
146 << '\n';
147 mcerr << "Type of *p is (in internal notations) " << typeid(*p).name()
148 << '\n';
149#endif
150 if (typeid(*p) != typeid(*f)) {
151 mcerr << "Error in X* StandardCopyDefinition::copy(const X* f): "
152 << "typeid(*p) != typeid(*f) \n";
153 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
154 << '\n';
155 mcerr << "Type of *p is (in internal notations) " << typeid(*p).name()
156 << '\n';
157 mcerr << "Type of *f is (in internal notations) " << typeid(*f).name()
158 << '\n';
159 mcerr << "Possible reason is omiting of copy function in one of the "
160 "derivative classes\n";
161 spexit(mcerr);
162 }
163 return p;
164#endif
165 }
166};
167
168/* The second parameter determines the class which has to have only one
169function copy() which "knows" the actual name of cloning function.
170Normally the cloning function is copy() as well.
171But can be any.
172Previously at this place there were some terrible comment
173which told that there might be some problems. But it was outdated.
174At contemporary systems there is no problems.
175So any complicated tree of derived classes even with multiple inheritance
176can each have the same-named function
177returning different types with accordance with
178the type of the class.
179Everything is compiled and work.
180But do not forget to add virtual destructors in pointee classes!
181In particular, when playing with multiple inheritance.
182*/
183
184enum Pilfer {
185 steal
187enum Clone {
190enum Pass {
193
194template <class X>
195class PassivePtr;
196
197class RegPassivePtr;
198
199namespace CountPP_ns {
200/// Counter of protected pointers.
202 public:
203 CountPassivePtr(const RegPassivePtr* frpp) : rpp(frpp), number_of_booked(0) {}
204
205 // In the following I will use the word book instead of register,
206 // because register seems to be interfered with some computer definition
207 inline void book(void);
208 inline void unbook(void);
209 inline long get_number_of_booked(void) { return number_of_booked; }
210 inline const RegPassivePtr* get_rpp(void) { return rpp; }
211 inline void change_rpp(const RegPassivePtr* frpp) { rpp = frpp; }
212 inline ~CountPassivePtr(); // here to delete reference from RegPassivePtr
213 private:
214 const RegPassivePtr* rpp;
215 // const is necessary here to make possible booking of RegPassivePtr
216 // by a function which is declared as const.
217
218 long number_of_booked; // the counter of pointers
219};
220
221inline void CountPassivePtr::book(void) {
222 if (number_of_booked > LONG_MAX - 1) {
223 mcerr << "Error in CountPassivePtr::book(void):\n"
224 << " too much booked counters, number_of_booked > LONG_MAX-1, "
225 "number_of_booked=" << number_of_booked << '\n';
226 spexit(mcerr);
227 }
228 number_of_booked++;
229}
230
231inline void CountPassivePtr::unbook(void) {
232 if (number_of_booked < 1) {
233 mcerr << "Error in CountPassivePtr::unbook(void):\n"
234 << " number_of_booked < 1, number_of_booked=" << number_of_booked
235 << '\n';
236 spexit(mcerr);
237 }
238 number_of_booked--;
239}
240}
241
242#ifdef USE_BIT_OPERA
243
244const unsigned char eb_s_ban_del = 1;
245const unsigned char eb_s_ban_sub1 = 2;
246const unsigned char eb_s_ban_sub2 = 4;
247const unsigned char eb_s_ban_cop1 = 8;
248const unsigned char eb_s_ban_cop2 = 16;
249#ifdef USE_DELETE_AT_ZERO_COUNT
250const unsigned char eb_s_allow_del_at_zero_count = 32;
251#endif
252#endif
253
255 public:
257// used for making cpp NULL when CountPassivePtr
258// is destructed
259
260#ifdef USE_BIT_OPERA
261 private:
262 inline static void clear_bit(unsigned char& cw, unsigned char b) {
263 if ((cw & b) != 0) {
264 cw ^= b;
265 }
266 }
267 inline static void rise_bit(unsigned char& cw, unsigned char b) { cw |= b; }
268
269 public:
270// To define auxiliary class, used only in the following case:
271#elif defined(USE_BIT_FIELDS)
272 class ControlParam {
273 public:
274 unsigned int s_ban_del : 1; // see below for comments
275 unsigned int s_ban_sub : 2;
276 unsigned int s_ban_cop : 2;
277#ifdef USE_DELETE_AT_ZERO_COUNT
278 unsigned int s_allow_del_at_zero_count : 1;
279#endif
280 ControlParam(void)
281 : s_ban_del(0),
282 s_ban_sub(0),
283 s_ban_cop(0)
285 ,
286 s_allow_del_at_zero_count(0)
287#endif
288 {
289 }
290#ifdef USE_CHAR_GETSETTERS_PARAMETERS
291 ControlParam(char fs_ban_del, char fs_ban_sub, char fs_ban_cop = 0
293 ,
294 char fs_allow_del_at_zero_count = 0
295#endif
296 )
297 :
298#else
299 ControlParam(int fs_ban_del, int fs_ban_sub, int fs_ban_cop = 0
301 ,
302 int fs_allow_del_at_zero_count = 0
303#endif
304 )
305 :
306#endif
307 s_ban_del(fs_ban_del),
308 s_ban_sub(fs_ban_sub),
309 s_ban_cop(fs_ban_cop)
311 ,
312 s_allow_del_at_zero_count(fs_allow_del_at_zero_count)
313#endif
314 {
315 if (!(fs_ban_del == 0 || fs_ban_del == 1)) {
316 mcerr << "ERROR in ControlParam::ControlParam(...)\n";
317 mcerr << "s_ban_del is outside limits, s_ban_del=" << fs_ban_del
318 << '\n';
319 spexit(mcerr);
320 }
321 if (fs_ban_sub < 0 || fs_ban_sub > 2) {
322 mcerr << "ERROR in ControlParam::ControlParam(...):\n";
323 mcerr << "s_ban_sub is outside limits, s_ban_sub=" << fs_ban_sub
324 << '\n';
325 spexit(mcerr);
326 }
327 if (fs_ban_cop < 0 || fs_ban_cop > 2) {
328 mcerr << "ERROR in ControlParam::ControlParam(...):\n";
329 mcerr << "s_ban_cop is outside limits, s_ban_cop=" << fs_ban_cop
330 << '\n';
331 spexit(mcerr);
332 }
333#ifdef USE_DELETE_AT_ZERO_COUNT
334 if (!(s_allow_del_at_zero_count == 0 || s_allow_del_at_zero_count == 1)) {
335 mcerr << "ERROR in ControlParam::ControlParam(...)\n";
336 mcerr << "s_allow_del_at_zero_count is outside limits, "
337 "s_allow_del_at_zero_count=" << fs_allow_del_at_zero_count
338 << '\n';
339 spexit(mcerr);
340 }
341#endif
342 }
343 }; // the total 6 bits
344#endif // ifdef USE_BIT_FIELDS
345
346 inline RegPassivePtr(void)
347 :
348#ifdef USE_BIT_OPERA
349 control_word(0),
350#elif defined USE_BIT_FIELDS
351 conparam(),
352#else
353 s_ban_del(0),
354 s_ban_sub(0),
355 s_ban_cop(0),
357 s_allow_del_at_zero_count(0),
358#endif
359#endif
360 cpp(NULL) {
361 }
362#ifdef USE_CHAR_GETSETTERS_PARAMETERS
363 inline RegPassivePtr(char fs_ban_del, char fs_ban_sub, char fs_ban_cop = 0)
364 :
365#else
366 inline RegPassivePtr(int fs_ban_del, int fs_ban_sub, int fs_ban_cop = 0)
367 :
368#endif
369#ifdef USE_BIT_OPERA
370 control_word(0),
371#elif defined(USE_BIT_FIELDS)
372 conparam(fs_ban_del, fs_ban_sub, fs_ban_cop),
373#else
374 s_ban_del(fs_ban_del), s_ban_sub(fs_ban_sub), s_ban_cop(fs_ban_cop),
376 s_allow_del_at_zero_count(0),
377#endif
378#endif
379 cpp(NULL) {
380#ifdef USE_BIT_OPERA
381 set_s_ban_del(fs_ban_del);
382 set_s_ban_sub(fs_ban_sub);
383 set_s_ban_cop(fs_ban_cop);
384#endif
385 }
386
388
390 // Copies s_ban_del and s_ban_sub
391 // Also calls clear_pointers if s_ban_sub==1 or
392 // spexit() if s_ban_sub==2 and the alist_of_prot_pointers is not empty.
393
394 inline CountPP_ns::CountPassivePtr* book(void) const {
395 if (!cpp) cpp = new CountPP_ns::CountPassivePtr(this);
396 cpp->book();
397 return cpp;
398 }
399
400 inline void clear_pointers(void) const {
401 // all pointers addressing this are cleared;
402 if (cpp) cpp->change_rpp(NULL);
403 }
404
405 virtual RegPassivePtr* copy() const { return new RegPassivePtr(*this); }
406
407 virtual ~RegPassivePtr();
408 // If there are pointers addressed this object and s_ban_del = 1,
409 // the program is terminated with output message to mcerr.
410 // Otherwise (normal behaviour) the references are cleared.
411
412 virtual void print(std::ostream& file, int l = 1) const;
413 friend std::ostream& operator<<(std::ostream& file, const RegPassivePtr& f);
414
415// Three parameters controlling behaviour of pointee object at
416// its deletion and substitution.
417// They are included for the sake of flexibility and
418// they are necessary very rarely. Normally they are not used.
419// If needed, you can set them though constructors,
420// or change responsibly directly.
421// Obviously, this is a temporary design.
422// It needs then to pack all these small numbers in one computer word.
423
424#ifdef USE_BIT_OPERA
425 private:
426 unsigned char control_word;
427
428 public:
429#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
430 private:
431#endif
432 static int s_ban_del_ignore;
433 static int s_print_adr_cpp;
434#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
435 public:
436#endif
437
438#elif defined(USE_BIT_FIELDS)
439 private:
440 ControlParam conparam;
441
442 public:
443#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
444 private:
445#endif
446 static int s_ban_del_ignore;
447 static int s_print_adr_cpp;
448#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
449 public:
450#endif
451
452#else // for elif defined( USE_BIT_FIELDS )
453
454#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
455 private:
456#endif
457#ifdef USE_CHAR_CONTROL_VARIABLES
458 char s_ban_del;
459#else
460 int s_ban_del;
461#endif
462 // sign whether this object can (0) or cannot (1)
463 // be deleted if it is addressed.
464 // Normally it can. When it happens, the pointers addressing this object
465 // are cleared and set to NULL.
466 // If user needs to find where he deletes referenced object,
467 // he may assign this variable to 1
468
469 static int s_ban_del_ignore;
470// auxiliary variable with default value 0,
471// meaning that s_ban_del is not ignored.
472// In the case of value 1 s_ban_del is ignored, whatever it is.
473// It is used in RegPassivePtr::~RegPassivePtr() to avoid loops at exiting
474// after the fist deletion of referenced object at s_ban_del = 1 is found.
475
476#ifdef USE_CHAR_CONTROL_VARIABLES
477 char s_ban_sub;
478#else
479 int s_ban_sub;
480#endif
481// sign controlling substitution of addressed object:
482// 0 - it can be substituted and the pointers addressing "this" preserve
483// their values (normal default case).
484// 1 - it can be substituted, but the pointers will be assigned NULL.
485// In the case of self-assignment and valid pointers to "this"
486// the run-time error is triggered, because otherwise either
487// the pointers to copied object would not be preserved or
488// the pointers to "this" would not be cleared - principal contradiction.
489// 2 - it cannot be substituted, if there are pointers to "this",
490// attempt to substitute in this case triggers error.
491// In the case of absence of pointers to this it is substituted.
492// Note: if the substitution is allowed,
493// s_ban_del, s_ban_sub, and s_ban_cop are themselves substituted -
494// arbitrary decision, perhaps correct.
495
496#ifdef USE_CHAR_CONTROL_VARIABLES
497 char s_ban_cop;
498#else
499 int s_ban_cop;
500#endif
501// sign controlling copying addressed object
502// 0 - it can always be copied
503// 1 - it can be copied only if there are no references,
504// otherwise it will be runtime error.
505// 2 - it can never be copied, but it is anyway runtime error,
506// the compiler cannot detect it.
507
508#ifdef USE_DELETE_AT_ZERO_COUNT
509#ifdef USE_CHAR_CONTROL_VARIABLES
510 char s_allow_del_at_zero_count;
511#else
512 int s_allow_del_at_zero_count;
513#endif
514// concession to people who likes shared pointers.
515// Instructs PassivePtr::~PassivePtr to delete the object if that
516// pointer is last. Think twice before use.
517// It basically violates the ideoma of reference to independent object.
518// Also in the case of circular references the program can fall into loop
519// of destructors, which is not the case for regular passive pointers.
520#endif
521
522 static int s_print_adr_cpp;
523// signature to print the address of cpp in operator<<
524// by default it is 0 and address is not printed,
525// but only the remark that it is NULL or not NULL is printed.
526// It is good for making such output listings which do not depend
527// on computer and can be automatically compared.
528// But in the case of some deep debug the user can make them printed
529// if he assigns s_print_adr_cpp = 1.
530#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
531 public:
532#endif
533
534#endif // for elif defined( USE_BIT_FIELDS )
535
536#ifdef USE_GETSETTERS_IN_PASSIVEPTR
537 public:
538#ifdef USE_CHAR_GETSETTERS_PARAMETERS
539 inline void set_s_ban_del(char fs_ban_del)
540#else
541 inline void set_s_ban_del(int fs_ban_del)
542#endif
543 {
544#ifdef USE_BIT_OPERA
545 if (fs_ban_del == 0)
546 clear_bit(control_word, eb_s_ban_del);
547 else if (fs_ban_del == 1)
548 rise_bit(control_word, eb_s_ban_del);
549#else
550 if (fs_ban_del == 0 || fs_ban_del == 1) {
551#ifdef USE_BIT_FIELDS
552 conparam.s_ban_del = fs_ban_del;
553#else
554 s_ban_del = fs_ban_del;
555#endif
556 }
557#endif
558 else {
559 mcerr << "ERROR in inline void set_s_ban_del(int fs_ban_del):\n";
560 mcerr << "s_ban_del is outside limits, s_ban_del=" << int(fs_ban_del)
561 << '\n';
562 spexit(mcerr);
563 }
564 }
565
566#ifdef USE_CHAR_GETSETTERS_PARAMETERS
567 inline char get_s_ban_del(void) const
568#else
569 inline int get_s_ban_del(void) const
570#endif
571#ifdef USE_BIT_OPERA
572 {
573 if ((control_word & eb_s_ban_del) != 0)
574 return 1;
575 else
576 return 0;
577 }
578#elif defined(USE_BIT_FIELDS)
579 {
580 return conparam.s_ban_del;
581 }
582#else
583 { return s_ban_del; }
584#endif
585
586#ifdef USE_CHAR_GETSETTERS_PARAMETERS
587 inline static void set_s_ban_del_ignore(char fs_ban_del_ignore)
588#else
589 inline static void set_s_ban_del_ignore(int fs_ban_del_ignore)
590#endif
591 {
592 if (fs_ban_del_ignore == 0 || fs_ban_del_ignore == 1) {
593 s_ban_del_ignore = fs_ban_del_ignore;
594 } else {
595 mcerr << "ERROR in inline void set_s_ban_del_ignore(int "
596 "fs_ban_del_ignore ):\n";
597 mcerr << "s_ban_del_ignore is outside limits, s_ban_del_ignore="
598 << int(fs_ban_del_ignore) << '\n';
599 spexit(mcerr);
600 }
601 }
602
603#ifdef USE_CHAR_GETSETTERS_PARAMETERS
604 inline static char get_s_ban_del_ignore(void)
605#else
606 inline static int get_s_ban_del_ignore(void)
607#endif
608 {
609 return s_ban_del_ignore;
610 }
611
612#ifdef USE_CHAR_GETSETTERS_PARAMETERS
613 inline void set_s_ban_sub(char fs_ban_sub)
614#else
615 inline void set_s_ban_sub(int fs_ban_sub)
616#endif
617 {
618#ifdef USE_BIT_OPERA
619 if (fs_ban_sub == 0) {
620 clear_bit(control_word, eb_s_ban_sub1);
621 clear_bit(control_word, eb_s_ban_sub2);
622 } else if (fs_ban_sub == 1) {
623 rise_bit(control_word, eb_s_ban_sub1);
624 clear_bit(control_word, eb_s_ban_sub2);
625 } else if (fs_ban_sub == 2) {
626 clear_bit(control_word, eb_s_ban_sub1);
627 rise_bit(control_word, eb_s_ban_sub2);
628 }
629#else
630 if (fs_ban_sub >= 0 && fs_ban_sub <= 2) {
631#ifdef USE_BIT_FIELDS
632 conparam.s_ban_sub = fs_ban_sub;
633#else
634 s_ban_sub = fs_ban_sub;
635#endif
636 }
637#endif
638 else {
639 mcerr << "ERROR in inline void set_s_ban_sub(int fs_ban_sub):\n";
640 mcerr << "s_ban_sub is outside limits, s_ban_sub=" << int(fs_ban_sub)
641 << '\n';
642 spexit(mcerr);
643 }
644 }
645
646#ifdef USE_CHAR_GETSETTERS_PARAMETERS
647 inline char get_s_ban_sub(void) const
648#else
649 inline int get_s_ban_sub(void) const
650#endif
651#ifdef USE_BIT_OPERA
652 {
653 if ((control_word & eb_s_ban_sub2) == 0) {
654 if ((control_word & eb_s_ban_sub1) == 0)
655 return 0;
656 else
657 return 1;
658 } else {
659 // Iprintn(mcout, (control_word & eb_s_ban_sub1) );
660 // Iprintn(mcout, (control_word & eb_s_ban_sub2) );
661 return 2;
662 }
663 }
664#elif defined(USE_BIT_FIELDS)
665 {
666 return conparam.s_ban_sub;
667 }
668#else
669 { return s_ban_sub; }
670#endif
671
672#ifdef USE_CHAR_GETSETTERS_PARAMETERS
673 inline void set_s_ban_cop(char fs_ban_cop)
674#else
675 inline void set_s_ban_cop(int fs_ban_cop)
676#endif
677 {
678#ifdef USE_BIT_OPERA
679 if (fs_ban_cop == 0) {
680 clear_bit(control_word, eb_s_ban_cop1);
681 clear_bit(control_word, eb_s_ban_cop2);
682 } else if (fs_ban_cop == 1) {
683 rise_bit(control_word, eb_s_ban_cop1);
684 clear_bit(control_word, eb_s_ban_cop2);
685 } else if (fs_ban_cop == 2) {
686 clear_bit(control_word, eb_s_ban_cop1);
687 rise_bit(control_word, eb_s_ban_cop2);
688 }
689#else
690 if (fs_ban_cop >= 0 && fs_ban_cop <= 2) {
691#ifdef USE_BIT_FIELDS
692 conparam.s_ban_cop = fs_ban_cop;
693#else
694 s_ban_cop = fs_ban_cop;
695#endif
696 }
697#endif
698 else {
699 mcerr << "ERROR in inline void set_s_ban_cop(int fs_ban_cop):\n";
700 mcerr << "s_ban_cop is outside limits, s_ban_cop=" << int(fs_ban_cop)
701 << '\n';
702 spexit(mcerr);
703 }
704 }
705
706#ifdef USE_CHAR_GETSETTERS_PARAMETERS
707 inline char get_s_ban_cop(void) const
708#else
709 inline int get_s_ban_cop(void) const
710#endif
711#ifdef USE_BIT_OPERA
712 {
713 if ((control_word & eb_s_ban_cop2) == 0) {
714 if ((control_word & eb_s_ban_cop1) == 0)
715 return 0;
716 else
717 return 1;
718 } else {
719 return 2;
720 }
721 }
722#elif defined USE_BIT_FIELDS
723 {
724 return conparam.s_ban_cop;
725 }
726#else
727 { return s_ban_cop; }
728#endif
729
730#ifdef USE_DELETE_AT_ZERO_COUNT
731
732#ifdef USE_CHAR_GETSETTERS_PARAMETERS
733 inline void set_s_allow_del_at_zero_count(char fs_allow_del_at_zero_count)
734#else
735 inline void set_s_allow_del_at_zero_count(int fs_allow_del_at_zero_count)
736#endif
737 {
738#ifdef USE_BIT_OPERA
739 if (fs_allow_del_at_zero_count == 0)
740 clear_bit(control_word, eb_s_allow_del_at_zero_count);
741 else if (fs_allow_del_at_zero_count == 1)
742 rise_bit(control_word, eb_s_allow_del_at_zero_count);
743#else
744 if (fs_allow_del_at_zero_count == 0 || fs_allow_del_at_zero_count == 1) {
745#ifdef USE_BIT_FIELDS
746 conparam.s_allow_del_at_zero_count = fs_allow_del_at_zero_count;
747#else
748 s_allow_del_at_zero_count = fs_allow_del_at_zero_count;
749#endif
750 }
751#endif
752 else {
753 mcerr << "ERROR in inline void set_s_allow_del_at_zero_count(int "
754 "fs_allow_del_at_zero_count):\n";
755 mcerr << "s_allow_del_at_zero_count is outside limits, "
756 "s_allow_del_at_zero_count=" << int(fs_allow_del_at_zero_count)
757 << '\n';
758 spexit(mcerr);
759 }
760 }
761
762#ifdef USE_CHAR_GETSETTERS_PARAMETERS
763 inline char get_s_allow_del_at_zero_count(void) const
764#else
765 inline int get_s_allow_del_at_zero_count(void) const
766#endif
767#ifdef USE_BIT_OPERA
768 {
769 if ((control_word & eb_s_allow_del_at_zero_count) != 0)
770 return 1;
771 else
772 return 0;
773 }
774#elif defined(USE_BIT_FIELDS)
775 {
776 return conparam.s_allow_del_at_zero_count;
777 }
778#else
779 { return s_allow_del_at_zero_count; }
780#endif
781
782#endif // for ifdef USE_DELETE_AT_ZERO_COUNT
783
784#ifdef USE_CHAR_GETSETTERS_PARAMETERS
785 inline static void set_s_print_adr_cpp(char fs_print_adr_cpp)
786#else
787 inline static void set_s_print_adr_cpp(int fs_print_adr_cpp)
788#endif
789 {
790 if (fs_print_adr_cpp == 0 || fs_print_adr_cpp == 1) {
791 s_print_adr_cpp = fs_print_adr_cpp;
792 } else {
793 mcerr << "ERROR in inline void set_s_print_adr_cpp(int fs_print_adr_cpp "
794 "):\n";
795 mcerr << "s_print_adr_cpp is outside limits, s_print_adr_cpp="
796 << int(fs_print_adr_cpp) << '\n';
797 spexit(mcerr);
798 }
799 }
800
801#ifdef USE_CHAR_GETSETTERS_PARAMETERS
802 inline static char get_s_print_adr_cpp(void)
803#else
804 inline static int get_s_print_adr_cpp(void)
805#endif
806 {
807 return s_print_adr_cpp;
808 }
809
810#endif // for ifdef USE_GETSETTERS_IN_PASSIVEPTR
811
812 long get_total_number_of_references(void) const;
813
814 private:
815 mutable CountPP_ns::CountPassivePtr* cpp; // reference to counter class
816};
817
819 if (number_of_booked != 0) {
820 mcerr << "Error in CountPassivePtr::~CountPassivePtr():\n"
821 << " number_of_booked != 0, number_of_booked=" << number_of_booked
822 << '\n';
823 if (rpp != NULL)
824 mcerr << (*rpp);
825 else
826 mcerr << "rpp = NULL\n";
827 spexit(mcerr);
828 }
829 if (rpp != NULL) rpp->cpp = NULL;
830}
831
832template <class X>
834 public:
835 friend class RegPassivePtr;
836
837 inline X* get(void) const {
838 if (cpp == NULL) return NULL;
839#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
840
841 if (cpp->get_rpp() == NULL) return NULL;
842#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
843 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
844 if (ptr != temp_ptr) {
845 mcerr << "Error in inline X* PassivePtr::get(void):\n";
846 mcerr << "ptr != temp_ptr\n";
847 spexit(mcerr);
848 }
849#endif
850 return ptr;
851#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
852 else
853 return (X*)(cpp->get_rpp());
854#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
855 }
856
857 // Since the pointer is passive, there is no cloning and pass and put
858 // make the same job.
859 // 03.06.2006: commenting off pass in order to forbid
860 // correct for active pointer but
861 // erroneous for passive pointer statements like ptr.pass(new any_class).
862 // inline void pass(const X* fptr) {put( fptr );}
863
864 inline void put(X* fptr); // unregirster old registered object and
865 // pass fptr to this.
866
867 // void print(std::ostream& file, int l) const
868 // { if(ptr!=NULL) ptr->print(file, l); }
869 inline PassivePtr(void)
870 : cpp(NULL)
872 ,
873 ptr(NULL)
874#endif
875 {
876 }
877 inline PassivePtr(X* fptr) {
878 if (fptr != NULL)
879 cpp = fptr->book();
880 else
881 cpp = NULL;
882#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
883 ptr = fptr;
884#endif
885 }
886 inline PassivePtr(X& fptr) {
887 cpp = fptr.book();
888#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
889 ptr = &fptr;
890#endif
891 }
892
893 inline PassivePtr(const PassivePtr<X>& f);
894
895 inline PassivePtr<X>& operator=(const PassivePtr<X>& f);
896 inline PassivePtr<X>& operator=(X* f);
897
898 // Y may be any derived class from X
899 template <class Y>
901 inline void move_pointer(PassivePtr<X>& f);
902 // get the pointer from f, clear f,
903 // put the pointer to this->ptr
904 // and register it. Thus, the pointer is passed from f to this.
905
906 inline X* operator->(void) const;
907 inline X& operator*(void) const;
908 inline X* getver(void) const;
909#ifdef IMPLICIT_X_STAR
910 inline operator X*(void) const;
911#endif
913 if (cpp == NULL)
914 return 0;
915 else
916 return cpp->get_number_of_booked();
917 }
918 void print(std::ostream& file, int l = 1) const;
919 virtual PassivePtr* copy() const { return new PassivePtr(*this); }
920 virtual ~PassivePtr();
921
922 private:
924#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
925 X* ptr;
926#endif
927};
928
929template <class X>
930template <class Y>
932 : cpp(NULL) {
933 put((f.get()));
934}
935
936template <class X>
937void PassivePtr<X>::print(std::ostream& file, int l) const {
938 Ifile << "PassivePtr<X>:";
939 if (get() == NULL)
940 file << " pointer is NULL, no object, number of ref's is "
941 << get_total_number_of_references() << "\n";
942 else {
943 file << noindent;
944 get()->print(file, l);
945 file << yesindent;
946 indn.n += 2;
947 Ifile << "number of ref's is " << get_total_number_of_references() << '\n';
948 indn.n -= 2;
949 }
950}
951template <class X>
952std::ostream& operator<<(std::ostream& file, const PassivePtr<X>& f) {
953 Ifile << "PassivePtr<X>:";
954 if (f.get() == NULL)
955 file << " pointer is NULL, no object, number of ref's is "
956 << f.get_total_number_of_references() << "\n";
957 else {
958 file << noindent;
959 file << (*f.get());
960 file << yesindent;
961 indn.n += 2;
962 Ifile << "number of ref's is " << f.get_total_number_of_references()
963 << '\n';
964 indn.n -= 2;
965 }
966 return file;
967}
968
969template <class X>
970inline void PassivePtr<X>::put(X* fptr) {
971 // unregister old registered object and pass fptr to this.
972 if (cpp != NULL) {
973#ifdef USE_DELETE_AT_ZERO_COUNT
974 const RegPassivePtr* arptr;
975 if ((arptr = cpp->get_rpp()) != NULL &&
977 arptr->get_s_allow_del_at_zero_count() == 1 &&
978#else
979 arptr->s_allow_del_at_zero_count == 1 &&
980#endif
981 cpp->get_number_of_booked() == 1)
982 delete arptr;
983// fptr should not be part of old object!
984#endif
985 cpp->unbook();
986 if (cpp->get_rpp() == NULL && cpp->get_number_of_booked() == 0)
987 // there is no referred object and no other references
988 delete cpp;
989 }
990 if (fptr != NULL)
991 cpp = fptr->book();
992 else
993 cpp = NULL;
994#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
995 ptr = fptr;
996#endif
997}
998
999template <class X>
1001 if (f.cpp != NULL) {
1002 f.cpp->book();
1003 cpp = f.cpp;
1004 } else
1005 cpp = NULL;
1006#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1007 ptr = f.ptr;
1008#endif
1009}
1010template <class X>
1012 if (this != &f) put(f.get());
1013 return *this;
1014}
1015
1016template <class X>
1018 put(f);
1019 return *this;
1020}
1021
1022template <class X>
1024 if (cpp != NULL) {
1025#ifdef USE_DELETE_AT_ZERO_COUNT
1026 const RegPassivePtr* arptr;
1027 if ((arptr = cpp->get_rpp()) != NULL &&
1029 arptr->get_s_allow_del_at_zero_count() == 1 &&
1030#else
1031 arptr->s_allow_del_at_zero_count == 1 &&
1032#endif
1033 cpp->get_number_of_booked() == 1)
1034 delete arptr;
1035// fptr should not be part of old object!
1036#endif
1037 cpp->unbook();
1038 if (cpp->get_rpp() == NULL && cpp->get_number_of_booked() == 0) {
1039 delete cpp;
1040 cpp = NULL;
1041 }
1042 }
1043 cpp = f.cpp;
1044 if (cpp != NULL) cpp->book();
1045#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1046 ptr = f.ptr;
1047#endif
1048 f.put(NULL);
1049}
1050
1051template <class X>
1052inline X* PassivePtr<X>::operator->(void) const {
1053#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1054#ifdef SKIP_CHECKS_NULL
1055 return ptr;
1056#else
1057 if (cpp == NULL) {
1058 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: cpp == NULL\n";
1059 mcerr << "This means that the pointer is emtpy, "
1060 << "there is no addressed object.\n";
1061 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1062 << '\n';
1063 spexit(mcerr);
1064 }
1065 if (cpp->get_rpp() == NULL) {
1066 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: "
1067 "cpp->get_rpp() == NULL\n";
1068 mcerr << "This means that the pointer is emtpy, "
1069 << "there is no addressed object.\n";
1070 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1071 << '\n';
1072 spexit(mcerr);
1073 }
1074#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
1075 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
1076 if (ptr != temp_ptr) {
1077 mcerr << "Error in inline X* PassivePtr::operator->(void):\n";
1078 mcerr << "ptr != temp_ptr\n";
1079 spexit(mcerr);
1080 }
1081#endif
1082 return ptr;
1083#endif // for ifdef SKIP_CHECKS_NULL
1084#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1085#ifdef SKIP_CHECKS_NULL
1086 const RegPassivePtr* rpp = cpp->get_rpp();
1087#else
1088 if (cpp == NULL) {
1089 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: cpp == NULL\n";
1090 mcerr << "This means that the pointer is emtpy, "
1091 << "there is no addressed object.\n";
1092 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1093 << '\n';
1094 spexit(mcerr);
1095 }
1096 const RegPassivePtr* rpp;
1097 if ((rpp = cpp->get_rpp()) == NULL) {
1098 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: "
1099 "cpp->get_rpp() == NULL\n";
1100 mcerr << "This means that the pointer is emtpy, "
1101 << "there is no addressed object.\n";
1102 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1103 << '\n';
1104 spexit(mcerr);
1105 }
1106#endif
1107 return (X*)(rpp);
1108#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1109}
1110
1111template <class X>
1112inline X& PassivePtr<X>::operator*(void) const {
1113#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1114#ifdef SKIP_CHECKS_NULL
1115 return *ptr;
1116#else
1117 if (cpp == NULL) {
1118 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp == NULL\n";
1119 mcerr << "This means that the pointer is emtpy, "
1120 << "there is no addressed object.\n";
1121 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1122 << '\n';
1123 spexit(mcerr);
1124 }
1125 if (cpp->get_rpp() == NULL) {
1126 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp->get_rpp() "
1127 "== NULL\n";
1128 mcerr << "This means that the pointer is emtpy, "
1129 << "there is no addressed object.\n";
1130 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1131 << '\n';
1132 spexit(mcerr);
1133 }
1134#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
1135 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
1136 if (ptr != temp_ptr) {
1137 mcerr << "Error in inline X& PassivePtr::operator*(void):\n";
1138 mcerr << "ptr != temp_ptr\n";
1139 spexit(mcerr);
1140 }
1141#endif
1142 return *ptr;
1143#endif // for ifdef SKIP_CHECKS_NULL
1144#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1145#ifdef SKIP_CHECKS_NULL
1146 static const RegPassivePtr* rpp = cpp->get_rpp();
1147#else
1148 if (cpp == NULL) {
1149 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp == NULL\n";
1150 mcerr << "This means that the pointer is emtpy, "
1151 << "there is no addressed object.\n";
1152 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1153 << '\n';
1154 spexit(mcerr);
1155 }
1156 static const RegPassivePtr* rpp;
1157 // I have put static here only to avoid
1158 // perhaps erroneous warning which appear
1159 // in compiler : gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
1160 // This is old compiler. At newer ones there is no problems.
1161 // The message is
1162 // AbsPtr.h:997: warning: reference to local variable `rpp' returned
1163 // This is in fact wrong statement, but so as not to make users thinking
1164 // about it, I made this variable static.
1165
1166 if ((rpp = cpp->get_rpp()) == NULL) {
1167 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp->get_rpp() "
1168 "== NULL\n";
1169 mcerr << "This means that the pointer is emtpy, "
1170 << "there is no addressed object.\n";
1171 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1172 << '\n';
1173 spexit(mcerr);
1174 }
1175#endif
1176 return *((X*)(rpp));
1177#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1178}
1179
1180template <class X>
1181inline X* PassivePtr<X>::getver(void) const {
1182#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1183#ifdef SKIP_CHECKS_NULL
1184 return ptr;
1185#else
1186 if (cpp == NULL) {
1187 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp == NULL\n";
1188 mcerr << "This means that the pointer is emtpy, "
1189 << "there is no addressed object.\n";
1190 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1191 << '\n';
1192 spexit(mcerr);
1193 }
1194 if (cpp->get_rpp() == NULL) {
1195 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp->get_rpp() == "
1196 "NULL\n";
1197 mcerr << "This means that the pointer is emtpy, "
1198 << "there is no addressed object.\n";
1199 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1200 << '\n';
1201 spexit(mcerr);
1202 }
1203#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
1204 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
1205 if (ptr != temp_ptr) {
1206 mcerr << "Error in inline X* PassivePtr::getver(void):\n";
1207 mcerr << "ptr != temp_ptr\n";
1208 spexit(mcerr);
1209 }
1210#endif
1211 return ptr;
1212#endif // for ifdef SKIP_CHECKS_NULL
1213#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1214#ifdef SKIP_CHECKS_NULL
1215 const RegPassivePtr* rpp = cpp->get_rpp();
1216#else
1217 if (cpp == NULL) {
1218 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp == NULL\n";
1219 mcerr << "This means that the pointer is emtpy, "
1220 << "there is no addressed object.\n";
1221 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1222 << '\n';
1223 spexit(mcerr);
1224 }
1225 const RegPassivePtr* rpp;
1226 if ((rpp = cpp->get_rpp()) == NULL) {
1227 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp->get_rpp() == "
1228 "NULL\n";
1229 mcerr << "This means that the pointer is emtpy, "
1230 << "there is no addressed object.\n";
1231 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1232 << '\n';
1233 spexit(mcerr);
1234 }
1235#endif
1236 return (X*)(rpp);
1237#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1238}
1239
1240#ifdef IMPLICIT_X_STAR
1241template <class X>
1242inline PassivePtr<X>::operator X*(void) const {
1243#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1244#ifdef SKIP_CHECKS_NULL
1245 return ptr;
1246#else
1247 if (cpp == NULL) {
1248 mcerr << "Error in PassivePtr<X>::operator X*(void) const: cpp == NULL\n";
1249 mcerr << "This means that the pointer is emtpy, "
1250 << "there is no addressed object.\n";
1251 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1252 << '\n';
1253 spexit(mcerr);
1254 }
1255 if (cpp->get_rpp() == NULL) {
1256 mcerr << "Error in X* PassivePtr<X>::operator X*(void) const: "
1257 "cpp->get_rpp() == NULL\n";
1258 mcerr << "This means that the pointer is emtpy, "
1259 << "there is no addressed object.\n";
1260 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1261 << '\n';
1262 spexit(mcerr);
1263 }
1264#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
1265 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
1266 if (ptr != temp_ptr) {
1267 mcerr << "Error in inline X* PassivePtr::operator X*(void):\n";
1268 mcerr << "ptr != temp_ptr\n";
1269 spexit(mcerr);
1270 }
1271#endif
1272 return ptr;
1273#endif // for ifdef SKIP_CHECKS_NULL
1274#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1275#ifdef SKIP_CHECKS_NULL
1276 const RegPassivePtr* rpp = cpp->get_rpp();
1277#else
1278 if (cpp == NULL) {
1279 mcerr
1280 << "Error in X* PassivePtr<X>::operator X*(void) const: cpp == NULL\n";
1281 mcerr << "This means that the pointer is emtpy, "
1282 << "there is no addressed object.\n";
1283 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1284 << '\n';
1285 spexit(mcerr);
1286 }
1287 const RegPassivePtr* rpp;
1288 if ((rpp = cpp->get_rpp()) == NULL) {
1289 mcerr << "Error in X* PassivePtr<X>::operator X*(void) const: "
1290 "cpp->get_rpp() == NULL\n";
1291 mcerr << "This means that the pointer is emtpy, "
1292 << "there is no addressed object.\n";
1293 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1294 << '\n';
1295 spexit(mcerr);
1296 }
1297#endif
1298 return (X*)(rpp);
1299#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1300}
1301#endif
1302template <class X>
1303inline int operator==(const PassivePtr<X>& f1, const PassivePtr<X>& f2) {
1304 // comparison of addresses, so it mimics regular pointers
1305 return f1.get() == f2.get();
1306}
1307
1308template <class X>
1310 if (cpp) {
1311#ifdef USE_DELETE_AT_ZERO_COUNT
1312 const RegPassivePtr* arptr;
1313 if ((arptr = cpp->get_rpp()) != NULL &&
1315 arptr->get_s_allow_del_at_zero_count() == 1 &&
1316#else
1317 arptr->s_allow_del_at_zero_count == 1 &&
1318#endif
1319 cpp->get_number_of_booked() == 1)
1320 delete arptr;
1321#endif
1322 cpp->unbook();
1323 // mcout<<"PassivePtr<X>::~PassivePtr(): &ptr="<<&ptr<<" *ptr="<<*ptr<<'\n';
1324 if (cpp->get_rpp() == NULL && cpp->get_number_of_booked() == 0) {
1325 delete cpp;
1326 cpp = NULL;
1327 }
1328 }
1329}
1330
1331template <class X>
1333 // necessary for std::set
1334 return f1.get() < f2.get();
1335}
1336
1337}
1338
1339#endif
#define USE_PRIVATE_PARAM_IN_PASSIVEPTR
Definition: AbsPtr.h:73
#define USE_DOUBLE_PTR_IN_PASSIVEPTR
Definition: AbsPtr.h:23
#define USE_DELETE_AT_ZERO_COUNT
Definition: AbsPtr.h:33
#define spexit(stream)
Definition: FunNameStack.h:256
Counter of protected pointers.
Definition: AbsPtr.h:201
void change_rpp(const RegPassivePtr *frpp)
Definition: AbsPtr.h:211
const RegPassivePtr * get_rpp(void)
Definition: AbsPtr.h:210
CountPassivePtr(const RegPassivePtr *frpp)
Definition: AbsPtr.h:203
PassivePtr(X &fptr)
Definition: AbsPtr.h:886
X * operator->(void) const
Definition: AbsPtr.h:1052
X * getver(void) const
Definition: AbsPtr.h:1181
X * get(void) const
Definition: AbsPtr.h:837
PassivePtr(void)
Definition: AbsPtr.h:869
void move_pointer(PassivePtr< X > &f)
Definition: AbsPtr.h:1023
long get_total_number_of_references(void) const
Definition: AbsPtr.h:912
void put(X *fptr)
Definition: AbsPtr.h:970
PassivePtr< X > & operator=(const PassivePtr< X > &f)
Definition: AbsPtr.h:1011
PassivePtr(X *fptr)
Definition: AbsPtr.h:877
void print(std::ostream &file, int l=1) const
Definition: AbsPtr.h:937
X & operator*(void) const
Definition: AbsPtr.h:1112
virtual ~PassivePtr()
Definition: AbsPtr.h:1309
virtual PassivePtr * copy() const
Definition: AbsPtr.h:919
static char get_s_ban_del_ignore(void)
Definition: AbsPtr.h:604
void clear_pointers(void) const
Definition: AbsPtr.h:400
static void set_s_ban_del_ignore(char fs_ban_del_ignore)
Definition: AbsPtr.h:587
static void set_s_print_adr_cpp(char fs_print_adr_cpp)
Definition: AbsPtr.h:785
virtual ~RegPassivePtr()
Definition: AbsPtr.cpp:231
virtual void print(std::ostream &file, int l=1) const
Definition: AbsPtr.cpp:152
static char get_s_print_adr_cpp(void)
Definition: AbsPtr.h:802
RegPassivePtr & operator=(const RegPassivePtr &f)
Definition: AbsPtr.cpp:60
char get_s_allow_del_at_zero_count(void) const
Definition: AbsPtr.h:763
void set_s_ban_cop(char fs_ban_cop)
Definition: AbsPtr.h:673
RegPassivePtr(char fs_ban_del, char fs_ban_sub, char fs_ban_cop=0)
Definition: AbsPtr.h:363
void set_s_allow_del_at_zero_count(char fs_allow_del_at_zero_count)
Definition: AbsPtr.h:733
char get_s_ban_sub(void) const
Definition: AbsPtr.h:647
virtual RegPassivePtr * copy() const
Definition: AbsPtr.h:405
friend std::ostream & operator<<(std::ostream &file, const RegPassivePtr &f)
Definition: AbsPtr.cpp:156
void set_s_ban_sub(char fs_ban_sub)
Definition: AbsPtr.h:613
RegPassivePtr(void)
Definition: AbsPtr.h:346
char get_s_ban_cop(void) const
Definition: AbsPtr.h:707
void set_s_ban_del(char fs_ban_del)
Definition: AbsPtr.h:539
char get_s_ban_del(void) const
Definition: AbsPtr.h:567
CountPP_ns::CountPassivePtr * book(void) const
Definition: AbsPtr.h:394
long get_total_number_of_references(void) const
Definition: AbsPtr.cpp:222
static X * copy(const X *f)
Definition: AbsPtr.h:132
Definition: BGMesh.cpp:6
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:17
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
Pilfer
Definition: AbsPtr.h:184
@ steal
Definition: AbsPtr.h:185
Clone
Definition: AbsPtr.h:187
@ do_clone
Definition: AbsPtr.h:188
int operator==(const circumf &f1, const circumf &f2)
Definition: circumf.cpp:34
DoubleAc operator*(const DoubleAc &f1, const DoubleAc &f2)
Definition: DoubleAc.h:523
Pass
Definition: AbsPtr.h:190
@ dont_clone
Definition: AbsPtr.h:191
indentation indn
Definition: prstream.cpp:15
bool operator<(PassivePtr< X > f1, PassivePtr< X > f2)
Definition: AbsPtr.h:1332
std::ostream & yesindent(std::ostream &f)
Definition: prstream.cpp:21
#define mcout
Definition: prstream.h:126
#define Ifile
Definition: prstream.h:195
#define mcerr
Definition: prstream.h:128