Garfield++ 5.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 {
186};
187enum Clone {
189};
190enum Pass {
192};
193
194class RegPassivePtr;
195
196namespace CountPP_ns {
197/// Counter of protected pointers.
199 public:
200 CountPassivePtr(const RegPassivePtr* frpp) : rpp(frpp), number_of_booked(0) {}
201
202 // In the following I will use the word book instead of register,
203 // because register seems to be interfered with some computer definition
204 inline void book(void);
205 inline void unbook(void);
206 inline long get_number_of_booked(void) { return number_of_booked; }
207 inline const RegPassivePtr* get_rpp(void) { return rpp; }
208 inline void change_rpp(const RegPassivePtr* frpp) { rpp = frpp; }
209 inline ~CountPassivePtr(); // here to delete reference from RegPassivePtr
210 private:
211 const RegPassivePtr* rpp;
212 // const is necessary here to make possible booking of RegPassivePtr
213 // by a function which is declared as const.
214
215 long number_of_booked; // the counter of pointers
216};
217
218inline void CountPassivePtr::book(void) {
219 if (number_of_booked > LONG_MAX - 1) {
220 mcerr << "Error in CountPassivePtr::book(void):\n"
221 << " too much booked counters, number_of_booked > LONG_MAX-1, "
222 "number_of_booked=" << number_of_booked << '\n';
223 spexit(mcerr);
224 }
225 number_of_booked++;
226}
227
228inline void CountPassivePtr::unbook(void) {
229 if (number_of_booked < 1) {
230 mcerr << "Error in CountPassivePtr::unbook(void):\n"
231 << " number_of_booked < 1, number_of_booked=" << number_of_booked
232 << '\n';
233 spexit(mcerr);
234 }
235 number_of_booked--;
236}
237}
238
239#ifdef USE_BIT_OPERA
240
241const unsigned char eb_s_ban_del = 1;
242const unsigned char eb_s_ban_sub1 = 2;
243const unsigned char eb_s_ban_sub2 = 4;
244const unsigned char eb_s_ban_cop1 = 8;
245const unsigned char eb_s_ban_cop2 = 16;
246#ifdef USE_DELETE_AT_ZERO_COUNT
247const unsigned char eb_s_allow_del_at_zero_count = 32;
248#endif
249#endif
250
252 public:
254// used for making cpp NULL when CountPassivePtr
255// is destructed
256
257#ifdef USE_BIT_OPERA
258 private:
259 inline static void clear_bit(unsigned char& cw, unsigned char b) {
260 if ((cw & b) != 0) {
261 cw ^= b;
262 }
263 }
264 inline static void rise_bit(unsigned char& cw, unsigned char b) { cw |= b; }
265
266 public:
267// To define auxiliary class, used only in the following case:
268#elif defined(USE_BIT_FIELDS)
269 class ControlParam {
270 public:
271 unsigned int s_ban_del : 1; // see below for comments
272 unsigned int s_ban_sub : 2;
273 unsigned int s_ban_cop : 2;
274#ifdef USE_DELETE_AT_ZERO_COUNT
275 unsigned int s_allow_del_at_zero_count : 1;
276#endif
277 ControlParam(void)
278 : s_ban_del(0),
279 s_ban_sub(0),
280 s_ban_cop(0)
282 ,
283 s_allow_del_at_zero_count(0)
284#endif
285 {
286 }
287#ifdef USE_CHAR_GETSETTERS_PARAMETERS
288 ControlParam(char fs_ban_del, char fs_ban_sub, char fs_ban_cop = 0
290 ,
291 char fs_allow_del_at_zero_count = 0
292#endif
293 )
294 :
295#else
296 ControlParam(int fs_ban_del, int fs_ban_sub, int fs_ban_cop = 0
298 ,
299 int fs_allow_del_at_zero_count = 0
300#endif
301 )
302 :
303#endif
304 s_ban_del(fs_ban_del),
305 s_ban_sub(fs_ban_sub),
306 s_ban_cop(fs_ban_cop)
308 ,
309 s_allow_del_at_zero_count(fs_allow_del_at_zero_count)
310#endif
311 {
312 if (!(fs_ban_del == 0 || fs_ban_del == 1)) {
313 mcerr << "ERROR in ControlParam::ControlParam(...)\n";
314 mcerr << "s_ban_del is outside limits, s_ban_del=" << fs_ban_del
315 << '\n';
316 spexit(mcerr);
317 }
318 if (fs_ban_sub < 0 || fs_ban_sub > 2) {
319 mcerr << "ERROR in ControlParam::ControlParam(...):\n";
320 mcerr << "s_ban_sub is outside limits, s_ban_sub=" << fs_ban_sub
321 << '\n';
322 spexit(mcerr);
323 }
324 if (fs_ban_cop < 0 || fs_ban_cop > 2) {
325 mcerr << "ERROR in ControlParam::ControlParam(...):\n";
326 mcerr << "s_ban_cop is outside limits, s_ban_cop=" << fs_ban_cop
327 << '\n';
328 spexit(mcerr);
329 }
330#ifdef USE_DELETE_AT_ZERO_COUNT
331 if (!(s_allow_del_at_zero_count == 0 || s_allow_del_at_zero_count == 1)) {
332 mcerr << "ERROR in ControlParam::ControlParam(...)\n";
333 mcerr << "s_allow_del_at_zero_count is outside limits, "
334 "s_allow_del_at_zero_count=" << fs_allow_del_at_zero_count
335 << '\n';
336 spexit(mcerr);
337 }
338#endif
339 }
340 }; // the total 6 bits
341#endif // ifdef USE_BIT_FIELDS
342
343 inline RegPassivePtr(void)
344 :
345#ifdef USE_BIT_OPERA
346 control_word(0),
347#elif defined USE_BIT_FIELDS
348 conparam(),
349#else
350 s_ban_del(0),
351 s_ban_sub(0),
352 s_ban_cop(0),
354 s_allow_del_at_zero_count(0),
355#endif
356#endif
357 cpp(NULL) {
358 }
359#ifdef USE_CHAR_GETSETTERS_PARAMETERS
360 inline RegPassivePtr(char fs_ban_del, char fs_ban_sub, char fs_ban_cop = 0)
361 :
362#else
363 inline RegPassivePtr(int fs_ban_del, int fs_ban_sub, int fs_ban_cop = 0)
364 :
365#endif
366#ifdef USE_BIT_OPERA
367 control_word(0),
368#elif defined(USE_BIT_FIELDS)
369 conparam(fs_ban_del, fs_ban_sub, fs_ban_cop),
370#else
371 s_ban_del(fs_ban_del), s_ban_sub(fs_ban_sub), s_ban_cop(fs_ban_cop),
373 s_allow_del_at_zero_count(0),
374#endif
375#endif
376 cpp(NULL) {
377#ifdef USE_BIT_OPERA
378 set_s_ban_del(fs_ban_del);
379 set_s_ban_sub(fs_ban_sub);
380 set_s_ban_cop(fs_ban_cop);
381#endif
382 }
383
385
387 // Copies s_ban_del and s_ban_sub
388 // Also calls clear_pointers if s_ban_sub==1 or
389 // spexit() if s_ban_sub==2 and the alist_of_prot_pointers is not empty.
390
391 inline CountPP_ns::CountPassivePtr* book(void) const {
392 if (!cpp) cpp = new CountPP_ns::CountPassivePtr(this);
393 cpp->book();
394 return cpp;
395 }
396
397 inline void clear_pointers(void) const {
398 // all pointers addressing this are cleared;
399 if (cpp) cpp->change_rpp(NULL);
400 }
401
402 virtual RegPassivePtr* copy() const { return new RegPassivePtr(*this); }
403
404 virtual ~RegPassivePtr();
405 // If there are pointers addressed this object and s_ban_del = 1,
406 // the program is terminated with output message to mcerr.
407 // Otherwise (normal behaviour) the references are cleared.
408
409 virtual void print(std::ostream& file, int l = 1) const;
410 friend std::ostream& operator<<(std::ostream& file, const RegPassivePtr& f);
411
412// Three parameters controlling behaviour of pointee object at
413// its deletion and substitution.
414// They are included for the sake of flexibility and
415// they are necessary very rarely. Normally they are not used.
416// If needed, you can set them though constructors,
417// or change responsibly directly.
418// Obviously, this is a temporary design.
419// It needs then to pack all these small numbers in one computer word.
420
421#ifdef USE_BIT_OPERA
422 private:
423 unsigned char control_word;
424
425 public:
426#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
427 private:
428#endif
429 static int s_ban_del_ignore;
430 static int s_print_adr_cpp;
431#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
432 public:
433#endif
434
435#elif defined(USE_BIT_FIELDS)
436 private:
437 ControlParam conparam;
438
439 public:
440#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
441 private:
442#endif
443 static int s_ban_del_ignore;
444 static int s_print_adr_cpp;
445#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
446 public:
447#endif
448
449#else // for elif defined( USE_BIT_FIELDS )
450
451#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
452 private:
453#endif
454#ifdef USE_CHAR_CONTROL_VARIABLES
455 char s_ban_del;
456#else
457 int s_ban_del;
458#endif
459 // sign whether this object can (0) or cannot (1)
460 // be deleted if it is addressed.
461 // Normally it can. When it happens, the pointers addressing this object
462 // are cleared and set to NULL.
463 // If user needs to find where he deletes referenced object,
464 // he may assign this variable to 1
465
466 static int s_ban_del_ignore;
467// auxiliary variable with default value 0,
468// meaning that s_ban_del is not ignored.
469// In the case of value 1 s_ban_del is ignored, whatever it is.
470// It is used in RegPassivePtr::~RegPassivePtr() to avoid loops at exiting
471// after the fist deletion of referenced object at s_ban_del = 1 is found.
472
473#ifdef USE_CHAR_CONTROL_VARIABLES
474 char s_ban_sub;
475#else
476 int s_ban_sub;
477#endif
478// sign controlling substitution of addressed object:
479// 0 - it can be substituted and the pointers addressing "this" preserve
480// their values (normal default case).
481// 1 - it can be substituted, but the pointers will be assigned NULL.
482// In the case of self-assignment and valid pointers to "this"
483// the run-time error is triggered, because otherwise either
484// the pointers to copied object would not be preserved or
485// the pointers to "this" would not be cleared - principal contradiction.
486// 2 - it cannot be substituted, if there are pointers to "this",
487// attempt to substitute in this case triggers error.
488// In the case of absence of pointers to this it is substituted.
489// Note: if the substitution is allowed,
490// s_ban_del, s_ban_sub, and s_ban_cop are themselves substituted -
491// arbitrary decision, perhaps correct.
492
493#ifdef USE_CHAR_CONTROL_VARIABLES
494 char s_ban_cop;
495#else
496 int s_ban_cop;
497#endif
498// sign controlling copying addressed object
499// 0 - it can always be copied
500// 1 - it can be copied only if there are no references,
501// otherwise it will be runtime error.
502// 2 - it can never be copied, but it is anyway runtime error,
503// the compiler cannot detect it.
504
505#ifdef USE_DELETE_AT_ZERO_COUNT
506#ifdef USE_CHAR_CONTROL_VARIABLES
507 char s_allow_del_at_zero_count;
508#else
509 int s_allow_del_at_zero_count;
510#endif
511// concession to people who likes shared pointers.
512// Instructs PassivePtr::~PassivePtr to delete the object if that
513// pointer is last. Think twice before use.
514// It basically violates the ideoma of reference to independent object.
515// Also in the case of circular references the program can fall into loop
516// of destructors, which is not the case for regular passive pointers.
517#endif
518
519 static int s_print_adr_cpp;
520// signature to print the address of cpp in operator<<
521// by default it is 0 and address is not printed,
522// but only the remark that it is NULL or not NULL is printed.
523// It is good for making such output listings which do not depend
524// on computer and can be automatically compared.
525// But in the case of some deep debug the user can make them printed
526// if he assigns s_print_adr_cpp = 1.
527#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
528 public:
529#endif
530
531#endif // for elif defined( USE_BIT_FIELDS )
532
533#ifdef USE_GETSETTERS_IN_PASSIVEPTR
534 public:
535#ifdef USE_CHAR_GETSETTERS_PARAMETERS
536 inline void set_s_ban_del(char fs_ban_del)
537#else
538 inline void set_s_ban_del(int fs_ban_del)
539#endif
540 {
541#ifdef USE_BIT_OPERA
542 if (fs_ban_del == 0)
543 clear_bit(control_word, eb_s_ban_del);
544 else if (fs_ban_del == 1)
545 rise_bit(control_word, eb_s_ban_del);
546#else
547 if (fs_ban_del == 0 || fs_ban_del == 1) {
548#ifdef USE_BIT_FIELDS
549 conparam.s_ban_del = fs_ban_del;
550#else
551 s_ban_del = fs_ban_del;
552#endif
553 }
554#endif
555 else {
556 mcerr << "ERROR in inline void set_s_ban_del(int fs_ban_del):\n";
557 mcerr << "s_ban_del is outside limits, s_ban_del=" << int(fs_ban_del)
558 << '\n';
559 spexit(mcerr);
560 }
561 }
562
563#ifdef USE_CHAR_GETSETTERS_PARAMETERS
564 inline char get_s_ban_del(void) const
565#else
566 inline int get_s_ban_del(void) const
567#endif
568#ifdef USE_BIT_OPERA
569 {
570 if ((control_word & eb_s_ban_del) != 0)
571 return 1;
572 else
573 return 0;
574 }
575#elif defined(USE_BIT_FIELDS)
576 {
577 return conparam.s_ban_del;
578 }
579#else
580 { return s_ban_del; }
581#endif
582
583#ifdef USE_CHAR_GETSETTERS_PARAMETERS
584 inline static void set_s_ban_del_ignore(char fs_ban_del_ignore)
585#else
586 inline static void set_s_ban_del_ignore(int fs_ban_del_ignore)
587#endif
588 {
589 if (fs_ban_del_ignore == 0 || fs_ban_del_ignore == 1) {
590 s_ban_del_ignore = fs_ban_del_ignore;
591 } else {
592 mcerr << "ERROR in inline void set_s_ban_del_ignore(int "
593 "fs_ban_del_ignore ):\n";
594 mcerr << "s_ban_del_ignore is outside limits, s_ban_del_ignore="
595 << int(fs_ban_del_ignore) << '\n';
596 spexit(mcerr);
597 }
598 }
599
600#ifdef USE_CHAR_GETSETTERS_PARAMETERS
601 inline static char get_s_ban_del_ignore(void)
602#else
603 inline static int get_s_ban_del_ignore(void)
604#endif
605 {
606 return s_ban_del_ignore;
607 }
608
609#ifdef USE_CHAR_GETSETTERS_PARAMETERS
610 inline void set_s_ban_sub(char fs_ban_sub)
611#else
612 inline void set_s_ban_sub(int fs_ban_sub)
613#endif
614 {
615#ifdef USE_BIT_OPERA
616 if (fs_ban_sub == 0) {
617 clear_bit(control_word, eb_s_ban_sub1);
618 clear_bit(control_word, eb_s_ban_sub2);
619 } else if (fs_ban_sub == 1) {
620 rise_bit(control_word, eb_s_ban_sub1);
621 clear_bit(control_word, eb_s_ban_sub2);
622 } else if (fs_ban_sub == 2) {
623 clear_bit(control_word, eb_s_ban_sub1);
624 rise_bit(control_word, eb_s_ban_sub2);
625 }
626#else
627 if (fs_ban_sub >= 0 && fs_ban_sub <= 2) {
628#ifdef USE_BIT_FIELDS
629 conparam.s_ban_sub = fs_ban_sub;
630#else
631 s_ban_sub = fs_ban_sub;
632#endif
633 }
634#endif
635 else {
636 mcerr << "ERROR in inline void set_s_ban_sub(int fs_ban_sub):\n";
637 mcerr << "s_ban_sub is outside limits, s_ban_sub=" << int(fs_ban_sub)
638 << '\n';
639 spexit(mcerr);
640 }
641 }
642
643#ifdef USE_CHAR_GETSETTERS_PARAMETERS
644 inline char get_s_ban_sub(void) const
645#else
646 inline int get_s_ban_sub(void) const
647#endif
648#ifdef USE_BIT_OPERA
649 {
650 if ((control_word & eb_s_ban_sub2) == 0) {
651 if ((control_word & eb_s_ban_sub1) == 0)
652 return 0;
653 else
654 return 1;
655 } else {
656 // Iprintn(mcout, (control_word & eb_s_ban_sub1) );
657 // Iprintn(mcout, (control_word & eb_s_ban_sub2) );
658 return 2;
659 }
660 }
661#elif defined(USE_BIT_FIELDS)
662 {
663 return conparam.s_ban_sub;
664 }
665#else
666 { return s_ban_sub; }
667#endif
668
669#ifdef USE_CHAR_GETSETTERS_PARAMETERS
670 inline void set_s_ban_cop(char fs_ban_cop)
671#else
672 inline void set_s_ban_cop(int fs_ban_cop)
673#endif
674 {
675#ifdef USE_BIT_OPERA
676 if (fs_ban_cop == 0) {
677 clear_bit(control_word, eb_s_ban_cop1);
678 clear_bit(control_word, eb_s_ban_cop2);
679 } else if (fs_ban_cop == 1) {
680 rise_bit(control_word, eb_s_ban_cop1);
681 clear_bit(control_word, eb_s_ban_cop2);
682 } else if (fs_ban_cop == 2) {
683 clear_bit(control_word, eb_s_ban_cop1);
684 rise_bit(control_word, eb_s_ban_cop2);
685 }
686#else
687 if (fs_ban_cop >= 0 && fs_ban_cop <= 2) {
688#ifdef USE_BIT_FIELDS
689 conparam.s_ban_cop = fs_ban_cop;
690#else
691 s_ban_cop = fs_ban_cop;
692#endif
693 }
694#endif
695 else {
696 mcerr << "ERROR in inline void set_s_ban_cop(int fs_ban_cop):\n";
697 mcerr << "s_ban_cop is outside limits, s_ban_cop=" << int(fs_ban_cop)
698 << '\n';
699 spexit(mcerr);
700 }
701 }
702
703#ifdef USE_CHAR_GETSETTERS_PARAMETERS
704 inline char get_s_ban_cop(void) const
705#else
706 inline int get_s_ban_cop(void) const
707#endif
708#ifdef USE_BIT_OPERA
709 {
710 if ((control_word & eb_s_ban_cop2) == 0) {
711 if ((control_word & eb_s_ban_cop1) == 0)
712 return 0;
713 else
714 return 1;
715 } else {
716 return 2;
717 }
718 }
719#elif defined USE_BIT_FIELDS
720 {
721 return conparam.s_ban_cop;
722 }
723#else
724 { return s_ban_cop; }
725#endif
726
727#ifdef USE_DELETE_AT_ZERO_COUNT
728
729#ifdef USE_CHAR_GETSETTERS_PARAMETERS
730 inline void set_s_allow_del_at_zero_count(char fs_allow_del_at_zero_count)
731#else
732 inline void set_s_allow_del_at_zero_count(int fs_allow_del_at_zero_count)
733#endif
734 {
735#ifdef USE_BIT_OPERA
736 if (fs_allow_del_at_zero_count == 0)
737 clear_bit(control_word, eb_s_allow_del_at_zero_count);
738 else if (fs_allow_del_at_zero_count == 1)
739 rise_bit(control_word, eb_s_allow_del_at_zero_count);
740#else
741 if (fs_allow_del_at_zero_count == 0 || fs_allow_del_at_zero_count == 1) {
742#ifdef USE_BIT_FIELDS
743 conparam.s_allow_del_at_zero_count = fs_allow_del_at_zero_count;
744#else
745 s_allow_del_at_zero_count = fs_allow_del_at_zero_count;
746#endif
747 }
748#endif
749 else {
750 mcerr << "ERROR in inline void set_s_allow_del_at_zero_count(int "
751 "fs_allow_del_at_zero_count):\n";
752 mcerr << "s_allow_del_at_zero_count is outside limits, "
753 "s_allow_del_at_zero_count=" << int(fs_allow_del_at_zero_count)
754 << '\n';
755 spexit(mcerr);
756 }
757 }
758
759#ifdef USE_CHAR_GETSETTERS_PARAMETERS
760 inline char get_s_allow_del_at_zero_count(void) const
761#else
762 inline int get_s_allow_del_at_zero_count(void) const
763#endif
764#ifdef USE_BIT_OPERA
765 {
766 if ((control_word & eb_s_allow_del_at_zero_count) != 0)
767 return 1;
768 else
769 return 0;
770 }
771#elif defined(USE_BIT_FIELDS)
772 {
773 return conparam.s_allow_del_at_zero_count;
774 }
775#else
776 { return s_allow_del_at_zero_count; }
777#endif
778
779#endif // for ifdef USE_DELETE_AT_ZERO_COUNT
780
781#ifdef USE_CHAR_GETSETTERS_PARAMETERS
782 inline static void set_s_print_adr_cpp(char fs_print_adr_cpp)
783#else
784 inline static void set_s_print_adr_cpp(int fs_print_adr_cpp)
785#endif
786 {
787 if (fs_print_adr_cpp == 0 || fs_print_adr_cpp == 1) {
788 s_print_adr_cpp = fs_print_adr_cpp;
789 } else {
790 mcerr << "ERROR in inline void set_s_print_adr_cpp(int fs_print_adr_cpp "
791 "):\n";
792 mcerr << "s_print_adr_cpp is outside limits, s_print_adr_cpp="
793 << int(fs_print_adr_cpp) << '\n';
794 spexit(mcerr);
795 }
796 }
797
798#ifdef USE_CHAR_GETSETTERS_PARAMETERS
799 inline static char get_s_print_adr_cpp(void)
800#else
801 inline static int get_s_print_adr_cpp(void)
802#endif
803 {
804 return s_print_adr_cpp;
805 }
806
807#endif // for ifdef USE_GETSETTERS_IN_PASSIVEPTR
808
809 long get_total_number_of_references(void) const;
810
811 private:
812 mutable CountPP_ns::CountPassivePtr* cpp; // reference to counter class
813};
814
816 if (number_of_booked != 0) {
817 mcerr << "Error in CountPassivePtr::~CountPassivePtr():\n"
818 << " number_of_booked != 0, number_of_booked=" << number_of_booked
819 << '\n';
820 if (rpp != NULL)
821 mcerr << (*rpp);
822 else
823 mcerr << "rpp = NULL\n";
824 spexit(mcerr);
825 }
826 if (rpp != NULL) rpp->cpp = NULL;
827}
828
829}
830
831#endif
#define USE_DELETE_AT_ZERO_COUNT
Definition AbsPtr.h:33
#define spexit(stream)
Counter of protected pointers.
Definition AbsPtr.h:198
void change_rpp(const RegPassivePtr *frpp)
Definition AbsPtr.h:208
const RegPassivePtr * get_rpp(void)
Definition AbsPtr.h:207
CountPassivePtr(const RegPassivePtr *frpp)
Definition AbsPtr.h:200
static char get_s_ban_del_ignore(void)
Definition AbsPtr.h:601
void clear_pointers(void) const
Definition AbsPtr.h:397
static void set_s_ban_del_ignore(char fs_ban_del_ignore)
Definition AbsPtr.h:584
static void set_s_print_adr_cpp(char fs_print_adr_cpp)
Definition AbsPtr.h:782
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:799
RegPassivePtr & operator=(const RegPassivePtr &f)
Definition AbsPtr.cpp:60
char get_s_allow_del_at_zero_count(void) const
Definition AbsPtr.h:760
void set_s_ban_cop(char fs_ban_cop)
Definition AbsPtr.h:670
RegPassivePtr(char fs_ban_del, char fs_ban_sub, char fs_ban_cop=0)
Definition AbsPtr.h:360
void set_s_allow_del_at_zero_count(char fs_allow_del_at_zero_count)
Definition AbsPtr.h:730
char get_s_ban_sub(void) const
Definition AbsPtr.h:644
virtual RegPassivePtr * copy() const
Definition AbsPtr.h:402
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:610
char get_s_ban_cop(void) const
Definition AbsPtr.h:704
void set_s_ban_del(char fs_ban_del)
Definition AbsPtr.h:536
char get_s_ban_del(void) const
Definition AbsPtr.h:564
CountPP_ns::CountPassivePtr * book(void) const
Definition AbsPtr.h:391
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
Pilfer
Definition AbsPtr.h:184
@ steal
Definition AbsPtr.h:185
Clone
Definition AbsPtr.h:187
@ do_clone
Definition AbsPtr.h:188
Pass
Definition AbsPtr.h:190
@ dont_clone
Definition AbsPtr.h:191
#define mcout
Definition prstream.h:126
#define mcerr
Definition prstream.h:128