Garfield++ v1r0
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>
19//#include "wcpplib/util/List.h"
22//#include "math/minmax.h"
24
25//#define USE_REPLACE_ALLOC
26
27#ifdef USE_REPLACE_ALLOC
29#endif
30
31//#define IMPLICIT_X_STAR
32//#define INCLUDE_ActivePtrWI
33
34//#define USE_DYNCAST_IN_PASSIVEPTR // (possibly obsolete, see below) default
35// option used to provide possibility of making base class RegPassivePtr
36// virtual.
37// In order to cast from base RegPassivePtr to the real pointer type
38// we need to use dynamic cast, which makes the referencing
39// little bit slower.
40
41#define USE_DOUBLE_PTR_IN_PASSIVEPTR //
42// New option. Makes passive ptr keeping address of counter and address
43// of object. This allow to avoid dynamic casts while still allowing
44// the class RegPassivePtr be virtual.
45//#define USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
46// for debug of the option above. At each access it checks
47// that the object address in ptr is equal to the address
48// restored from the counter.
49
50#define USE_DELETE_AT_ZERO_COUNT // to switch on option
51 // for emulation of shared pointer.
52// But it only gives possibility to emulate it by the passive pointer,
53// but does not make passive pointer equival to shared one.
54// You should assign 1 to s_allow_del_at_zero_count of each particular object,
55// which should be deleted.
56
57//#define SKIP_CHECKS_NULL // skip checks of smart pointers
58// (that they are not NULL) at
59// dereferencing via getver(), *, and ->.
60// In all cases at the normal execution the object should not be NULL
61// for these operators.
62// Skiping checks, we assume that they are not NULL
63// (and risk to have bad undetected errors at the execution time).
64// This option is incerted due to curiosity about for how much
65// the checks delay the program.
66// For Monte Carlo simulation the result was a few percent.
67// Therefore the use (uncommenting ) of this macro for the purposes
68// other than similar curiosity does NOT have any sence.
69
70// To be addressed by active pointer an object of a class
71// should have functions
72// copy() which clones the object and returns new address, and may have
73// print() which prints it to a stream.
74// The others (the class name, its bases etc.) is not matter.
75// However sometimes it is convenient to derive such a class from AbsCont -
76// an abstract class, in which the function copy is declared pure
77// and the function print does nothing.
78// The copy() is declared pure just to insure that the user does not
79// forget to define it in derivative.
80// Its body is approximately the same and consists of two lines.
81
82#define COPY_TYPE_CHECK // make execution longer, but allows
83// to detect missings of copy functions in classes referred by
84// active pointers.
85
86//#define COPY_RETURNS_COMMON_BASE // to bypass bug in Linux compiler
87/*
88sorry, not implemented:
89adjusting pointers for covariant returns.
90
91This happens when copy function returns always the type of
92the class to which it belongs.
93
94g++ -v:
95Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
96gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-113)
97The same problem was detected at Red Hat Linux 8.0.
98At Scientific Linux 4.1 there is no such problem (at 4.5 - too).
99So this marco can be either commented off or commented on.
100I prefere comment it off when possible.
101Perhaps it is most convenient to declare this macro in environment variables
102which are invoked at compilation.
103The detailed explanation is following:
104
105You might derive a sequence of classes from a base and
106return this base. But if you have two such sequences derived from
107different bases and need to unifiy them in a common derivative,
108you meet the problem of covariant returns.
109In order the both base classes can be addressed by active pointer,
110the both should have functions "BaseClassName* copy(void) const".
111Their declarations differ only by return value.
112The old compilers cannot distinguish them correctly and produce
113this error.
114It is possible to bypass it by giving different names of copy function
115in the first and the second base. But then to assure the correct functioning
116of the program you have to define the both functions in derived class.
117Also you will need to supply their names to active pointer.
118The program then gets difficult to understand.
119
120It is possible, in principle, to make the copy function returning void
121and to convert void* to base type in CopyDefinition.
122But if the base class is not the first base from which this type is derived,
123such a scheme would not work correctly, although at compilation
124the error would not be found.
125
126It seems that the best solution is temporaty one consisting in derivation
127of all necessary classes which are handled by active pointers
128from a common base class with a virtual function, returning from copy
129function the pointer to this base and its conversion to real type
130by dynamic cast. All statements should be implemented through macro definitions
131by such a way that they should ne annuled as soon as the covariant
132return types are imtroduced in g++ compilers (expected in version 3.4).
133*/
134//#define DEBUG_ACTIVEPTR // print some messages at running ActivePtr
135// components
136// The pilfer constructor and the pilfer function is sometimes not resolved
137// (i.e. at Scientific Linux 4.1,
138// on the contrary at Windows Vis. Studio it is resolved always)
139// if they are declared with non-const argument.
140// The solution is declaration them with const and class fields as mutable
141// as follows:
142#define PILF_CONST const
143#define PILF_MUTABLE mutable
144// Otherwise leave these macros empty
145//#define PILF_CONST
146//#define PILF_MUTABLE
147// The mutable fields do not seem to be harmful, except if
148// a user wants to add a new member functions. In the latter case
149// it might be useful to compile a program which does not use pilfers
150// with non-const arguments and without muables in order to verify
151// whether new functions erroneously change their constant arguments.
152// Then, mutables should be again switched on.
153// Note: these desclarations are repeated in AbsArr.h and AbsList,
154// see it for details.
155
156#define USE_GETSETTERS_IN_PASSIVEPTR // new option allowing to use
157// getters and setters in the passive pointer
158// instead or in addition to direct access to auxiliary parameters.
159// It allows to control correctness of input values and also to use
160// fields if the next option is switched on. But note that using fields
161// can increase the size of the code.
162// Switching this option on does not forbid to use direct access to
163// these parameters.
164
165#define USE_PRIVATE_PARAM_IN_PASSIVEPTR // allows to change parameters
166 // only through getters and setters.
167// Obviously, switching this option on requires switching on the previous
168// option, which is controlled by the following:
169#if defined(USE_PRIVATE_PARAM_IN_PASSIVEPTR) && \
170 !defined(USE_GETSETTERS_IN_PASSIVEPTR)
171"options incompatible\n"; // any line to trigger compiler diagnostic
172#endif
173
174#define USE_CHAR_CONTROL_VARIABLES // instead of int control variables
175// enables to use char control variables (except two static ones),
176// which could be optimal
177// both for memory and speed, but that it is really optimal
178// is not checked so far.
179
180//#define USE_BIT_FIELDS // instead of int control variables
181// allowes to pack control auxiliary
182// variables presented in passive pointer into bit fields.
183// It is assumed that the passive pointer objects and the whole
184// programs using it could be smaller in size with this option switched on.
185// But be informed that according to Stroustrup this is not always the fact:
186// this reduces the data but increases the executable code size.
187// Also the performance could be
188// decreased due to necessity to unpack these thinigs each time at their use.
189// This option does not compatible with the previous one.
190// So only one of them can be switched on, which is checked by the following:
191
192//#define USE_BIT_OPERA // Instead of the two previous options
193// allowes to pack control auxiliary
194// variables presented in passive pointer into bit fields
195// and to use bit operations.
196// Currently under debug.
197#if defined(USE_CHAR_CONTROL_VARIABLES) && defined(USE_BIT_FIELDS)
198"options incompatible\n"; // any line to trigger compiler diagnostic
199#endif
200#if defined(USE_CHAR_CONTROL_VARIABLES) && defined(USE_BIT_OPERA)
201"options incompatible\n"; // any line to trigger compiler diagnostic
202#endif
203#if defined(USE_BIT_FIELDS) && defined(USE_BIT_OPERA)
204"options incompatible\n"; // any line to trigger compiler diagnostic
205#endif
206
207#define USE_CHAR_GETSETTERS_PARAMETERS // related to type of parameters
208 // in gatters and setters.
209// If this macro is enabled, the parameters are "char".
210// Otherwise the parameters and int.
211// What is faster I do not know at the moment
212// They are not bool since in many instanses they can have the values
213// of 0, 1, or 2 (and the author does not like bool type at all).
214#if defined(USE_CHAR_CONTROL_VARIABLES) && \
215 !defined(USE_CHAR_GETSETTERS_PARAMETERS)
216"options incompatible\n"; // any line to trigger compiler diagnostic
217#endif
218
219#ifdef COPY_RETURNS_COMMON_BASE
220class CommonBase {
221 public:
222 //virtual void printCommonBase(void) { cout<<"CommonBase::print: Hello\n";}
223 // This function is just to make this "polymorphic", that is
224 // with at least one virtual function
225 virtual ~CommonBase() {}
226};
227// For macros which are designed to disappear completely without
228// editing of source when covariant types are
229// included and COPY_RETURNS_COMMON_BASE gets not defined anymore:
230#define virt_common_base \
231 public \
232 virtual CommonBase
233#define virt_common_base_col :public virtual CommonBase // for single case
234#define virt_common_base_comma \
235 public \
236 virtual CommonBase, // one of many
237#define virt_common_base_col_comma :public virtual CommonBase, // first of many
238#define virt_common_base_pcomma , public virtual CommonBase // last of many
239#else
240// define them just empty
241#define virt_common_base
242#define virt_common_base_col // for single case
243#define virt_common_base_comma // one of many
244#define virt_common_base_col_comma // first of many
245#define virt_common_base_pcomma // last of many
246
247#endif
248
249/*
250// Original source:
251//#define AbsCont_copy(type) virtual AbsCont* copy(void) const \
252//{return new type(*this);}
253//#define AnyType_copy(derived_type, base_type) \
254//virtual base_type* copy(void) const \
255//{return new derived_type(*this);}
256*/
257// These are obliterate macros. Actually parameter base_type is not necessary
258#ifndef COPY_RETURNS_COMMON_BASE
259// return type
260#define AbsCont_copy(type) \
261 virtual type* copy(void) const { return new type(*this); }
262#define AnyType_copy(derived_type, base_type) \
263 virtual derived_type* copy(void) const { return new derived_type(*this); }
264#else
265// return CommonBase
266#define AbsCont_copy(type) \
267 virtual CommonBase* copy(void) const { return new type(*this); }
268#define AnyType_copy(derived_type, base_type) \
269 virtual CommonBase* copy(void) const { return new derived_type(*this); }
270#endif
271
272// New definitions
273#ifndef COPY_RETURNS_COMMON_BASE
274// return type
275
276class AbsCont // Abstract Container
277 {
278 public:
279 virtual AbsCont* copy(void) const = 0;
280 // printing function
281 // parameter l is useful so as to control length of listing.
282 virtual void print(std::ostream& file, int l) const {
283 Ifile << "AbsCont::print is called, l=" << l << "\n";
284 }
285 virtual ~AbsCont() {}
286};
287
288// Interesting that the following macros do not seem to be working
289// with templates with more than one argument, since preprocessor
290// perhaps interprate the template arguments as macro arguments
291// and produce compiler error.
292// Direct use of these functions is recommended in this case
293#define macro_copy_total(type) \
294 virtual type* copy(void) const { return new type(*this); }
295#define macro_copy_total_zero(type) virtual type* copy(void) const = 0
296#define macro_copy_header(type) virtual type* copy(void) const
297#define macro_copy_body(type) \
298 type* type::copy(void) const { return new type(*this); }
299#define macro_copy_body_not_defined(type) \
300 type* type::copy(void) const { \
301 mcerr << "macro_copy_body_not_defined(" << #type << "): forbidden call\n"; \
302 spexit(mcerr); \
303 return NULL; \
304 }
305// return NULL to calm compiler of Solaris which wants to see return value
306
307#else
308
309// return void
310
311class AbsCont virt_common_base_col // Abstract Container
312 {
313 public:
314 virtual CommonBase* copy(void) const = 0;
315 virtual void print(std::ostream& file, int l) const {
316 Ifile << "AbsCont::print is called, l=" << l << "\n";
317 } // printing function
318 // parameter l is useful so as to control length of listing.
319 virtual ~AbsCont() {}
320};
321
322#define macro_copy_total(type) \
323 virtual CommonBase* copy(void) const { return new type(*this); }
324#define macro_copy_total_zero(type) virtual CommonBase* copy(void) const = 0
325#define macro_copy_header(type) virtual CommonBase* copy(void) const;
326#define macro_copy_body(type) \
327 CommonBase* type::copy(void) const { return new type(*this); }
328#define macro_copy_body_not_defined(type) \
329 CommonBase* type::copy(void) const { \
330 mcerr << "macro_copy_body_not_defined(" << #type << "): forbidden call\n"; \
331 spexit(mcerr); \
332 return NULL; \
333 }
334// return NULL to calm compiler of Solaris which wants to see return value
335#endif
336
337inline std::ostream& operator<<(std::ostream& file, const AbsCont& f) {
338 Ifile << "operator<<AbsCont& is called.\n";
339 f.print(file, 0); // this line is needed only to avoid warnings
340 // at some severe compiler options that f is unused.
341 return file;
342}
343
344// The auxiliary class determining the name of clone function
345// which is member of class X and will be used for cloning
346//#ifdef COPY_TYPE_CHECK
347//class FunNameStack;
348//static FunNameStack& FunNameStack::instance(void);
349//#endif
350
351template <class X> class StandardCopyDefinition {
352 public:
353 static X* copy(const X* f) {
354#ifdef DEBUG_ACTIVEPTR
355 mcout << "static X* StandardCopyDefinition::copy(const X* f)\n";
356#endif
357// If to allow the type of copy function be any (void* for example,
358// it needs to convert it. This seems there is no reason to allow this.
359#ifndef COPY_TYPE_CHECK
360#ifndef COPY_RETURNS_COMMON_BASE
361 return f->copy();
362#else
363 X* ptr = dynamic_cast<X*>(f->copy());
364 if (ptr == NULL) {
365 mcerr << "Error in X* StandardCopyDefinition::copy(const X* f): "
366 << "cannot convert pointer returned from f->copy()"
367 << "to type " << typeid(X).name() << '\n';
368 }
369 return ptr;
370#endif
371#else
372 //return (X*)(f->copy());
373 //X* p = static_cast< X* >(f->copy());
374 //#ifndef COPY_RETURNS_VOID // this macro should NOT be used, leads to
375 //errors
376 X* p = f->copy();
377//#else
378//X* p = dynamic_cast< X* >(f->copy());
379//if(p == NULL)
380//{
381// mcerr<<"Error in X* StandardCopyDefinition::copy(const X* f): "
382// <<"cannot convert pointer returned from f->copy()"
383// <<"to type "<<typeid(X).name()<<'\n';
384//}
385//#endif
386#ifdef DEBUG_ACTIVEPTR
387 mcout << "X* StandardCopyDefinition::copy(const X* f): f->copy() returned "
388 << p << '\n';
389 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
390 << '\n';
391 mcerr << "Type of *p is (in internal notations) " << typeid(*p).name()
392 << '\n';
393#endif
394 if (typeid(*p) != typeid(*f)) {
395 mcerr << "Error in X* StandardCopyDefinition::copy(const X* f): "
396 << "typeid(*p) != typeid(*f) \n";
397 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
398 << '\n';
399 mcerr << "Type of *p is (in internal notations) " << typeid(*p).name()
400 << '\n';
401 mcerr << "Type of *f is (in internal notations) " << typeid(*f).name()
402 << '\n';
403 mcerr << "Possible reason is omiting of copy function in one of the "
404 "derivative classes\n";
405 spexit(mcerr);
406 }
407 return p;
408#endif
409 }
410};
411
412/*
413template<class X>class CopyDefinition_1
414{public:
415 static X* copy(const X* f)
416 {
417 //mcout<<"static X* CopyDefinition_1::copy(const X* f)\n";
418 //return (X*)(f->copy1());
419#ifndef COPY_TYPE_CHECK
420#ifndef COPY_RETURNS_VOID
421 return f->copy1();
422#else
423 return static_cast< X* >(f->copy1());
424#endif
425#else
426#ifndef COPY_RETURNS_VOID
427 X* p = f->copy1();
428#else
429 X* p = static_cast< X* >(f->copy1());
430#endif
431 if(typeid(*p) != typeid(*f))
432 {
433 mcerr<<"Error in X* CopyDefinition_1::copy(const X* f): "
434 <<"typeid(*p) != typeid(*f) \n";
435 mcerr<<"Type of X is (in internal notations) "<<typeid(X).name()<<'\n';
436 mcerr<<"Type of *p is (in internal notations) "<<typeid(*p).name()<<'\n';
437 mcerr<<"Type of *f is (in internal notations) "<<typeid(*f).name()<<'\n';
438 mcerr<<"Possible reasone is omiting of copy function in one of the derivative
439classes\n";
440 spexit(mcerr);
441 }
442 return p;
443#endif
444 }
445};
446*/
447
448/*
449It looks like that this thing is not necessary
450template<class X>class VoidCopyDefinition
451{public:
452 static X* copy(const X* f)
453 {
454 //mcout<<"static X* VoidCopyDefinition::copy(const X* f)\n";
455 //mcout<<"Type of X is (in internal notations) "<<typeid(X).name()<<'\n';
456 //mcout<<"Type of f is (in internal notations) "<<typeid(f).name()<<'\n';
457 //mcout<<"Type of *f is (in internal notations)
458"<<typeid(*f).name()<<'\n';
459 //return (X*)(f->copy()); // return of f->copy();
460 // assumed to be void, and we convert it directly
461 X* p = static_cast< X* >(f->copy());
462 if(typeid(*p) != typeid(*f))
463 {
464 mcerr<<"Error in X* VoidCopyDefinition::copy(const X* f): "
465 <<"typeid(*p) != typeid(*f) \n";
466 mcerr<<"Type of X is (in internal notations) "<<typeid(X).name()<<'\n';
467 mcerr<<"Type of *p is (in internal notations) "<<typeid(*p).name()<<'\n';
468 mcerr<<"Type of *f is (in internal notations) "<<typeid(*f).name()<<'\n';
469 mcerr<<"Possible reasone is omiting of copy function in one of the derivative
470classes\n";
471 spexit(mcerr);
472 }
473 return p;
474 }
475};
476*/
477// This does not require from pointee object to provide
478// copy function, but don't preserve inheritance as well
479
480template <class X> class CopyDefinitionWithoutInheritance {
481 public:
482 static X* copy(const X* f) {
483#ifdef DEBUG_ACTIVEPTR
484 mcout << "static X* CopyDefinitionWithoutInheritance::copy(const X* f)\n";
485#endif
486 return new X(*f);
487 }
488};
489
490/* The second parameter determines the class which has to have only one
491function copy() which "knows" the actual name of cloning function.
492Normally the cloning function is copy() as well.
493But can be any.
494Previously at this place there were some terrible comment
495which told that there might be some problems. But it was outdated.
496At contemporary systems there is no problems.
497So any complicated tree of derived classes even with multiple inheritance
498can each have the same-named function
499returning different types with accordance with
500the type of the class.
501Everything is compiled and work.
502But do not forget to add virtual destructors in pointee classes!
503In particular, when playing with multiple inheritance.
504*/
505
506#define USE_OLD_POINTER_NAMES
507#ifdef USE_OLD_POINTER_NAMES
508// To use old name:
509#define AutoCont ActivePtr
510#endif
511
512enum Pilfer {
513 steal
515enum Clone {
518enum Pass {
521
522template <class X, class C = StandardCopyDefinition<X> >
523class ActivePtr virt_common_base_col
524 // Active pointer or automatic container or controlling pointer
525 {
526 public:
527 // First of all, two pointer's operations.
528 // NULL address is interpreted as error.
529 inline X* operator->(void) const;
530 inline X& operator*(void) const;
531
532 // get with verification, that is the same as two operators above,
533 // but with sintax of function:
534 inline X* getver(void) const;
535
536#ifdef IMPLICIT_X_STAR
537 inline operator X*(void) const;
538#endif
539
540 // Then, gentle exctraction of pointer without check:
541 inline X* get(void) const { return ptr; }
542
543 // Two variants of putting the object under control of the pointer:
544 // 1. put(): with cloning
545 // (the ActivePtr will keep copy of what is found at fptr).
546 // 2. pass(): with incerting given address under control
547 // (the ActivePtr will keep fptr, which should be address of
548 // block of dynamic memory).
549 // The old kept object in deleted in both cases.
550 //
551 inline void put(const X* fptr) // delete old owned object and
552 // copy object fptr to ownership of this.
553 // At fptr==NULL old object is deleted and new one is not copyed.
554 { //
555#ifdef DEBUG_ACTIVEPTR
556 mcout << "inline void put(const X* fptr)\n";
557 Iprintn(mcout, ptr);
558 mcout << "Type of X is (in internal notations) " << typeid(X).name()
559 << '\n';
560 mcout << "Type of *fptr is (in internal notations) " << typeid(*fptr).name()
561 << '\n';
562#endif
563 // Initialization of copy should go ahead, since
564 // object *fptr could be dependant or part of *this,
565 // and could be deleted prior to copying at the reverse order.
566 X* ptr_temp = (fptr != NULL ? C::copy(fptr) : (X*)(NULL));
567 if (ptr != NULL) delete ptr;
568 ptr = ptr_temp;
569#ifdef DEBUG_ACTIVEPTR
570 mcout << "finishing inline void put(const X* fptr):\n";
571 Iprintn(mcout, ptr);
572#endif
573 }
574 inline void pass(X* fptr) // delete old owned object and
575 // pass address of object fptr to ownership of this
576 // without copying.
577 // At fptr==NULL old object is deleted and new one is not copyed.
578 // In general this is dengerous operation.
579 // In particular if object pointed by fptr is direct or indirect part
580 // of object pointed by ptr, it will be destroyed, which would probably
581 // cause error.
582 // But it is more efficient since does not require copying.
583 { //
584 //if(ptr!=NULL) delete ptr;
585
586 if (ptr != NULL) {
587 if (fptr != NULL) {
588 mcerr << "ERROR in ActivePtr::pass(X* fptr):\n";
589 mcerr << "Both the destination and source pointers are not empty\n";
590 // if f belongs to *ptr, deletion of *ptr would lead to
591 // deletion of f. In order to avoid this unexpected behaviour,
592 // we interprete non-zero ptr as error.
593 // The user should clear ptr first and then use this function.
594 spexit(mcerr);
595 } else {
596 delete ptr;
597 }
598 }
599 ptr = fptr;
600 }
601
602 // Removing the object from the responsibility of smart pointer
603 // without copying
604 inline X* extract(void) {
605 X* ret = ptr;
606 ptr = NULL;
607 return ret;
608 }
609 inline void clear(void) {
610#ifdef DEBUG_ACTIVEPTR
611 mcout << "ActivePtr::clear is called, ptr =" << ptr << '\n';
612#endif
613 if (ptr != NULL) {
614 delete ptr;
615 ptr = NULL;
616 }
617 }
618
619 inline void pilfer(PILF_CONST ActivePtr<X, C>& f)
620 //!Attention: actually not const
621 {
622#ifdef DEBUG_ACTIVEPTR
623 mcout << "ActivePtr::pilfer is called\n";
624#endif
625 if (this != &f) {
626 if (ptr != NULL) {
627 if (f.ptr != NULL) {
628 mcerr << "ERROR in ActivePtr::pilfer(...):\n";
629 mcerr << "Both the destination and source pointers are not empty\n";
630 // if f belongs to *ptr, deletion of *ptr would lead to
631 // deletion of f. In order to avoid this unexpected behaviour,
632 // we interprete non-zero ptr as error.
633 // The user should clear ptr first and then use this function.
634 spexit(mcerr);
635 } else {
636 delete ptr;
637 }
638 }
639 ptr = f.ptr;
640 f.ptr = NULL;
641 }
642 return;
643 }
644
645 void print(std::ostream& file, int l = 1) const;
646 inline ActivePtr(void) : ptr(NULL) {}
647
648 // The constructors and the assignment are interpreted as put(),
649 // that is they assume cloning the object.
650 /*
651 inline ActivePtr(const X* fptr):ptr(fptr != NULL ? C::copy(fptr) : ((X*)NULL))
652//inline ActivePtr(const X* fptr):ptr(fptr != NULL ? fptr->copy() : ((X*)NULL))
653#ifndef DEBUG_ACTIVEPTR
654 {} //normal case
655#else
656 {mcout<<"ActivePtr(const X* fptr) is finished\n";} // debug
657#endif
658 */
659 inline ActivePtr(const X* fptr, Clone)
660 : ptr(fptr != NULL ? C::copy(fptr) : ((X*)NULL))
661#ifndef DEBUG_ACTIVEPTR
662 {
663 } //normal case
664#else
665 {
666 mcout << "ActivePtr(const X* fptr, Clone) is finished, ptr =" << ptr
667 << '\n';
668 delete ptr;
669 cout << "deleted, exit\n";
670 exit(0);
671 }
672// debug
673#endif
674 //inline ActivePtr( ActivePtr<X,C>& f): // was required at some old
675 //systems, don't remember why.
676 // ptr(f.ptr != NULL ? C::copy(f.ptr) : f.ptr) {}
677 inline ActivePtr(const ActivePtr<X, C>& f)
678 : ptr(f.ptr != NULL ? C::copy(f.ptr) : f.ptr)
679#ifndef DEBUG_ACTIVEPTR
680 {
681 }
682#else
683 {
684 mcout << "ActivePtr(const ActivePtr<X,C>& f) is finished\n";
685 } // debug
686#endif
687
688 // Pilfer constructor
689 inline ActivePtr(PILF_CONST ActivePtr<X, C>& f, Pilfer)
690 : ptr(f.ptr) { //!Attention: actually not const
691#ifdef DEBUG_ACTIVEPTR
692 mcout << "ActivePtr(const ActivePtr<X,C>& f, Pilfer) is run\n";
693#endif
694 f.ptr = NULL;
695 } // debug
696
697 // Pass constructor
698 inline ActivePtr(X* fptr, Pass) : ptr(fptr) {}
699
700 inline ActivePtr& operator=(const ActivePtr<X, C>& f) {
701#ifdef DEBUG_ACTIVEPTR
702 mcout << "inline ActivePtr& operator=(const ActivePtr<X,C>& f)\n";
703#endif
704 if (this != &f) put(f.ptr);
705 return *this;
706 }
707
709 virtual ~ActivePtr() // unfortunately it should be virtual
710 // in order to avoid some rare (not met in practice but
711 // in principle possible) problems with ActivePtrReg.
712 // Therefore (if there is a virtual member)
713 // we can also include virtual copy (see above),
714 // although there is no obvious application for it
715 // (multiple indirection depth, but for what?).
716 {
717 if (ptr != NULL) {
718 delete ptr;
719 ptr = NULL;
720 }
721 }
722 // the last assignment is for debug to assure the fast detection of error
723 // in the case of continuing access to this ptr.
724 private:
725 PILF_MUTABLE X* ptr; // mutable is only to allow pilfer function and pilfer
726// constructor to have const descriptor of its argument and still to steal
727// the object.
728// Somewhy if without const, this function and this constructor
729// is sometimes not recognized by Scientific Linux 4.1 compiler.
730// (when argument is temporary, actual at receiving return value).
731#ifdef USE_REPLACE_ALLOC
733#endif
734};
735
736// Trying to change name
737//typedef ActivePtr<class X, class C > ActivePtr;
738// does not work
739
740template <class X, class C>
741void ActivePtr<X, C>::print(std::ostream& file, int l) const {
742 //if(ptr!=NULL) ptr->print(file, l);
743 Ifile << "ActivePtr<X,C>: ";
744 if (ptr == NULL)
745 file << " ptr==NULL. \n"; // optimized to provide automatic reading
746 else {
747 file << " ptr!=NULL: ";
748 file << noindent;
749 ptr->print(file, l);
750 file << yesindent;
751 }
752 /*
753 Ifile<<"ActivePtr<X,C>: ";
754 if(ptr == NULL)
755 file<<" pointer is NULL, no object.\n";
756 else
757 {
758 file<<noindent;
759 ptr->print(file, l);
760 file<<yesindent;
761 }
762 */
763}
764
765template <class X, class C>
766 std::ostream& operator<<(std::ostream& file, const ActivePtr<X, C>& f) {
767 Ifile << "ActivePtr<X,C>: ";
768 if (f.get() == NULL)
769 file << " ptr==NULL. \n"; // optimized to provide automatic reading
770 else {
771 file << " ptr!=NULL: ";
772 file << noindent;
773 file << (*f.get());
774 file << yesindent;
775 }
776
777 /*
778 if(f.get() == NULL)
779 file<<" pointer in NULL, no object.\n";
780 else
781 {
782 file<<noindent;
783 file<<(*f.get());
784 //f.get()->print(file,1); alternatively,
785 // but logically it is better as above
786 file<<yesindent;
787 }
788 */
789 return file;
790}
791
792template <class X, class C>
793 std::istream& operator>>(std::istream& file, ActivePtr<X, C>& f) {
794 long q = 13;
795 long n;
796 char keyline[13];
797 for (n = 0; n < q - 1; n++) {
798 keyline[n] = file.get();
799 }
800 keyline[n] = '\0';
801 if (!strcmp(&(keyline[0]), " ptr==NULL. ")) {
802 f.clear();
803 } else {
804 X x;
805 file >> x;
806 f.put(x);
807 }
808 return file;
809}
810/*
811template<class X>
812std::ostream& operator<<(std::ostream& file, const ActivePtr<X>& f)
813{
814 Ifile<<"ActivePtr<X>:";
815 if(f.get() == NULL)
816 file<<" pointer in NULL, no object\n";
817 else
818 {
819 file<<noindent;
820 f.get()->print(file,1);
821 file<<yesindent;
822 }
823 return file;
824}
825*/
826
827template <class X, class C> inline X* ActivePtr<X, C>::operator->(void) const {
828#ifdef SKIP_CHECKS_NULL
829 return ptr;
830#else
831 if (ptr != NULL) return ptr;
832 mcerr << "Error in X* ActivePtr<X,C>::operator->(void) const: "
833 << " ptr == NULL\n";
834 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
835 //mcerr<<"Type of ptr is "<<typeid(ptr).name()<<'\n';
836 spexit(mcerr);
837 return ptr; // just to quiet compiler which wants to see a return value
838#endif
839}
840template <class X, class C> inline X& ActivePtr<X, C>::operator*(void) const {
841#ifdef SKIP_CHECKS_NULL
842 return *ptr;
843#else
844 if (ptr != NULL) return *ptr;
845 mcerr << "Error in X& ActivePtr<X,C>::operator*(void) const: "
846 << " ptr == NULL\n";
847 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
848 spexit(mcerr);
849 return *ptr; // just to quiet compiler which wants to see a return value
850#endif
851}
852template <class X, class C> inline X* ActivePtr<X, C>::getver(void) const {
853#ifdef SKIP_CHECKS_NULL
854 return ptr;
855#else
856 if (ptr != NULL) return ptr;
857 mcerr << "Error in X* ActivePtr<X,C>::getver(void) const: "
858 << " ptr == NULL\n";
859 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
860 spexit(mcerr);
861 return ptr; // just to quiet compiler which wants to see a return value
862#endif
863}
864#ifdef IMPLICIT_X_STAR
865template <class X, class C> inline ActivePtr<X, C>::operator X*(void) const {
866#ifdef SKIP_CHECKS_NULL
867 return ptr;
868#else
869 if (ptr != NULL) return ptr;
870 mcerr << "Error in ActivePtr<X,C>::operator X*(void) const: "
871 << " ptr == NULL\n";
872 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
873 spexit(mcerr);
874 return ptr; // just to quiet compiler which wants to see a return value
875#endif
876}
877#endif
878template <class X, class C>
879inline void exchange(ActivePtr<X, C>& f1, ActivePtr<X, C>& f2) {
880 X* ptr = f1.extract();
881 f1.pass(f2.extract());
882 f2.pass(ptr);
883}
884
885#ifdef INCLUDE_ActivePtrWI
886
887// The following of obliterate class.
888// Use ActivePtr <X, CopyDefinitionWithoutInheritance >
889
890// The inheritance is not preserved in the following
891
892#define USE_OLD_POINTER_NAMES
893#ifdef USE_OLD_POINTER_NAMES
894// To use old name:
895#define AutoPtr ActivePtrWI
896#endif
897
898// WI means without inheritance
899
900template <class X> class ActivePtrWI {
901 public:
902 inline X* get(void) const { return ptr; }
903 inline void put(const X* fptr) // delete old owned object and
904 // copy object fptr to ownership of this.
905 // At fptr==NULL old object is deleted and new one is not copyed.
906 { //
907 if (ptr != NULL) {
908 delete ptr;
909 ptr = NULL;
910 }
911 if (fptr != NULL) ptr = new X(*fptr);
912 }
913 inline void pass(X* fptr) // delete old owned object and
914 // pass address of object fptr to ownership of this
915 // without copying.
916 // At fptr==NULL old object is deleted and new one is not copyed.
917 { //
918 if (ptr != NULL) delete ptr;
919 ptr = fptr;
920 }
921 void print(std::ostream& file, int l = 1) const;
922 inline ActivePtrWI(void) : ptr(NULL) {}
923 inline ActivePtrWI(const X* fptr)
924 : ptr(fptr != NULL ? new X(*fptr) : ((X*)NULL)) {}
925 //inline ActivePtrWI(ActivePtrWI<X>& f): ptr(NULL)
926 // { if(f.ptr != NULL) ptr= new X(*(f.ptr)); }
927 inline ActivePtrWI(const ActivePtrWI<X>& f) : ptr(NULL) {
928 if (f.ptr != NULL) ptr = new X(*(f.ptr));
929 }
930 inline ActivePtrWI& operator=(const ActivePtrWI<X>& f) {
931 if (this != &f) put(f.ptr);
932 return *this;
933 }
934 inline X* operator->(void) const;
935 inline X& operator*(void) const;
936#ifdef IMPLICIT_X_STAR
937 operator X*(void) const;
938#endif
939 virtual ~ActivePtrWI() {
940 if (ptr != NULL) delete ptr;
941 }
942
943 private:
944 X* ptr;
945#ifdef USE_REPLACE_ALLOC
947#endif
948};
949
950template <class X> inline X* ActivePtrWI<X>::operator->(void) const {
951#ifdef SKIP_CHECKS_NULL
952 return ptr;
953#else
954 if (ptr != NULL) return ptr;
955 mcerr << "Error in X* ActivePtrWI<X>::operator->(void) const: "
956 << " ptr == NULL\n";
957 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
958 spexit(mcerr);
959 return ptr; // just to quiet compiler which wants to see a return value
960#endif
961}
962template <class X> inline X& ActivePtrWI<X>::operator*(void) const {
963#ifdef SKIP_CHECKS_NULL
964 return *ptr;
965#else
966 if (ptr != NULL) return *ptr;
967 mcerr << "Error in X& ActivePtrWI<X>::operator*(void) const: "
968 << " ptr == NULL\n";
969 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
970 spexit(mcerr);
971 return *ptr; // just to quiet compiler which wants to see a return value
972#endif
973}
974
975#ifdef IMPLICIT_X_STAR
976template <class X> ActivePtrWI<X>::operator X*(void) const {
977#ifdef SKIP_CHECKS_NULL
978 return ptr;
979#else
980 if (ptr != NULL) return ptr;
981 mcerr << "Error in ActivePtrWI<X>::operator X*(void) const: "
982 << " ptr == NULL\n";
983 mcerr << "Type of X is (in internal notations) " << typeid(X).name() << '\n';
984 spexit(mcerr);
985 return ptr; // just to quiet compiler which wants to see a return value
986#endif
987}
988#endif
989
990template <class X> void ActivePtrWI<X>::print(std::ostream& file, int l) const {
991 //if(ptr!=NULL) ptr->print(file, l);
992 Ifile << "ActivePtrWI<X>:";
993 if (ptr == NULL)
994 file << " pointer in NULL, no object.\n";
995 else {
996 file << noindent;
997 ptr->print(file, l);
998 file << yesindent;
999 }
1000}
1001template <class X>
1002 std::ostream& operator<<(std::ostream& file, const ActivePtrWI<X>& f) {
1003 Ifile << "ActivePtrWI<X>:";
1004 if (f.get() == NULL)
1005 file << " pointer in NULL, no object\n";
1006 else {
1007 file << noindent;
1008 file << (*f.get());
1009 //f.get()->print(file,1);
1010 file << yesindent;
1011 }
1012 return file;
1013}
1014#endif
1015
1016#define USE_OLD_POINTER_NAMES
1017#ifdef USE_OLD_POINTER_NAMES
1018// To use old name:
1019#define ProtPtr PassivePtr
1020#define RegProtPtr RegPassivePtr
1021#define CountProtPtr CountPassivePtr
1022#endif
1023
1024template <class X> class PassivePtr;
1025
1026class RegPassivePtr;
1027
1028namespace CountPP_ns {
1029class CountPassivePtr // counter of protected pointers
1030 {
1031 public:
1032 //CountPassivePtr();
1033 CountPassivePtr(const RegPassivePtr* frpp) : rpp(frpp), number_of_booked(0) {}
1034
1035 // In the following I will use the word book instead of register,
1036 // because register seems to be interfered with some computer definition
1037 inline void book(void);
1038 inline void unbook(void);
1039 inline long get_number_of_booked(void) { return number_of_booked; }
1040 inline const RegPassivePtr* get_rpp(void) { return rpp; }
1041 inline void change_rpp(const RegPassivePtr* frpp) { rpp = frpp; }
1042 inline ~CountPassivePtr(); // here to delete reference from RegPassivePtr
1043 private:
1044 const RegPassivePtr* rpp;
1045 // const is necessary here to make possible booking of RegPassivePtr
1046 // by a function which is declared as const.
1047
1048 long number_of_booked; // the counter of pointers
1049#ifdef USE_REPLACE_ALLOC
1051#endif
1052};
1053
1054inline void CountPassivePtr::book(void) {
1055 if (number_of_booked > LONG_MAX - 1) {
1056 mcerr << "Error in CountPassivePtr::book(void):\n"
1057 << " too much booked counters, number_of_booked > LONG_MAX-1, "
1058 "number_of_booked=" << number_of_booked << '\n';
1059 spexit(mcerr);
1060 }
1061 number_of_booked++;
1062}
1063
1064inline void CountPassivePtr::unbook(void) {
1065 if (number_of_booked < 1) {
1066 mcerr << "Error in CountPassivePtr::unbook(void):\n"
1067 << " number_of_booked < 1, number_of_booked=" << number_of_booked
1068 << '\n';
1069 spexit(mcerr);
1070 }
1071 number_of_booked--;
1072}
1073
1074}
1075//template<class X>class PassivePtr;
1076
1077#ifdef USE_BIT_OPERA
1078
1079const unsigned char eb_s_ban_del = 1;
1080const unsigned char eb_s_ban_sub1 = 2;
1081const unsigned char eb_s_ban_sub2 = 4;
1082const unsigned char eb_s_ban_cop1 = 8;
1083const unsigned char eb_s_ban_cop2 = 16;
1084#ifdef USE_DELETE_AT_ZERO_COUNT
1085const unsigned char eb_s_allow_del_at_zero_count = 32;
1086#endif
1087#endif
1088
1089class RegPassivePtr virt_common_base_col
1090 // virt_common_base_col is added just to avoid repetitions in application
1091 // classes
1092 {
1093 public:
1095// used for making cpp NULL when CountPassivePtr
1096// is destructed
1097
1098#ifdef USE_BIT_OPERA
1099 private:
1100 /*
1101 enum E_cwb{eb_s_ban_del=01, eb_s_ban_sub1 = 010, eb_s_ban_sub2 = 0100,
1102 eb_s_ban_cop1=01000, eb_s_ban_cop2=010000
1103 #ifdef USE_DELETE_AT_ZERO_COUNT
1104 , eb_s_allow_del_at_zero_count = 0100000
1105 #endif
1106 };*/
1107 inline static void clear_bit(unsigned char& cw, unsigned char b) {
1108 if ((cw & b) != 0) {
1109 cw ^= b;
1110 }
1111 }
1112 inline static void rise_bit(unsigned char& cw, unsigned char b) { cw |= b; }
1113
1114 public:
1115// To define auxiliary class, used only in the following case:
1116#elif defined(USE_BIT_FIELDS)
1117 class ControlParam {
1118 public:
1119 unsigned int s_ban_del : 1; // see below for comments
1120 unsigned int s_ban_sub : 2;
1121 unsigned int s_ban_cop : 2;
1122#ifdef USE_DELETE_AT_ZERO_COUNT
1123 unsigned int s_allow_del_at_zero_count : 1;
1124#endif
1125 ControlParam(void)
1126 : s_ban_del(0),
1127 s_ban_sub(0),
1128 s_ban_cop(0)
1130 ,
1131 s_allow_del_at_zero_count(0)
1132#endif
1133 {
1134 }
1135#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1136 ControlParam(char fs_ban_del, char fs_ban_sub, char fs_ban_cop = 0
1138 ,
1139 char fs_allow_del_at_zero_count = 0
1140#endif
1141 )
1142 :
1143#else
1144 ControlParam(int fs_ban_del, int fs_ban_sub, int fs_ban_cop = 0
1146 ,
1147 int fs_allow_del_at_zero_count = 0
1148#endif
1149 )
1150 :
1151#endif
1152 s_ban_del(fs_ban_del),
1153 s_ban_sub(fs_ban_sub),
1154 s_ban_cop(fs_ban_cop)
1156 ,
1157 s_allow_del_at_zero_count(fs_allow_del_at_zero_count)
1158#endif
1159 {
1160 if (!(fs_ban_del == 0 || fs_ban_del == 1)) {
1161 mcerr << "ERROR in ControlParam::ControlParam(...)\n";
1162 mcerr << "s_ban_del is outside limits, s_ban_del=" << fs_ban_del
1163 << '\n';
1164 spexit(mcerr);
1165 }
1166 if (fs_ban_sub < 0 || fs_ban_sub > 2) {
1167 mcerr << "ERROR in ControlParam::ControlParam(...):\n";
1168 mcerr << "s_ban_sub is outside limits, s_ban_sub=" << fs_ban_sub
1169 << '\n';
1170 spexit(mcerr);
1171 }
1172 if (fs_ban_cop < 0 || fs_ban_cop > 2) {
1173 mcerr << "ERROR in ControlParam::ControlParam(...):\n";
1174 mcerr << "s_ban_cop is outside limits, s_ban_cop=" << fs_ban_cop
1175 << '\n';
1176 spexit(mcerr);
1177 }
1178#ifdef USE_DELETE_AT_ZERO_COUNT
1179 if (!(s_allow_del_at_zero_count == 0 || s_allow_del_at_zero_count == 1)) {
1180 mcerr << "ERROR in ControlParam::ControlParam(...)\n";
1181 mcerr << "s_allow_del_at_zero_count is outside limits, "
1182 "s_allow_del_at_zero_count=" << fs_allow_del_at_zero_count
1183 << '\n';
1184 spexit(mcerr);
1185 }
1186#endif
1187 }
1188 }; // the total 6 bits
1189#endif // ifdef USE_BIT_FIELDS
1190
1191 //friend template<class X>class PassivePtr;
1192 inline RegPassivePtr(void)
1193 :
1194#ifdef USE_BIT_OPERA
1195 control_word(0),
1196#elif defined USE_BIT_FIELDS
1197 conparam(),
1198#else
1199 s_ban_del(0),
1200 s_ban_sub(0),
1201 s_ban_cop(0),
1203 s_allow_del_at_zero_count(0),
1204#endif
1205#endif
1206 cpp(NULL) {
1207 }
1208#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1209 inline RegPassivePtr(char fs_ban_del, char fs_ban_sub, char fs_ban_cop = 0)
1210 :
1211#else
1212 inline RegPassivePtr(int fs_ban_del, int fs_ban_sub, int fs_ban_cop = 0)
1213 :
1214#endif
1215#ifdef USE_BIT_OPERA
1216 control_word(0),
1217#elif defined(USE_BIT_FIELDS)
1218 conparam(fs_ban_del, fs_ban_sub, fs_ban_cop),
1219#else
1220 s_ban_del(fs_ban_del),
1221 s_ban_sub(fs_ban_sub),
1222 s_ban_cop(fs_ban_cop),
1224 s_allow_del_at_zero_count(0),
1225#endif
1226#endif
1227 cpp(NULL) {
1228#ifdef USE_BIT_OPERA
1229 set_s_ban_del(fs_ban_del);
1230 set_s_ban_sub(fs_ban_sub);
1231 set_s_ban_cop(fs_ban_cop);
1232#endif
1233 }
1234 //{mcout<<"RegPassivePtr::RegPassivePtr(void) is run\n";}
1235
1236 RegPassivePtr(const RegPassivePtr& f);
1237
1238 RegPassivePtr& operator=(const RegPassivePtr& f);
1239 // Copies s_ban_del and s_ban_sub
1240 // Also calls clear_pointers if s_ban_sub==1 or
1241 // spexit() if s_ban_sub==2 and the alist_of_prot_pointers is not empty.
1242
1243 inline CountPP_ns::CountPassivePtr* book(void) const {
1244 if (cpp == NULL) {
1245 cpp = new CountPP_ns::CountPassivePtr(this);
1246 }
1247 cpp->book();
1248 return cpp;
1249 }
1250
1251 inline void clear_pointers(void) const // all pointers addressing this
1252 // are cleared;
1253 {
1254 if (cpp != NULL) cpp->change_rpp(NULL);
1255 }
1256
1257 macro_copy_total(RegPassivePtr);
1258
1260 // If there are pointers addressed this object and s_ban_del = 1,
1261 // the program is terminated with output message to mcerr.
1262 // Otherwise (normal behaviour) the references are cleared.
1263
1264 virtual void print(std::ostream& file, int l = 1) const;
1265 friend std::ostream& operator<<(std::ostream& file, const RegPassivePtr& f);
1266
1267// Three parameters controlling behaviour of pointee object at
1268// its deletion and substitution.
1269// They are included for the sake of flexibility and
1270// they are necessary very rarely. Normally they are not used.
1271// If needed, you can set them though constructors,
1272// or change responsibly directly.
1273// Obviously, this is a temporary design.
1274// It needs then to pack all these small numbers in one computer word.
1275
1276#ifdef USE_BIT_OPERA
1277 private:
1278 unsigned char control_word;
1279
1280 public:
1281#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
1282 private:
1283#endif
1284 static int s_ban_del_ignore;
1285 static int s_print_adr_cpp;
1286#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
1287 public:
1288#endif
1289
1290#elif defined(USE_BIT_FIELDS)
1291 private:
1292 ControlParam conparam;
1293
1294 public:
1295#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
1296 private:
1297#endif
1298 static int s_ban_del_ignore;
1299 static int s_print_adr_cpp;
1300#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
1301 public:
1302#endif
1303
1304#else // for elif defined( USE_BIT_FIELDS )
1305
1306#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
1307 private:
1308#endif
1309#ifdef USE_CHAR_CONTROL_VARIABLES
1310 char s_ban_del;
1311#else
1312 int s_ban_del;
1313#endif
1314 // sign whether this object can (0) or cannot (1)
1315 // be deleted if it is addressed.
1316 // Normally it can. When it happens, the pointers addressing this object
1317 // are cleared and set to NULL.
1318 // If user needs to find where he deletes referenced object,
1319 // he may assign this variable to 1
1320
1321 static int s_ban_del_ignore;
1322// auxiliary variable with default value 0,
1323// meaning that s_ban_del is not ignored.
1324// In the case of value 1 s_ban_del is ignored, whatever it is.
1325// It is used in RegPassivePtr::~RegPassivePtr() to avoid loops at exiting
1326// after the fist deletion of referenced object at s_ban_del = 1 is found.
1327
1328#ifdef USE_CHAR_CONTROL_VARIABLES
1329 char s_ban_sub;
1330#else
1331 int s_ban_sub;
1332#endif
1333// sign controlling substitution of addressed object:
1334// 0 - it can be substituted and the pointers addressing "this" preserve
1335// their values (normal default case).
1336// 1 - it can be substituted, but the pointers will be assigned NULL.
1337// In the case of self-assignment and valid pointers to "this"
1338// the run-time error is triggered, because otherwise either
1339// the pointers to copied object would not be preserved or
1340// the pointers to "this" would not be cleared - principal contradiction.
1341// 2 - it cannot be substituted, if there are pointers to "this",
1342// attempt to substitute in this case triggers error.
1343// In the case of absence of pointers to this it is substituted.
1344// Note: if the substitution is allowed,
1345// s_ban_del, s_ban_sub, and s_ban_cop are themselves substituted -
1346// arbitrary decision, perhaps correct.
1347
1348#ifdef USE_CHAR_CONTROL_VARIABLES
1349 char s_ban_cop;
1350#else
1351 int s_ban_cop;
1352#endif
1353// sign controlling copying addressed object
1354// 0 - it can always be copied
1355// 1 - it can be copied only if there are no references,
1356// otherwise it will be runtime error.
1357// 2 - it can never be copied, but it is anyway runtime error,
1358// the compiler cannot detect it.
1359
1360#ifdef USE_DELETE_AT_ZERO_COUNT
1361#ifdef USE_CHAR_CONTROL_VARIABLES
1362 char s_allow_del_at_zero_count;
1363#else
1364 int s_allow_del_at_zero_count;
1365#endif
1366// concession to people who likes shared pointers.
1367// Instructs PassivePtr::~PassivePtr to delete the object if that
1368// pointer is last. Think twice before use.
1369// It basically violates the ideoma of reference to independent object.
1370// Also in the case of circular references the program can fall into loop
1371// of destructors, which is not the case for regular passive pointers.
1372#endif
1373
1374 static int s_print_adr_cpp;
1375// signature to print the address of cpp in operator<<
1376// by default it is 0 and address is not printed,
1377// but only the remark that it is NULL or not NULL is printed.
1378// It is good for making such output listings which do not depend
1379// on computer and can be automatically compared.
1380// But in the case of some deep debug the user can make them printed
1381// if he assigns s_print_adr_cpp = 1.
1382#ifdef USE_PRIVATE_PARAM_IN_PASSIVEPTR
1383 public:
1384#endif
1385
1386#endif // for elif defined( USE_BIT_FIELDS )
1387
1388#ifdef USE_GETSETTERS_IN_PASSIVEPTR
1389 public:
1390
1391#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1392 inline void set_s_ban_del(char fs_ban_del)
1393#else
1394 inline void set_s_ban_del(int fs_ban_del)
1395#endif
1396 {
1397#ifdef USE_BIT_OPERA
1398 if (fs_ban_del == 0)
1399 clear_bit(control_word, eb_s_ban_del);
1400 else if (fs_ban_del == 1)
1401 rise_bit(control_word, eb_s_ban_del);
1402#else
1403 if (fs_ban_del == 0 || fs_ban_del == 1) {
1404#ifdef USE_BIT_FIELDS
1405 conparam.s_ban_del = fs_ban_del;
1406#else
1407 s_ban_del = fs_ban_del;
1408#endif
1409 }
1410#endif
1411 else {
1412 mcerr << "ERROR in inline void set_s_ban_del(int fs_ban_del):\n";
1413 mcerr << "s_ban_del is outside limits, s_ban_del=" << int(fs_ban_del)
1414 << '\n';
1415 spexit(mcerr);
1416 }
1417 }
1418
1419#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1420 inline char get_s_ban_del(void) const
1421#else
1422 inline int get_s_ban_del(void) const
1423#endif
1424#ifdef USE_BIT_OPERA
1425 {
1426 if ((control_word & eb_s_ban_del) != 0)
1427 return 1;
1428 else
1429 return 0;
1430 }
1431#elif defined(USE_BIT_FIELDS)
1432 { return conparam.s_ban_del; }
1433#else
1434 { return s_ban_del; }
1435#endif
1436
1437#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1438 inline static void set_s_ban_del_ignore(char fs_ban_del_ignore)
1439#else
1440 inline static void set_s_ban_del_ignore(int fs_ban_del_ignore)
1441#endif
1442 {
1443 if (fs_ban_del_ignore == 0 || fs_ban_del_ignore == 1) {
1444 s_ban_del_ignore = fs_ban_del_ignore;
1445 } else {
1446 mcerr << "ERROR in inline void set_s_ban_del_ignore(int "
1447 "fs_ban_del_ignore ):\n";
1448 mcerr << "s_ban_del_ignore is outside limits, s_ban_del_ignore="
1449 << int(fs_ban_del_ignore) << '\n';
1450 spexit(mcerr);
1451 }
1452 }
1453
1454#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1455 inline static char get_s_ban_del_ignore(void)
1456#else
1457 inline static int get_s_ban_del_ignore(void)
1458#endif
1459 {
1460 return s_ban_del_ignore;
1461 }
1462
1463#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1464 inline void set_s_ban_sub(char fs_ban_sub)
1465#else
1466 inline void set_s_ban_sub(int fs_ban_sub)
1467#endif
1468 {
1469#ifdef USE_BIT_OPERA
1470 if (fs_ban_sub == 0) {
1471 clear_bit(control_word, eb_s_ban_sub1);
1472 clear_bit(control_word, eb_s_ban_sub2);
1473 } else if (fs_ban_sub == 1) {
1474 rise_bit(control_word, eb_s_ban_sub1);
1475 clear_bit(control_word, eb_s_ban_sub2);
1476 } else if (fs_ban_sub == 2) {
1477 clear_bit(control_word, eb_s_ban_sub1);
1478 rise_bit(control_word, eb_s_ban_sub2);
1479 }
1480#else
1481 if (fs_ban_sub >= 0 && fs_ban_sub <= 2) {
1482#ifdef USE_BIT_FIELDS
1483 conparam.s_ban_sub = fs_ban_sub;
1484#else
1485 s_ban_sub = fs_ban_sub;
1486#endif
1487 }
1488#endif
1489 else {
1490 mcerr << "ERROR in inline void set_s_ban_sub(int fs_ban_sub):\n";
1491 mcerr << "s_ban_sub is outside limits, s_ban_sub=" << int(fs_ban_sub)
1492 << '\n';
1493 spexit(mcerr);
1494 }
1495 }
1496
1497#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1498 inline char get_s_ban_sub(void) const
1499#else
1500 inline int get_s_ban_sub(void) const
1501#endif
1502#ifdef USE_BIT_OPERA
1503 {
1504 if ((control_word & eb_s_ban_sub2) == 0) {
1505 if ((control_word & eb_s_ban_sub1) == 0)
1506 return 0;
1507 else
1508 return 1;
1509 } else {
1510 //Iprintn(mcout, (control_word & eb_s_ban_sub1) );
1511 //Iprintn(mcout, (control_word & eb_s_ban_sub2) );
1512 return 2;
1513 }
1514 }
1515#elif defined(USE_BIT_FIELDS)
1516 { return conparam.s_ban_sub; }
1517#else
1518 { return s_ban_sub; }
1519#endif
1520
1521#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1522 inline void set_s_ban_cop(char fs_ban_cop)
1523#else
1524 inline void set_s_ban_cop(int fs_ban_cop)
1525#endif
1526 {
1527#ifdef USE_BIT_OPERA
1528 if (fs_ban_cop == 0) {
1529 clear_bit(control_word, eb_s_ban_cop1);
1530 clear_bit(control_word, eb_s_ban_cop2);
1531 } else if (fs_ban_cop == 1) {
1532 rise_bit(control_word, eb_s_ban_cop1);
1533 clear_bit(control_word, eb_s_ban_cop2);
1534 } else if (fs_ban_cop == 2) {
1535 clear_bit(control_word, eb_s_ban_cop1);
1536 rise_bit(control_word, eb_s_ban_cop2);
1537 }
1538#else
1539 if (fs_ban_cop >= 0 && fs_ban_cop <= 2) {
1540#ifdef USE_BIT_FIELDS
1541 conparam.s_ban_cop = fs_ban_cop;
1542#else
1543 s_ban_cop = fs_ban_cop;
1544#endif
1545 }
1546#endif
1547 else {
1548 mcerr << "ERROR in inline void set_s_ban_cop(int fs_ban_cop):\n";
1549 mcerr << "s_ban_cop is outside limits, s_ban_cop=" << int(fs_ban_cop)
1550 << '\n';
1551 spexit(mcerr);
1552 }
1553 }
1554
1555#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1556 inline char get_s_ban_cop(void) const
1557#else
1558 inline int get_s_ban_cop(void) const
1559#endif
1560#ifdef USE_BIT_OPERA
1561 {
1562 if ((control_word & eb_s_ban_cop2) == 0) {
1563 if ((control_word & eb_s_ban_cop1) == 0)
1564 return 0;
1565 else
1566 return 1;
1567 } else {
1568 return 2;
1569 }
1570 }
1571#elif defined USE_BIT_FIELDS
1572 { return conparam.s_ban_cop; }
1573#else
1574 { return s_ban_cop; }
1575#endif
1576
1577#ifdef USE_DELETE_AT_ZERO_COUNT
1578
1579#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1580 inline void set_s_allow_del_at_zero_count(char fs_allow_del_at_zero_count)
1581#else
1582 inline void set_s_allow_del_at_zero_count(int fs_allow_del_at_zero_count)
1583#endif
1584 {
1585#ifdef USE_BIT_OPERA
1586 if (fs_allow_del_at_zero_count == 0)
1587 clear_bit(control_word, eb_s_allow_del_at_zero_count);
1588 else if (fs_allow_del_at_zero_count == 1)
1589 rise_bit(control_word, eb_s_allow_del_at_zero_count);
1590#else
1591 if (fs_allow_del_at_zero_count == 0 || fs_allow_del_at_zero_count == 1) {
1592#ifdef USE_BIT_FIELDS
1593 conparam.s_allow_del_at_zero_count = fs_allow_del_at_zero_count;
1594#else
1595 s_allow_del_at_zero_count = fs_allow_del_at_zero_count;
1596#endif
1597 }
1598#endif
1599 else {
1600 mcerr << "ERROR in inline void set_s_allow_del_at_zero_count(int "
1601 "fs_allow_del_at_zero_count):\n";
1602 mcerr << "s_allow_del_at_zero_count is outside limits, "
1603 "s_allow_del_at_zero_count=" << int(fs_allow_del_at_zero_count)
1604 << '\n';
1605 spexit(mcerr);
1606 }
1607 }
1608
1609#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1610 inline char get_s_allow_del_at_zero_count(void) const
1611#else
1612 inline int get_s_allow_del_at_zero_count(void) const
1613#endif
1614#ifdef USE_BIT_OPERA
1615 {
1616 if ((control_word & eb_s_allow_del_at_zero_count) != 0)
1617 return 1;
1618 else
1619 return 0;
1620 }
1621#elif defined(USE_BIT_FIELDS)
1622 { return conparam.s_allow_del_at_zero_count; }
1623#else
1624 { return s_allow_del_at_zero_count; }
1625#endif
1626
1627#endif // for ifdef USE_DELETE_AT_ZERO_COUNT
1628
1629#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1630 inline static void set_s_print_adr_cpp(char fs_print_adr_cpp)
1631#else
1632 inline static void set_s_print_adr_cpp(int fs_print_adr_cpp)
1633#endif
1634 {
1635 if (fs_print_adr_cpp == 0 || fs_print_adr_cpp == 1) {
1636 s_print_adr_cpp = fs_print_adr_cpp;
1637 } else {
1638 mcerr << "ERROR in inline void set_s_print_adr_cpp(int fs_print_adr_cpp "
1639 "):\n";
1640 mcerr << "s_print_adr_cpp is outside limits, s_print_adr_cpp="
1641 << int(fs_print_adr_cpp) << '\n';
1642 spexit(mcerr);
1643 }
1644 }
1645
1646#ifdef USE_CHAR_GETSETTERS_PARAMETERS
1647 inline static char get_s_print_adr_cpp(void)
1648#else
1649 inline static int get_s_print_adr_cpp(void)
1650#endif
1651 {
1652 return s_print_adr_cpp;
1653 }
1654
1655#endif // for ifdef USE_GETSETTERS_IN_PASSIVEPTR
1656
1658
1659 private:
1660 mutable CountPP_ns::CountPassivePtr* cpp; // reference to counter class
1661#ifdef USE_REPLACE_ALLOC
1663#endif
1664};
1665
1667 if (number_of_booked != 0) {
1668 mcerr << "Error in CountPassivePtr::~CountPassivePtr():\n"
1669 << " number_of_booked != 0, number_of_booked=" << number_of_booked
1670 << '\n';
1671 if (rpp != NULL)
1672 mcerr << (*rpp);
1673 else
1674 mcerr << "rpp = NULL\n";
1675 spexit(mcerr);
1676 }
1677 if (rpp != NULL) rpp->cpp = NULL;
1678}
1679
1680template <class X> class PassivePtr virt_common_base_col {
1681 public:
1682 friend class RegPassivePtr;
1683
1684 inline X* get(void) const {
1685 if (cpp == NULL) return NULL;
1686#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1687
1688 if (cpp->get_rpp() == NULL) return NULL;
1689#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
1690 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
1691 if (ptr != temp_ptr) {
1692 mcerr << "Error in inline X* PassivePtr::get(void):\n";
1693 mcerr << "ptr != temp_ptr\n";
1694 spexit(mcerr);
1695 }
1696#endif
1697 return ptr;
1698#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1699
1700#ifdef USE_DYNCAST_IN_PASSIVEPTR
1701 //else return dynamic_cast< X* >
1702 // (const_cast< RegPassivePtr* >( cpp->get_rpp() ) );
1703 const RegPassivePtr* rpp = cpp->get_rpp();
1704 if (rpp == NULL) return NULL;
1705 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(rpp));
1706 if (temp_ptr == NULL) {
1707 mcerr << "Error in inline X* PassivePtr::get(void):\n"
1708 << " dynamic cast from RegPassivePtr to X* is not successful."
1709 << " You have probably tried to address with passive pointer "
1710 << " an object which is not derived from RegPassivePtr\n";
1711 spexit(mcerr);
1712 }
1713 return temp_ptr;
1714#else // for ifdef USE_DYNCAST_IN_PASSIVEPTR
1715 else return (X*)(cpp->get_rpp());
1716#endif // for ifdef USE_DYNCAST_IN_PASSIVEPTR
1717
1718#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1719 }
1720
1721 // Since the pointer is passive, there is no cloning and pass and put
1722 // make the same job.
1723 // 03.06.2006: commenting off pass in order to forbid
1724 // correct for active pointer but
1725 // erroneous for passive pointer statements like ptr.pass(new any_class).
1726 //inline void pass(const X* fptr) {put( fptr );}
1727
1728 inline void put(X* fptr); // unregirster old registered object and
1729 // pass fptr to this.
1730
1731 //void print(std::ostream& file, int l) const
1732 // { if(ptr!=NULL) ptr->print(file, l); }
1733 inline PassivePtr(void)
1734 : cpp(NULL)
1736 ,
1737 ptr(NULL)
1738#endif
1739 {
1740 }
1741 //inline PassivePtr(X* fptr):ptr(fptr)
1742 // { if(ptr!=NULL) ptr->loc_book((void**)&ptr); }
1743 inline PassivePtr(X* fptr) {
1744 if (fptr != NULL)
1745 cpp = fptr->book();
1746 else
1747 cpp = NULL;
1748#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1749 ptr = fptr;
1750#endif
1751 }
1752 //inline PassivePtr(Y* fptr):ptr(fptr)
1753 // { if(ptr!=NULL) ptr->loc_book((void**)&ptr); }
1754 inline PassivePtr(X& fptr) {
1755 cpp = fptr.book();
1756#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1757 ptr = &fptr;
1758#endif
1759 }
1760 //inline PassivePtr(PassivePtr<X>& f);
1761
1762 // The following contractor allows to avoid copying of pointer at s = 0.
1763 // Perhaps it is not necessary
1764 //inline PassivePtr(PassivePtr<X>& f, int s); // s==0 do not copy, s==1 copy
1765 //to new
1766
1767 inline PassivePtr(const PassivePtr<X>& f);
1768 //inline PassivePtr(const PassivePtr<X>& f, int s);
1769 // s==0 do not copy, s==1 copy to new
1770
1773 //template< class Y > explicit operator PassivePtr< Y >() const ; does not
1774 //work,
1775 // produces ambiguity with operators X* and constructors
1776
1777 // Y may be any derived class from X
1778 template <class Y> PassivePtr<X>(const PassivePtr<Y>& f);
1780 // get the pointer from f, clear f,
1781 // put the pointer to this->ptr
1782 // and register it. Thus, the pointer is passed from f to this.
1783
1784 inline X* operator->(void) const;
1785 inline X& operator*(void) const;
1786 inline X* getver(void) const;
1787#ifdef IMPLICIT_X_STAR
1788 inline operator X*(void) const;
1789#endif
1791 if (cpp == NULL)
1792 return 0;
1793 else
1794 return cpp->get_number_of_booked();
1795 }
1796 void print(std::ostream& file, int l = 1) const;
1798 virtual ~PassivePtr();
1799
1800 private:
1802#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1803 X* ptr;
1804#endif
1805#ifdef USE_REPLACE_ALLOC
1807#endif
1808};
1809
1810/*
1811template<class X >
1812template<class Y >
1813PassivePtr<X>::operator PassivePtr<Y>() const { return PassivePtr<Y>(get());}
1814*/
1815
1816template <class X>
1817template <class Y>
1819 : cpp(NULL) {
1820 put((f.get()));
1821}
1822
1823template <class X> void PassivePtr<X>::print(std::ostream& file, int l) const {
1824 Ifile << "PassivePtr<X>:";
1825 if (get() == NULL)
1826 file << " pointer is NULL, no object, number of ref's is "
1827 << get_total_number_of_references() << "\n";
1828 else {
1829 file << noindent;
1830 get()->print(file, l);
1831 file << yesindent;
1832 indn.n += 2;
1833 Ifile << "number of ref's is " << get_total_number_of_references() << '\n';
1834 indn.n -= 2;
1835
1836 }
1837}
1838template <class X>
1839 std::ostream& operator<<(std::ostream& file, const PassivePtr<X>& f) {
1840 Ifile << "PassivePtr<X>:";
1841 if (f.get() == NULL)
1842 file << " pointer is NULL, no object, number of ref's is "
1843 << f.get_total_number_of_references() << "\n";
1844 else {
1845 file << noindent;
1846 file << (*f.get());
1847 file << yesindent;
1848 indn.n += 2;
1849 Ifile << "number of ref's is " << f.get_total_number_of_references()
1850 << '\n';
1851 indn.n -= 2;
1852
1853 }
1854 return file;
1855}
1856
1857template <class X>
1858inline void PassivePtr<X>::put(X* fptr)
1859 // unregirster old registered object and
1860 // pass fptr to this.
1861 {
1862 if (cpp != NULL) {
1863#ifdef USE_DELETE_AT_ZERO_COUNT
1864 const RegPassivePtr* arptr;
1865 if ((arptr = cpp->get_rpp()) != NULL &&
1867 arptr->get_s_allow_del_at_zero_count() == 1 &&
1868#else
1869 arptr->s_allow_del_at_zero_count == 1 &&
1870#endif
1871 cpp->get_number_of_booked() == 1)
1872 delete arptr;
1873// fptr should not be part of old object!
1874#endif
1875 cpp->unbook();
1876 if (cpp->get_rpp() == NULL && cpp->get_number_of_booked() == 0)
1877 // there is no referred object and no other references
1878 delete cpp;
1879 }
1880 if (fptr != NULL)
1881 cpp = fptr->book();
1882 else
1883 cpp = NULL;
1884#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1885 ptr = fptr;
1886#endif
1887}
1888/*
1889template<class X>
1890inline PassivePtr<X>::PassivePtr(PassivePtr<X>& f)
1891{
1892 if(f.cpp != NULL)
1893 {
1894 f.cpp->book();
1895 cpp = f.cpp;
1896 }
1897 else
1898 cpp = NULL;
1899}
1900*/
1901
1902template <class X> inline PassivePtr<X>::PassivePtr(const PassivePtr<X>& f) {
1903 if (f.cpp != NULL) {
1904 f.cpp->book();
1905 cpp = f.cpp;
1906 } else
1907 cpp = NULL;
1908#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1909 ptr = f.ptr;
1910#endif
1911}
1912/*
1913template<class X>
1914inline PassivePtr<X>::PassivePtr(PassivePtr<X>& f, int s)
1915 // s==0 do not copy, s==1 copy to new
1916{
1917 if(f.cpp != NULL && s == 1)
1918 {
1919 f.cpp->book();
1920 cpp = f.cpp;
1921 }
1922 else
1923 cpp = NULL;
1924}
1925
1926template<class X>
1927inline PassivePtr<X>::PassivePtr(const PassivePtr<X>& f, int s)
1928 // s==0 do not copy, s==1 copy to new
1929{
1930 if(f.cpp != NULL && s == 1)
1931 {
1932 f.cpp->book();
1933 cpp = f.cpp;
1934 }
1935 else
1936 cpp = NULL;
1937}
1938*/
1939template <class X>
1941 if (this != &f) put(f.get());
1942 return *this;
1943}
1944
1945template <class X> inline PassivePtr<X>& PassivePtr<X>::operator=(X* f) {
1946 put(f);
1947 return *this;
1948}
1949
1950template <class X> inline void PassivePtr<X>::move_pointer(PassivePtr<X>& f) {
1951 if (cpp != NULL) {
1952#ifdef USE_DELETE_AT_ZERO_COUNT
1953 const RegPassivePtr* arptr;
1954 if ((arptr = cpp->get_rpp()) != NULL &&
1956 arptr->get_s_allow_del_at_zero_count() == 1 &&
1957#else
1958 arptr->s_allow_del_at_zero_count == 1 &&
1959#endif
1960 cpp->get_number_of_booked() == 1)
1961 delete arptr;
1962// fptr should not be part of old object!
1963#endif
1964 cpp->unbook();
1965 if (cpp->get_rpp() == NULL && cpp->get_number_of_booked() == 0) {
1966 delete cpp;
1967 cpp = NULL;
1968 }
1969 }
1970 cpp = f.cpp;
1971 if (cpp != NULL) cpp->book();
1972#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1973 ptr = f.ptr;
1974#endif
1975 f.put(NULL);
1976}
1977
1978template <class X> inline X* PassivePtr<X>::operator->(void) const {
1979#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
1980#ifdef SKIP_CHECKS_NULL
1981 return ptr;
1982#else
1983 if (cpp == NULL) {
1984 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: cpp == NULL\n";
1985 mcerr << "This means that the pointer is emtpy, "
1986 << "there is no addressed object.\n";
1987 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1988 << '\n';
1989 spexit(mcerr);
1990 }
1991 if (cpp->get_rpp() == NULL) {
1992 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: "
1993 "cpp->get_rpp() == NULL\n";
1994 mcerr << "This means that the pointer is emtpy, "
1995 << "there is no addressed object.\n";
1996 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
1997 << '\n';
1998 spexit(mcerr);
1999 }
2000#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
2001 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
2002 if (ptr != temp_ptr) {
2003 mcerr << "Error in inline X* PassivePtr::operator->(void):\n";
2004 mcerr << "ptr != temp_ptr\n";
2005 spexit(mcerr);
2006 }
2007#endif
2008 return ptr;
2009#endif // for ifdef SKIP_CHECKS_NULL
2010#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2011#ifdef SKIP_CHECKS_NULL
2012 const RegPassivePtr* rpp = cpp->get_rpp();
2013#else
2014 if (cpp == NULL) {
2015 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: cpp == NULL\n";
2016 mcerr << "This means that the pointer is emtpy, "
2017 << "there is no addressed object.\n";
2018 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2019 << '\n';
2020 spexit(mcerr);
2021 }
2022 const RegPassivePtr* rpp;
2023 if ((rpp = cpp->get_rpp()) == NULL) {
2024 mcerr << "Error in X* PassivePtr<X>::operator->(void) const: "
2025 "cpp->get_rpp() == NULL\n";
2026 mcerr << "This means that the pointer is emtpy, "
2027 << "there is no addressed object.\n";
2028 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2029 << '\n';
2030 spexit(mcerr);
2031 }
2032#endif
2033#ifdef USE_DYNCAST_IN_PASSIVEPTR
2034 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(rpp));
2035 if (temp_ptr == NULL) {
2036 mcerr << "Error in X* PassivePtr<X>::operator->(void) const:\n"
2037 << " dynamic cast from RegPassivePtr to X* is not successful"
2038 << " (although the addresses of counter and abject are not zero)."
2039 << " You have probably initialized passive pointer "
2040 << " with address of deleted object\n";
2041 //<<" You have probably tried to address with passive pointer "
2042 //<<" an object which is not derived from RegPassivePtr\n";
2043 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2044 << '\n';
2045 spexit(mcerr);
2046 }
2047 return temp_ptr;
2048#else
2049 return (X*)(rpp);
2050#endif
2051#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2052}
2053
2054template <class X> inline X& PassivePtr<X>::operator*(void) const {
2055//mcout<<"PassivePtr<X>::operator* is called\n";
2056#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2057#ifdef SKIP_CHECKS_NULL
2058 return *ptr;
2059#else
2060 if (cpp == NULL) {
2061 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp == NULL\n";
2062 mcerr << "This means that the pointer is emtpy, "
2063 << "there is no addressed object.\n";
2064 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2065 << '\n';
2066 spexit(mcerr);
2067 }
2068 if (cpp->get_rpp() == NULL) {
2069 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp->get_rpp() "
2070 "== NULL\n";
2071 mcerr << "This means that the pointer is emtpy, "
2072 << "there is no addressed object.\n";
2073 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2074 << '\n';
2075 spexit(mcerr);
2076 }
2077#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
2078 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
2079 if (ptr != temp_ptr) {
2080 mcerr << "Error in inline X& PassivePtr::operator*(void):\n";
2081 mcerr << "ptr != temp_ptr\n";
2082 spexit(mcerr);
2083 }
2084#endif
2085 return *ptr;
2086#endif // for ifdef SKIP_CHECKS_NULL
2087#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2088#ifdef SKIP_CHECKS_NULL
2089 static const RegPassivePtr* rpp = cpp->get_rpp();
2090#else
2091 if (cpp == NULL) {
2092 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp == NULL\n";
2093 mcerr << "This means that the pointer is emtpy, "
2094 << "there is no addressed object.\n";
2095 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2096 << '\n';
2097 spexit(mcerr);
2098 }
2099 static const RegPassivePtr* rpp;
2100 // I have put static here only to avoid
2101 // perhaps erroneous warning which appear
2102 // in compiler : gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
2103 // This is old compiler. At newer ones there is no problems.
2104 // The message is
2105 // AbsPtr.h:997: warning: reference to local variable `rpp' returned
2106 // This is in fact wrong statement, but so as not to make users thinking
2107 // about it, I made this variable static.
2108
2109 if ((rpp = cpp->get_rpp()) == NULL) {
2110 mcerr << "Error in X& PassivePtr<X>::operator*(void) const: cpp->get_rpp() "
2111 "== NULL\n";
2112 mcerr << "This means that the pointer is emtpy, "
2113 << "there is no addressed object.\n";
2114 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2115 << '\n';
2116 spexit(mcerr);
2117 }
2118#endif
2119#ifdef USE_DYNCAST_IN_PASSIVEPTR
2120 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(rpp));
2121 if (temp_ptr == NULL) {
2122 mcerr << "Error in X& PassivePtr<X>::operator*(void) const:\n"
2123 << " dynamic cast from RegPassivePtr to X* is not successful."
2124 << " You have probably tried to address with passive pointer "
2125 << " an object which is not derived from RegPassivePtr\n";
2126 spexit(mcerr);
2127 }
2128 return *temp_ptr;
2129#else
2130 return *((X*)(rpp));
2131#endif
2132#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2133}
2134
2135template <class X> inline X* PassivePtr<X>::getver(void) const {
2136#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2137#ifdef SKIP_CHECKS_NULL
2138 return ptr;
2139#else
2140 if (cpp == NULL) {
2141 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp == NULL\n";
2142 mcerr << "This means that the pointer is emtpy, "
2143 << "there is no addressed object.\n";
2144 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2145 << '\n';
2146 spexit(mcerr);
2147 }
2148 if (cpp->get_rpp() == NULL) {
2149 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp->get_rpp() == "
2150 "NULL\n";
2151 mcerr << "This means that the pointer is emtpy, "
2152 << "there is no addressed object.\n";
2153 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2154 << '\n';
2155 spexit(mcerr);
2156 }
2157#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
2158 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
2159 if (ptr != temp_ptr) {
2160 mcerr << "Error in inline X* PassivePtr::getver(void):\n";
2161 mcerr << "ptr != temp_ptr\n";
2162 spexit(mcerr);
2163 }
2164#endif
2165 return ptr;
2166#endif // for ifdef SKIP_CHECKS_NULL
2167#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2168#ifdef SKIP_CHECKS_NULL
2169 const RegPassivePtr* rpp = cpp->get_rpp();
2170#else
2171 if (cpp == NULL) {
2172 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp == NULL\n";
2173 mcerr << "This means that the pointer is emtpy, "
2174 << "there is no addressed object.\n";
2175 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2176 << '\n';
2177 spexit(mcerr);
2178 }
2179 const RegPassivePtr* rpp;
2180 if ((rpp = cpp->get_rpp()) == NULL) {
2181 mcerr << "Error in X* PassivePtr<X>::getver(void) const: cpp->get_rpp() == "
2182 "NULL\n";
2183 mcerr << "This means that the pointer is emtpy, "
2184 << "there is no addressed object.\n";
2185 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2186 << '\n';
2187 spexit(mcerr);
2188 }
2189#endif
2190#ifdef USE_DYNCAST_IN_PASSIVEPTR
2191 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(rpp));
2192 if (temp_ptr == NULL) {
2193 mcerr << "Error in X* PassivePtr<X>::getver(void) const:\n"
2194 << " dynamic cast from RegPassivePtr to X* is not successful."
2195 << " You have probably tried to address with passive pointer "
2196 << " an object which is not derived from RegPassivePtr\n";
2197 spexit(mcerr);
2198 }
2199 return temp_ptr;
2200#else
2201 return (X*)(rpp);
2202#endif
2203#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2204}
2205
2206#ifdef IMPLICIT_X_STAR
2207template <class X> inline PassivePtr<X>::operator X*(void) const {
2208#ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2209#ifdef SKIP_CHECKS_NULL
2210 return ptr;
2211#else
2212 if (cpp == NULL) {
2213 mcerr << "Error in PassivePtr<X>::operator X*(void) const: cpp == NULL\n";
2214 mcerr << "This means that the pointer is emtpy, "
2215 << "there is no addressed object.\n";
2216 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2217 << '\n';
2218 spexit(mcerr);
2219 }
2220 if (cpp->get_rpp() == NULL) {
2221 mcerr << "Error in X* PassivePtr<X>::operator X*(void) const: "
2222 "cpp->get_rpp() == NULL\n";
2223 mcerr << "This means that the pointer is emtpy, "
2224 << "there is no addressed object.\n";
2225 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2226 << '\n';
2227 spexit(mcerr);
2228 }
2229#ifdef USE_CHECK_DOUBLE_PTR_IN_PASSIVEPTR
2230 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(cpp->get_rpp()));
2231 if (ptr != temp_ptr) {
2232 mcerr << "Error in inline X* PassivePtr::operator X*(void):\n";
2233 mcerr << "ptr != temp_ptr\n";
2234 spexit(mcerr);
2235 }
2236#endif
2237 return ptr;
2238#endif // for ifdef SKIP_CHECKS_NULL
2239#else // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2240#ifdef SKIP_CHECKS_NULL
2241 const RegPassivePtr* rpp = cpp->get_rpp();
2242#else
2243 if (cpp == NULL) {
2244 mcerr
2245 << "Error in X* PassivePtr<X>::operator X*(void) const: cpp == NULL\n";
2246 mcerr << "This means that the pointer is emtpy, "
2247 << "there is no addressed object.\n";
2248 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2249 << '\n';
2250 spexit(mcerr);
2251 }
2252 const RegPassivePtr* rpp;
2253 if ((rpp = cpp->get_rpp()) == NULL) {
2254 mcerr << "Error in X* PassivePtr<X>::operator X*(void) const: "
2255 "cpp->get_rpp() == NULL\n";
2256 mcerr << "This means that the pointer is emtpy, "
2257 << "there is no addressed object.\n";
2258 mcerr << "Type of X is (in internal notations) " << typeid(X).name()
2259 << '\n';
2260 spexit(mcerr);
2261 }
2262#endif
2263#ifdef USE_DYNCAST_IN_PASSIVEPTR
2264 X* temp_ptr = dynamic_cast<X*>(const_cast<RegPassivePtr*>(rpp));
2265 if (temp_ptr == NULL) {
2266 mcerr << "Error in X* PassivePtr<X>::operator X*(void) const:\n"
2267 << " dynamic cast from RegPassivePtr to X* is not successful."
2268 << " You have probably tried to address with passive pointer "
2269 << " an object which is not derived from RegPassivePtr\n";
2270 spexit(mcerr);
2271 }
2272 return temp_ptr;
2273#else
2274 return (X*)(rpp);
2275#endif
2276#endif // for ifdef USE_DOUBLE_PTR_IN_PASSIVEPTR
2277}
2278#endif
2279template <class X>
2280 inline int operator==(const PassivePtr<X>& f1,
2281 const PassivePtr<X>&
2282 f2) { // comparison of addresses, so it mimics
2283 // regular pointers
2284 return f1.get() == f2.get();
2285}
2286
2287template <class X> PassivePtr<X>::~PassivePtr() {
2288 if (cpp != NULL) {
2289//mcout<<"PassivePtr<X>::~PassivePtr(): &ptr="<<&ptr<<" *ptr="<<*ptr<<'\n';
2290#ifdef USE_DELETE_AT_ZERO_COUNT
2291 const RegPassivePtr* arptr;
2292 if ((arptr = cpp->get_rpp()) != NULL &&
2294 arptr->get_s_allow_del_at_zero_count() == 1 &&
2295#else
2296 arptr->s_allow_del_at_zero_count == 1 &&
2297#endif
2298 cpp->get_number_of_booked() == 1)
2299 delete arptr;
2300#endif
2301 cpp->unbook();
2302 //mcout<<"PassivePtr<X>::~PassivePtr(): &ptr="<<&ptr<<" *ptr="<<*ptr<<'\n';
2303 if (cpp->get_rpp() == NULL && cpp->get_number_of_booked() == 0) {
2304 delete cpp;
2305 cpp = NULL;
2306 }
2307 }
2308}
2309
2310template <class X>
2312 PassivePtr<X> f2) // necessary for std::set
2313 {
2314 return f1.get() < f2.get();
2315}
2316
2317#define USE_OLD_POINTER_NAMES
2318#ifdef USE_OLD_POINTER_NAMES
2319#define AutoContReg ActivePtrReg
2320#endif
2321
2322template <class X, class C = StandardCopyDefinition<X> >
2323class ActivePtrReg : public RegPassivePtr,
2324 public ActivePtr<X, C> {
2325 public:
2326 inline ActivePtrReg(void) : RegPassivePtr(), ActivePtr<X, C>() {}
2327 inline ActivePtrReg(const X* fptr, Clone)
2328 : RegPassivePtr(), ActivePtr<X, C>(fptr, do_clone) {}
2329 inline ActivePtrReg(const X* fptr, Pass)
2330 : RegPassivePtr(), ActivePtr<X, C>(fptr, dont_clone) {}
2331
2333 : RegPassivePtr(), ActivePtr<X, C>(f) {}
2335 : RegPassivePtr(), ActivePtr<X, C>(f) {}
2337 if (this != &f) put(f.get());
2338 return *this;
2339 }
2340 virtual void print(std::ostream& file, int l = 1) const;
2342 virtual ~ActivePtrReg() {}
2343#ifdef USE_REPLACE_ALLOC
2345#endif
2346};
2347
2348template <class X, class C>
2349void ActivePtrReg<X, C>::print(std::ostream& file, int l) const {
2350 //if(ptr!=NULL) ptr->print(file, l);
2351 Ifile << "ActivePtrReg<X,C>:\n";
2352 indn.n += 2;
2353 RegPassivePtr::print(file, l);
2354 ActivePtr<X, C>::print(file, l);
2355 indn.n -= 2;
2356}
2357
2358template <class X>
2359 std::ostream& operator<<(std::ostream& file, const ActivePtrReg<X>& f) {
2360 Ifile << "ActivePtrReg<X>:";
2361 file << noindent;
2362 file << (ActivePtr<X>&)f;
2363 file << yesindent;
2364 return file;
2365}
2366
2367#ifdef INCLUDE_ActivePtrWI
2368
2369#define USE_OLD_POINTER_NAMES
2370#ifdef USE_OLD_POINTER_NAMES
2371#define AutoPtrReg ActivePtrWIReg
2372#endif
2373
2374template <class X>
2375class ActivePtrWIReg : public RegPassivePtr,
2376 public ActivePtrWI<X> {
2377 public:
2378 inline ActivePtrWIReg(void) : ActivePtrWI<X>(), RegPassivePtr() {}
2379 inline ActivePtrWIReg(const X* fptr)
2380 : ActivePtrWI<X>(fptr), RegPassivePtr() {}
2381 inline ActivePtrWIReg(ActivePtrWIReg<X>& f)
2382 : ActivePtrWI<X>(fptr), RegPassivePtr() {}
2383 inline ActivePtrWIReg(const ActivePtrWIReg<X>& f)
2384 : ActivePtrWI<X>(fptr), RegPassivePtr() {}
2385 inline ActivePtrWIReg& operator=(const ActivePtrWIReg<X>& f) {
2386 if (this != &f) put(f.get());
2387 return *this;
2388 }
2389 virtual ~ActivePtrWIReg() {}
2390#ifdef USE_REPLACE_ALLOC
2392#endif
2393};
2394#endif
2395
2396class DoubleReg : public RegPassivePtr {
2397 public:
2398 double val;
2399 inline DoubleReg(void) : val(0) {}
2400 inline DoubleReg(const DoubleReg& f) : RegPassivePtr(), val(f.val) {}
2401 inline DoubleReg(double f) : RegPassivePtr(), val(f) {}
2402 inline operator double(void) { return val; }
2403#ifdef USE_REPLACE_ALLOC
2405#endif
2406};
2407
2408std::ostream& operator<<(std::ostream& file, const DoubleReg& f);
2409#endif
int operator==(const PassivePtr< X > &f1, const PassivePtr< X > &f2)
Definition: AbsPtr.h:2280
bool operator<(PassivePtr< X > f1, PassivePtr< X > f2)
Definition: AbsPtr.h:2311
Pilfer
Definition: AbsPtr.h:512
@ steal
Definition: AbsPtr.h:513
#define USE_PRIVATE_PARAM_IN_PASSIVEPTR
Definition: AbsPtr.h:165
void exchange(ActivePtr< X, C > &f1, ActivePtr< X, C > &f2)
Definition: AbsPtr.h:879
Clone
Definition: AbsPtr.h:515
@ do_clone
Definition: AbsPtr.h:516
#define PILF_MUTABLE
Definition: AbsPtr.h:143
Pass
Definition: AbsPtr.h:518
@ dont_clone
Definition: AbsPtr.h:519
#define USE_DOUBLE_PTR_IN_PASSIVEPTR
Definition: AbsPtr.h:41
std::ostream & operator<<(std::ostream &file, const AbsCont &f)
Definition: AbsPtr.h:337
std::istream & operator>>(std::istream &file, ActivePtr< X, C > &f)
Definition: AbsPtr.h:793
#define PILF_CONST
Definition: AbsPtr.h:142
#define USE_DELETE_AT_ZERO_COUNT
Definition: AbsPtr.h:50
DoubleAc operator*(const DoubleAc &f1, const DoubleAc &f2)
Definition: DoubleAc.h:524
#define spexit(stream)
Definition: FunNameStack.h:536
#define macro_alloc
Definition: ReplaceAlloc.h:10
virtual ~AbsCont()
Definition: AbsPtr.h:285
virtual void print(std::ostream &file, int l) const
Definition: AbsPtr.h:282
virtual AbsCont * copy(void) const =0
ActivePtrReg(const X *fptr, Clone)
Definition: AbsPtr.h:2327
ActivePtrReg(const ActivePtrReg< X, C > &f)
Definition: AbsPtr.h:2334
virtual ~ActivePtrReg()
Definition: AbsPtr.h:2342
macro_copy_total(ActivePtrReg)
ActivePtrReg(void)
Definition: AbsPtr.h:2326
ActivePtrReg & operator=(const ActivePtrReg< X, C > &f)
Definition: AbsPtr.h:2336
ActivePtrReg(ActivePtrReg< X, C > &f)
Definition: AbsPtr.h:2332
ActivePtrReg(const X *fptr, Pass)
Definition: AbsPtr.h:2329
virtual void print(std::ostream &file, int l=1) const
Definition: AbsPtr.h:2349
static X * copy(const X *f)
Definition: AbsPtr.h:482
void change_rpp(const RegPassivePtr *frpp)
Definition: AbsPtr.h:1041
CountPassivePtr(const RegPassivePtr *frpp)
Definition: AbsPtr.h:1033
long get_number_of_booked(void)
Definition: AbsPtr.h:1039
const RegPassivePtr * get_rpp(void)
Definition: AbsPtr.h:1040
DoubleReg(double f)
Definition: AbsPtr.h:2401
DoubleReg(void)
Definition: AbsPtr.h:2399
DoubleReg(const DoubleReg &f)
Definition: AbsPtr.h:2400
double val
Definition: AbsPtr.h:2398
static X * copy(const X *f)
Definition: AbsPtr.h:353
void pilfer(PILF_CONST ActivePtr< X, C > &f)
Attention: actually not const.
Definition: AbsPtr.h:619
X * extract(void)
Definition: AbsPtr.h:604
ActivePtr & operator=(const ActivePtr< X, C > &f)
Definition: AbsPtr.h:700
void put(const X *fptr)
Definition: AbsPtr.h:551
char get_s_ban_cop(void) const
Definition: AbsPtr.h:1556
char get_s_allow_del_at_zero_count(void) const
Definition: AbsPtr.h:1610
PassivePtr(X *fptr)
Definition: AbsPtr.h:1743
PassivePtr(X &fptr)
Definition: AbsPtr.h:1754
static char get_s_print_adr_cpp(void)
Definition: AbsPtr.h:1647
virtual void print(std::ostream &file, int l=1) const
void put(X *fptr)
RegPassivePtr(const RegPassivePtr &f)
X * operator->(void) const
CountPP_ns::CountPassivePtr * book(void) const
Definition: AbsPtr.h:1243
char get_s_ban_sub(void) const
Definition: AbsPtr.h:1498
long get_total_number_of_references(void) const
X & operator*(void) const
static char get_s_ban_del_ignore(void)
Definition: AbsPtr.h:1455
void set_s_allow_del_at_zero_count(char fs_allow_del_at_zero_count)
Definition: AbsPtr.h:1580
PassivePtr< X > & operator=(X *f)
void set_s_ban_sub(char fs_ban_sub)
Definition: AbsPtr.h:1464
void pass(X *fptr)
Definition: AbsPtr.h:574
void set_s_ban_del(char fs_ban_del)
Definition: AbsPtr.h:1392
virtual ~RegPassivePtr()
void set_s_ban_cop(char fs_ban_cop)
Definition: AbsPtr.h:1522
X * get(void) const
Definition: AbsPtr.h:541
ActivePtr(const ActivePtr< X, C > &f)
Definition: AbsPtr.h:677
virtual ~ActivePtr()
Definition: AbsPtr.h:709
RegPassivePtr(char fs_ban_del, char fs_ban_sub, char fs_ban_cop=0)
Definition: AbsPtr.h:1209
void clear_pointers(void) const
Definition: AbsPtr.h:1251
void move_pointer(PassivePtr< X > &f)
char get_s_ban_del(void) const
Definition: AbsPtr.h:1420
macro_copy_total(PassivePtr)
static void set_s_print_adr_cpp(char fs_print_adr_cpp)
Definition: AbsPtr.h:1630
void clear(void)
Definition: AbsPtr.h:609
macro_copy_total(RegPassivePtr)
PassivePtr< X > & operator=(const PassivePtr< X > &f)
X * getver(void) const
ActivePtr(const X *fptr, Clone)
Definition: AbsPtr.h:659
void print(std::ostream &file, int l=1) const
macro_copy_total(ActivePtr)
ActivePtr(PILF_CONST ActivePtr< X, C > &f, Pilfer)
Definition: AbsPtr.h:689
RegPassivePtr & operator=(const RegPassivePtr &f)
ActivePtr(X *fptr, Pass)
Definition: AbsPtr.h:698
static void set_s_ban_del_ignore(char fs_ban_del_ignore)
Definition: AbsPtr.h:1438
PassivePtr(const PassivePtr< X > &f)
indentation indn
Definition: prstream.cpp:13
std::ostream & yesindent(std::ostream &f)
Definition: prstream.cpp:19
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:15
#define mcout
Definition: prstream.h:133
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
#define Iprintn(file, name)
Definition: prstream.h:216
std::ostream & operator<<(std::ostream &file, const trajestep &f)
Definition: trajestep.cpp:137