/home/docs/checkouts/readthedocs.org/user_builds/ratpac/checkouts/latest/src/external/stlplus/include/stlplus/smart_ptr.hpp Source File

Ratpac-two: /home/docs/checkouts/readthedocs.org/user_builds/ratpac/checkouts/latest/src/external/stlplus/include/stlplus/smart_ptr.hpp Source File
Ratpac-two
smart_ptr.hpp
1 #ifndef SMART_PTR_HPP
2 #define SMART_PTR_HPP
3 /*------------------------------------------------------------------------------
4 
5  Author: Andy Rushton and Daniel Milton
6  Copyright: (c) Andy Rushton, 2004; Daniel Milton 2005
7  License: BSD License, see ../docs/license.html
8 
9  Dan Milton: three simple pointer containers with single level access:
10  - simple_ptr for simple types and classes
11  - simple_ptr_clone for polymorphic class hierarchies
12  - simple_ptr_nocopy for any class that cannot or should no be copied
13 
14  Andy Rushton: three smart pointer containers with two-layer access:
15  - smart_ptr for simple types and classes
16  - smart_ptr_clone for polymorphic class hierarchies
17  - smart_ptr_nocopy for any class that cannot or should no be copied
18 
19  ------------------------------------------------------------------------------*/
20 #include <map>
21 #include <string>
22 
23 #include "exceptions.hpp"
24 #include "os_fixes.hpp"
25 #include "persistent.hpp"
26 #include "textio.hpp"
27 
30 // Simple pointer class
33 
34 template <typename T>
35 class simple_ptr {
36  public:
38  // member type definitions
39 
40  typedef T value_type;
41  typedef T& reference;
42  typedef const T& const_reference;
43 
45  // constructors, assignments and destructors
46 
47  // create a null pointer
48  simple_ptr(void);
49 
50  // create a pointer containing a *copy* of the object
51  // this copy is taken because the pointer class maintains a dynamically allocated object
52  // and the T& may not be (usually is not) dynamically allocated
53  // constructor form
54  simple_ptr(const T& data);
55  // assignment form for an already-constructed smart-pointer
56  simple_ptr<T>& operator=(const T& data);
57 
58  // copy constructor implements counted referencing - no copy is made
59  simple_ptr(const simple_ptr<T>& r);
60  // assignment of smart pointers implement counted referencing - no copy is made
61  simple_ptr<T>& operator=(const simple_ptr<T>&);
62 
63  // create a pointer containing a dynamically created object
64  // Note: the object must be allocated *by the user* with new
65  // constructor form - must be called in the form simple_ptr<type> x(new type(args))
66  explicit simple_ptr(T* data);
67  // assignment form
68  simple_ptr<T>& operator=(T* data);
69 
70  // destructor decrements the reference count and delete only when the last reference is destroyed
71  ~simple_ptr(void);
72 
74  // logical tests to see if there is anything contained in the pointer since it can be null
75 
76  // there are two forms:explicit and implicit
77  // implicit: if(!r) or if(r)
78  // explicit: if(r.null()) or if(r.present())
79  operator bool(void) const;
80  bool operator!(void) const;
81  bool present(void) const;
82  bool null(void) const;
83 
85  // dereference operators and functions
86 
87  // dereference the smart pointer to get the object - use in the form *p1
88  T& operator*(void) throw();
89  const T& operator*(void) const throw();
90 
91  // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
92  T* operator->(void) throw();
93  const T* operator->(void) const throw();
94 
96  // explicit function forms of the above assignment and dereference operators
97 
98  // set the value
99  void set_value(const T& data);
100  // get the value
101  T& value(void) throw();
102  const T& value(void) const throw();
103 
104  // set the pointer
105  // deletes the previous pointer and adopts the passed pointer instead
106  // Note: the object must be allocated *by the user* with new
107  // Warning: it is very easy to break the memory management with this operation
108  void set(T* data = 0);
109  // get the pointer
110  T* pointer(void);
111  const T* pointer(void) const;
112 
114  // functions to manage counted referencing
115 
116  // test whether two pointers point to the same object(known as aliasing the object)
117  // used in the form if(a.aliases(b))
118  bool aliases(const simple_ptr<T>&) const;
119 
120  // find the number of aliases - used when you need to know whether an object is still referred to from elsewhere
121  // (rare!)
122  unsigned alias_count(void) const;
123 
124  // make this pointer unique with respect to any other references to the same object
125  // if this pointer is already unique, it does nothing - otherwise it copies the object
126  void make_unique(void);
127 
128  // delete the object and make the pointer null - does not make it unique first, so all other pointers to this will be
129  // null too
130  void clear(void);
131 
132  // make the pointer unique and null in one step - does not affect other pointers that were pointing to the same object
133  void clear_unique(void);
134 
135  // make this pointer a unique copy of the parameter
136  // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
137  void copy(const simple_ptr<T>&);
138  // alternate form used in assignments: p1 = ps.copy()
139  simple_ptr<T> copy(void) const;
140 
141  // persistence functions
142  void dump(dump_context& str) const throw();
143  void restore(restore_context& str) throw();
144 
145  protected:
146  T* m_pointer;
147  unsigned* m_count;
148 };
149 
151 // comparisons required for using this class in an STL container
152 // These require == and < operator in the contained type T
153 // the remaining relational operators are provided by template functions
154 // a null pointer is less-than a non-null, two nulls are equal
155 // these funcions are defined as non-members so that you only need provide
156 // the underlying T::operator< and == if you are going to use these functions
157 
158 template <typename T>
159 bool operator==(const simple_ptr<T>&, const simple_ptr<T>&);
160 
161 template <typename T>
162 bool operator<(const simple_ptr<T>&, const simple_ptr<T>&);
163 
165 // string/print utilities
166 
167 template <typename T>
168 std::string simple_ptr_to_string(const simple_ptr<T>& ptr, std::string null_string);
169 
170 template <typename T>
171 otext& print_simple_ptr(otext& str, const simple_ptr<T>& ptr, std::string null_string);
172 
173 template <typename T>
174 otext& print_simple_ptr(otext& str, const simple_ptr<T>& ptr, unsigned indent, std::string null_string);
175 
177 // persistence - call these rather than the methods
178 // the dump routine dumps simple_ptr-specific information and then calls dump_pointer on the contents
179 // similarly the restore routine calls restore_pointer
180 // so therefore the class T should have non-member dump/restore functions
181 
182 template <typename T>
183 void dump_simple_ptr(dump_context& str, const simple_ptr<T>& data) throw();
184 
185 template <typename T>
186 void restore_simple_ptr(restore_context& str, simple_ptr<T>& data) throw();
187 
190 // Cloning simple pointer class for polymorphic class hierarchies
191 // The contained class T should implement the clonable interface defined in clonable.hpp
194 
195 template <typename T>
197  public:
199  // member type definitions
200 
201  typedef T value_type;
202  typedef T& reference;
203  typedef const T& const_reference;
204 
206  // constructors, assignments and destructors
207 
208  // create a null pointer
209  simple_ptr_clone(void);
210 
211  // create a pointer containing a *copy* of the object
212  // this copy is taken because the pointer class maintains a dynamically allocated object
213  // and the T& may not be (usually is not) dynamically allocated
214  // constructor form
215  simple_ptr_clone(const T& data);
216  // assignment form for an already-constructed smart-pointer
217  simple_ptr_clone<T>& operator=(const T& data);
218 
219  // copy constructor implements counted referencing - no copy is made
221  // assignment of smart pointers implement counted referencing - no copy is made
222  simple_ptr_clone<T>& operator=(const simple_ptr_clone<T>&);
223 
224  // create a pointer containing a dynamically created object
225  // Note: the object must be allocated *by the user* with new
226  // constructor form - must be called in the form simple_ptr_clone<type> x(new type(args))
227  explicit simple_ptr_clone(T* data);
228  // assignment form
229  simple_ptr_clone<T>& operator=(T* data);
230 
231  // destructor decrements the reference count and delete only when the last reference is destroyed
232  ~simple_ptr_clone(void);
233 
235  // logical tests to see if there is anything contained in the pointer since it can be null
236 
237  // there are two forms:explicit and implicit
238  // implicit: if(!r) or if(r)
239  // explicit: if(r.null()) or if(r.present())
240  operator bool(void) const;
241  bool operator!(void) const;
242  bool present(void) const;
243  bool null(void) const;
244 
246  // dereference operators and functions
247 
248  // dereference the smart pointer to get the object - use in the form *p1
249  T& operator*(void) throw();
250  const T& operator*(void) const throw();
251 
252  // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
253  T* operator->(void) throw();
254  const T* operator->(void) const throw();
255 
257  // explicit function forms of the above assignment and dereference operators
258 
259  // set the value
260  void set_value(const T& data);
261  // get the value
262  T& value(void) throw();
263  const T& value(void) const throw();
264 
265  // set the pointer
266  // deletes the previous pointer and adopts the passed pointer instead
267  // Note: the object must be allocated *by the user* with new
268  // Warning: it is very easy to break the memory management with this operation
269  void set(T* data = 0);
270  // get the pointer
271  T* pointer(void);
272  const T* pointer(void) const;
273 
275  // functions to manage counted referencing
276 
277  // test whether two pointers point to the same object(known as aliasing the object)
278  // used in the form if(a.aliases(b))
279  bool aliases(const simple_ptr_clone<T>&) const;
280 
281  // find the number of aliases - used when you need to know whether an object is still referred to from elsewhere
282  // (rare!)
283  unsigned alias_count(void) const;
284 
285  // make this pointer unique with respect to any other references to the same object
286  // if this pointer is already unique, it does nothing - otherwise it copies the object
287  void make_unique(void);
288 
289  // delete the object and make the pointer null - does not make it unique first, so all other pointers to this will be
290  // null too
291  void clear(void);
292 
293  // make the pointer unique and null in one step - does not affect other pointers that were pointing to the same object
294  void clear_unique(void);
295 
296  // make this pointer a unique copy of the parameter
297  // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
298  void copy(const simple_ptr_clone<T>&);
299  // alternate form used in assignments: p1 = ps.copy()
300  simple_ptr_clone<T> copy(void) const;
301 
302  // persistence functions
303  void dump(dump_context& str) const throw();
304  void restore(restore_context& str) throw();
305 
306  protected:
307  T* m_pointer;
308  unsigned* m_count;
309 };
310 
312 // comparisons required for using this class in an STL container
313 // These require == and < operator in the contained type T
314 // the remaining relational operators are provided by template functions
315 // a null pointer is less-than a non-null, two nulls are equal
316 // these funcions are defined as non-members so that you only need provide
317 // the underlying T::operator< and == if you are going to use these functions
318 
319 template <typename T>
320 bool operator==(const simple_ptr_clone<T>&, const simple_ptr_clone<T>&);
321 
322 template <typename T>
323 bool operator<(const simple_ptr_clone<T>&, const simple_ptr_clone<T>&);
324 
326 // string/print utilities
327 
328 template <typename T>
329 std::string simple_ptr_clone_to_string(const simple_ptr_clone<T>& ptr, std::string null_string);
330 
331 template <typename T>
332 otext& print_simple_ptr_clone(otext& str, const simple_ptr_clone<T>& ptr, std::string null_string);
333 
334 template <typename T>
335 otext& print_simple_ptr_clone(otext& str, const simple_ptr_clone<T>& ptr, unsigned indent, std::string null_string);
336 
338 // persistence - call these rather than the methods
339 // the dump routine dumps simple_ptr_clone-specific information and then calls dump_interface
340 // similarly the restore routine calls restore_interface
341 // so therefore the class T should implement the persistent interface defined by the class persistent in persistent.hpp
342 
343 template <typename T>
344 void dump_simple_ptr_clone(dump_context& str, const simple_ptr_clone<T>& data) throw();
345 
346 template <typename T>
347 void restore_simple_ptr_clone(restore_context& str, simple_ptr_clone<T>& data) throw();
348 
351 // No-copy simple pointer class for managing objects that cannot be copied
354 
355 template <typename T>
357  public:
359  // member type definitions
360 
361  typedef T value_type;
362  typedef T& reference;
363  typedef const T& const_reference;
364 
366  // constructors, assignments and destructors
367 
368  // create a null pointer
369  simple_ptr_nocopy(void);
370 
371  // copy constructor implements counted referencing - no copy is made
373  // assignment of smart pointers implement counted referencing - no copy is made
374  simple_ptr_nocopy<T>& operator=(const simple_ptr_nocopy<T>&);
375 
376  // create a pointer containing a dynamically created object
377  // Note: the object must be allocated *by the user* with new
378  // constructor form - must be called in the form simple_ptr_nocopy<type> x(new type(args))
379  explicit simple_ptr_nocopy(T* data);
380  // assignment form
381  simple_ptr_nocopy<T>& operator=(T* data);
382 
383  // destructor decrements the reference count and delete only when the last reference is destroyed
384  ~simple_ptr_nocopy(void);
385 
387  // logical tests to see if there is anything contained in the pointer since it can be null
388 
389  // there are two forms:explicit and implicit
390  // implicit: if(!r) or if(r)
391  // explicit: if(r.null()) or if(r.present())
392  operator bool(void) const;
393  bool operator!(void) const;
394  bool present(void) const;
395  bool null(void) const;
396 
398  // dereference operators and functions
399 
400  // dereference the smart pointer to get the object - use in the form *p1
401  T& operator*(void) throw();
402  const T& operator*(void) const throw();
403 
404  // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
405  T* operator->(void) throw();
406  const T* operator->(void) const throw();
407 
409  // explicit function forms of the above assignment and dereference operators
410 
411  // get the value
412  T& value(void) throw();
413  const T& value(void) const throw();
414 
415  // set the pointer
416  // deletes the previous pointer and adopts the passed pointer instead
417  // Note: the object must be allocated *by the user* with new
418  // Warning: it is very easy to break the memory management with this operation
419  void set(T* data = 0);
420  // get the pointer
421  T* pointer(void);
422  const T* pointer(void) const;
423 
425  // functions to manage counted referencing
426 
427  // test whether two pointers point to the same object(known as aliasing the object)
428  // used in the form if(a.aliases(b))
429  bool aliases(const simple_ptr_nocopy<T>&) const;
430 
431  // find the number of aliases - used when you need to know whether an object is still referred to from elsewhere
432  // (rare!)
433  unsigned alias_count(void) const;
434 
435  // delete the object and make the pointer null - does not make it unique first, so all other pointers to this will be
436  // null too
437  void clear(void);
438 
439  // make the pointer unique and null in one step - does not affect other pointers that were pointing to the same object
440  // void clear_unique(void); FIXME
441 
442  protected:
443  T* m_pointer;
444  unsigned* m_count;
445 };
446 
448 // comparisons required for using this class in an STL container
449 // These require == and < operator in the contained type T
450 // the remaining relational operators are provided by template functions
451 // a null pointer is less-than a non-null, two nulls are equal
452 // these funcions are defined as non-members so that you only need provide
453 // the underlying T::operator< and == if you are going to use these functions
454 
455 template <typename T>
456 bool operator==(const simple_ptr_nocopy<T>&, const simple_ptr_nocopy<T>&);
457 
458 template <typename T>
459 bool operator<(const simple_ptr_nocopy<T>&, const simple_ptr_nocopy<T>&);
460 
462 // string/print utilities
463 
464 template <typename T>
465 std::string simple_ptr_nocopy_to_string(const simple_ptr_nocopy<T>& ptr, std::string null_string);
466 
467 template <typename T>
468 otext& print_simple_ptr_nocopy(otext& str, const simple_ptr_nocopy<T>& ptr, std::string null_string);
469 
470 template <typename T>
471 otext& print_simple_ptr_nocopy(otext& str, const simple_ptr_nocopy<T>& ptr, unsigned indent, std::string null_string);
472 
474 // there's no persistence on simple_ptr_nocopy because the whole point is that
475 // it stores an uncopyable object and persistence is a form of copying
476 
479 // Simple smart pointer class
482 
484 // internals
485 
486 template <typename T>
488 
490 
491 template <typename T>
492 class smart_ptr {
493  public:
495  // member type definitions
496 
497  typedef T value_type;
498  typedef T& reference;
499  typedef const T& const_reference;
500 
502  // constructors, assignments and destructors
503 
504  // create a null pointer
505  smart_ptr(void);
506 
507  // create a pointer containing a *copy* of the object
508  // this copy is taken because the pointer class maintains a dynamically allocated object
509  // and the T& may not be (usually is not) dynamically allocated
510  // constructor form
511  smart_ptr(const T& data);
512  // assignment form for an already-constructed smart-pointer
513  smart_ptr<T>& operator=(const T& data);
514 
515  // copy constructor implements counted referencing - no copy is made
516  smart_ptr(const smart_ptr<T>& r);
517  // assignment of smart pointers implement counted referencing - no copy is made
518  smart_ptr<T>& operator=(const smart_ptr<T>&);
519 
520  // create a pointer containing a dynamically created object
521  // Note: the object must be allocated *by the user* with new
522  // constructor form - must be called in the form smart_ptr<type> x(new type(args))
523  explicit smart_ptr(T* data);
524  // assignment form
525  smart_ptr<T>& operator=(T* data);
526 
527  // destructor decrements the reference count and delete only when the last reference is destroyed
528  ~smart_ptr(void);
529 
531  // logical tests to see if there is anything contained in the pointer since it can be null
532 
533  // there are two forms:explicit and implicit
534  // implicit: if(!r) or if(r)
535  // explicit: if(r.null()) or if(r.present())
536  operator bool(void) const;
537  bool operator!(void) const;
538  bool present(void) const;
539  bool null(void) const;
540 
542  // dereference operators and functions
543 
544  // dereference the smart pointer to get the object - use in the form *p1
545  T& operator*(void) throw();
546  const T& operator*(void) const throw();
547 
548  // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
549  T* operator->(void) throw();
550  const T* operator->(void) const throw();
551 
553  // explicit function forms of the above assignment and dereference operators
554 
555  // set the value
556  void set_value(const T& data);
557  // get the value
558  T& value(void) throw();
559  const T& value(void) const throw();
560 
561  // set the pointer
562  // deletes the previous pointer and adopts the passed pointer instead
563  // Note: the object must be allocated *by the user* with new
564  // Warning: it is very easy to break the memory management with this operation
565  void set(T* data = 0);
566  // get the pointer
567  T* pointer(void);
568  const T* pointer(void) const;
569 
571  // functions to manage counted referencing
572 
573  // test whether two pointers point to the same object(known as aliasing the object)
574  // used in the form if(a.aliases(b))
575  bool aliases(const smart_ptr<T>&) const;
576 
577  // find the number of aliases - used when you need to know whether an object is still referred to from elsewhere
578  // (rare!)
579  unsigned alias_count(void) const;
580 
581  // make this pointer unique with respect to any other references to the same object
582  // if this pointer is already unique, it does nothing - otherwise it copies the object
583  void make_unique(void);
584 
585  // delete the object and make the pointer null - does not make it unique first, so all other pointers to this will be
586  // null too
587  void clear(void);
588 
589  // make the pointer unique and null in one step - does not affect other pointers that were pointing to the same object
590  void clear_unique(void);
591 
592  // make this pointer a unique copy of the parameter
593  // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
594  void copy(const smart_ptr<T>&);
595  // alternate form used in assignments: p1 = ps.copy()
596  smart_ptr<T> copy(void) const;
597 
598  // persistence functions
599  void dump(dump_context& str) const throw();
600  void restore(restore_context& str) throw();
601 
602  protected:
603  smart_ptr_holder<T>* m_holder;
604 };
605 
607 // comparisons required for using this class in an STL container
608 // These require == and < operator in the contained type T
609 // the remaining relational operators are provided by template functions
610 // a null pointer is less-than a non-null, two nulls are equal
611 // these funcions are defined as non-members so that you only need provide
612 // the underlying T::operator< and == if you are going to use these functions
613 
614 template <typename T>
615 bool operator==(const smart_ptr<T>&, const smart_ptr<T>&);
616 
617 template <typename T>
618 bool operator<(const smart_ptr<T>&, const smart_ptr<T>&);
619 
621 // string/print utilities
622 
623 template <typename T>
624 std::string smart_ptr_to_string(const smart_ptr<T>& ptr, std::string null_string);
625 
626 template <typename T>
627 otext& print_smart_ptr(otext& str, const smart_ptr<T>& ptr, std::string null_string);
628 
629 template <typename T>
630 otext& print_smart_ptr(otext& str, const smart_ptr<T>& ptr, unsigned indent, std::string null_string);
631 
633 // persistence - call these rather than the methods
634 // the dump routine dumps smart_ptr-specific information and then calls dump_pointer on the contents
635 // similarly the restore routine calls restore_pointer
636 // so therefore the class T should have non-member dump/restore functions
637 
638 template <typename T>
639 void dump_smart_ptr(dump_context& str, const smart_ptr<T>& data) throw();
640 
641 template <typename T>
642 void restore_smart_ptr(restore_context& str, smart_ptr<T>& data) throw();
643 
646 // Cloning smart pointer class for polymorphic class hierarchies
647 // The contained class T should implement the clonable interface defined in clonable.hpp
650 
651 template <typename T>
653  public:
655  // member type definitions
656 
657  typedef T value_type;
658  typedef T& reference;
659  typedef const T& const_reference;
660 
662  // constructors, assignments and destructors
663 
664  // create a null pointer
665  smart_ptr_clone(void);
666 
667  // create a pointer containing a *copy* of the object
668  // this copy is taken because the pointer class maintains a dynamically allocated object
669  // and the T& may not be (usually is not) dynamically allocated
670  // constructor form
671  smart_ptr_clone(const T& data);
672  // assignment form for an already-constructed smart-pointer
673  smart_ptr_clone<T>& operator=(const T& data);
674 
675  // copy constructor implements counted referencing - no copy is made
677  // assignment of smart pointers implement counted referencing - no copy is made
678  smart_ptr_clone<T>& operator=(const smart_ptr_clone<T>&);
679 
680  // create a pointer containing a dynamically created object
681  // Note: the object must be allocated *by the user* with new
682  // constructor form - must be called in the form smart_ptr_clone<type> x(new type(args))
683  explicit smart_ptr_clone(T* data);
684  // assignment form
685  smart_ptr_clone<T>& operator=(T* data);
686 
687  // destructor decrements the reference count and delete only when the last reference is destroyed
688  ~smart_ptr_clone(void);
689 
691  // logical tests to see if there is anything contained in the pointer since it can be null
692 
693  // there are two forms:explicit and implicit
694  // implicit: if(!r) or if(r)
695  // explicit: if(r.null()) or if(r.present())
696  operator bool(void) const;
697  bool operator!(void) const;
698  bool present(void) const;
699  bool null(void) const;
700 
702  // dereference operators and functions
703 
704  // dereference the smart pointer to get the object - use in the form *p1
705  T& operator*(void) throw();
706  const T& operator*(void) const throw();
707 
708  // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
709  T* operator->(void) throw();
710  const T* operator->(void) const throw();
711 
713  // explicit function forms of the above assignment and dereference operators
714 
715  // set the value
716  void set_value(const T& data);
717  // get the value
718  T& value(void) throw();
719  const T& value(void) const throw();
720 
721  // set the pointer
722  // deletes the previous pointer and adopts the passed pointer instead
723  // Note: the object must be allocated *by the user* with new
724  // Warning: it is very easy to break the memory management with this operation
725  void set(T* data = 0);
726  // get the pointer
727  T* pointer(void);
728  const T* pointer(void) const;
729 
731  // functions to manage counted referencing
732 
733  // test whether two pointers point to the same object(known as aliasing the object)
734  // used in the form if(a.aliases(b))
735  bool aliases(const smart_ptr_clone<T>&) const;
736 
737  // find the number of aliases - used when you need to know whether an object is still referred to from elsewhere
738  // (rare!)
739  unsigned alias_count(void) const;
740 
741  // make this pointer unique with respect to any other references to the same object
742  // if this pointer is already unique, it does nothing - otherwise it copies the object
743  void make_unique(void);
744 
745  // delete the object and make the pointer null - does not make it unique first, so all other pointers to this will be
746  // null too
747  void clear(void);
748 
749  // make the pointer unique and null in one step - does not affect other pointers that were pointing to the same object
750  void clear_unique(void);
751 
752  // make this pointer a unique copy of the parameter
753  // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
754  void copy(const smart_ptr_clone<T>&);
755  // alternate form used in assignments: p1 = ps.copy()
756  smart_ptr_clone<T> copy(void) const;
757 
758  // persistence functions
759  void dump(dump_context& str) const throw();
760  void restore(restore_context& str) throw();
761 
762  protected:
763  smart_ptr_holder<T>* m_holder;
764 };
765 
767 // comparisons required for using this class in an STL container
768 // These require == and < operator in the contained type T
769 // the remaining relational operators are provided by template functions
770 // a null pointer is less-than a non-null, two nulls are equal
771 // these funcions are defined as non-members so that you only need provide
772 // the underlying T::operator< and == if you are going to use these functions
773 
774 template <typename T>
775 bool operator==(const smart_ptr_clone<T>&, const smart_ptr_clone<T>&);
776 
777 template <typename T>
778 bool operator<(const smart_ptr_clone<T>&, const smart_ptr_clone<T>&);
779 
781 // string/print utilities
782 
783 template <typename T>
784 std::string smart_ptr_clone_to_string(const smart_ptr_clone<T>& ptr, std::string null_string);
785 
786 template <typename T>
787 otext& print_smart_ptr_clone(otext& str, const smart_ptr_clone<T>& ptr, std::string null_string);
788 
789 template <typename T>
790 otext& print_smart_ptr_clone(otext& str, const smart_ptr_clone<T>& ptr, unsigned indent, std::string null_string);
791 
793 // persistence - call these rather than the methods
794 // the dump routine dumps smart_ptr_clone-specific information and then calls dump_interface
795 // similarly the restore routine calls restore_interface
796 // so therefore the class T should implement the persistent interface defined by the class persistent in persistent.hpp
797 
798 template <typename T>
799 void dump_smart_ptr_clone(dump_context& str, const smart_ptr_clone<T>& data) throw();
800 
801 template <typename T>
802 void restore_smart_ptr_clone(restore_context& str, smart_ptr_clone<T>& data) throw();
803 
806 // No-copy smart pointer class for managing objects that cannot be copied
809 
810 template <typename T>
812  public:
814  // member type definitions
815 
816  typedef T value_type;
817  typedef T& reference;
818  typedef const T& const_reference;
819 
821  // constructors, assignments and destructors
822 
823  // create a null pointer
824  smart_ptr_nocopy(void);
825 
826  // copy constructor implements counted referencing - no copy is made
828  // assignment of smart pointers implement counted referencing - no copy is made
829  smart_ptr_nocopy<T>& operator=(const smart_ptr_nocopy<T>&);
830 
831  // create a pointer containing a dynamically created object
832  // Note: the object must be allocated *by the user* with new
833  // constructor form - must be called in the form smart_ptr_nocopy<type> x(new type(args))
834  explicit smart_ptr_nocopy(T* data);
835  // assignment form
836  smart_ptr_nocopy<T>& operator=(T* data);
837 
838  // destructor decrements the reference count and delete only when the last reference is destroyed
839  ~smart_ptr_nocopy(void);
840 
842  // logical tests to see if there is anything contained in the pointer since it can be null
843 
844  // there are two forms:explicit and implicit
845  // implicit: if(!r) or if(r)
846  // explicit: if(r.null()) or if(r.present())
847  operator bool(void) const;
848  bool operator!(void) const;
849  bool present(void) const;
850  bool null(void) const;
851 
853  // dereference operators and functions
854 
855  // dereference the smart pointer to get the object - use in the form *p1
856  T& operator*(void) throw();
857  const T& operator*(void) const throw();
858 
859  // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
860  T* operator->(void) throw();
861  const T* operator->(void) const throw();
862 
864  // explicit function forms of the above assignment and dereference operators
865 
866  // get the value
867  T& value(void) throw();
868  const T& value(void) const throw();
869 
870  // set the pointer
871  // deletes the previous pointer and adopts the passed pointer instead
872  // Note: the object must be allocated *by the user* with new
873  // Warning: it is very easy to break the memory management with this operation
874  void set(T* data = 0);
875  // get the pointer
876  T* pointer(void);
877  const T* pointer(void) const;
878 
880  // functions to manage counted referencing
881 
882  // test whether two pointers point to the same object(known as aliasing the object)
883  // used in the form if(a.aliases(b))
884  bool aliases(const smart_ptr_nocopy<T>&) const;
885 
886  // find the number of aliases - used when you need to know whether an object is still referred to from elsewhere
887  // (rare!)
888  unsigned alias_count(void) const;
889 
890  // delete the object and make the pointer null - does not make it unique first, so all other pointers to this will be
891  // null too
892  void clear(void);
893 
894  // make the pointer unique and null in one step - does not affect other pointers that were pointing to the same object
895  void clear_unique(void);
896 
897  protected:
898  smart_ptr_holder<T>* m_holder;
899 };
900 
902 // comparisons required for using this class in an STL container
903 // These require == and < operator in the contained type T
904 // the remaining relational operators are provided by template functions
905 // a null pointer is less-than a non-null, two nulls are equal
906 // these funcions are defined as non-members so that you only need provide
907 // the underlying T::operator< and == if you are going to use these functions
908 
909 template <typename T>
910 bool operator==(const smart_ptr_nocopy<T>&, const smart_ptr_nocopy<T>&);
911 
912 template <typename T>
913 bool operator<(const smart_ptr_nocopy<T>&, const smart_ptr_nocopy<T>&);
914 
916 // string/print utilities
917 
918 template <typename T>
919 std::string smart_ptr_nocopy_to_string(const smart_ptr_nocopy<T>& ptr, std::string null_string);
920 
921 template <typename T>
922 otext& print_smart_ptr_nocopy(otext& str, const smart_ptr_nocopy<T>& ptr, std::string null_string);
923 
924 template <typename T>
925 otext& print_smart_ptr_nocopy(otext& str, const smart_ptr_nocopy<T>& ptr, unsigned indent, std::string null_string);
926 
928 // there's no persistence on smart_ptr_nocopy because the whole point is that
929 // it stores an uncopyable object and persistence is a form of copying
930 
932 #include "smart_ptr.tpp"
933 #endif
Definition: persistent.hpp:64
Definition: textio.hpp:37
Definition: persistent.hpp:126
Definition: smart_ptr.hpp:196
Definition: smart_ptr.hpp:356
Definition: smart_ptr.hpp:35
Definition: smart_ptr.hpp:652
Definition: smart_ptr.hpp:487
Definition: smart_ptr.hpp:811
Definition: smart_ptr.hpp:492