01
02 class HandleBase
03 {
04 proteteced:
05
06 typedef int Counter;
07
08 // All Handle::null() instances point at the counter.
// It is initialized with the value of 1. Therefore,
// it is never 0 and, consequently, there are no
// attempts to delete it.
09
10 static Counter _null;
11 };
12
13 template<class Data>
14 class Handle : public HandleBase
15 {
16 #include "counted.h"
17
18 public:
19
20 ~Handle() { _counted->dismiss(); }
21
22 explicit Handle()
23 : _counted(new Counted()) { _counted->use(); }
24
25 Handle(const Handle<Data>& ref)
26 : _counted(ref._counted) { _counted->use(); }
27
28 Handle<Data>&
29 operator=(const Handle<Data>& src)
30 {
31 if (this->_counted != src._counted)
32 {
33 _counted->dismiss();
34 _counted = src._counted;
35 _counted->use();
36 }
37 return *this;
38 }
39
40 // Direct access.
41
42 operator Data& () const
{ return _counted->operator Data&(); }
43 operator Data* () const
{ return _counted->operator Data*(); }
44 Data* operator-> () const
{ return _counted->operator ->(); }
45
46 #include "create.h"
47 #include "unofficial.h"
48
49 template<class Other>
50 Handle(const Handle<Other>& ref)
51 : _counted(ref.cast<Data>()._counted)
52 {
53 _counted->use();
54 }
55
56 template<class Other>
57 Handle(Handle<Other>& ref)
58 : _counted(ref.cast<Data>()._counted)
59 {
60 _counted->use();
61 }
62
63 template<class Other>
64 Handle<Data>&
65 operator=(const Handle<Other>& src)
66 {
67 return operator=(src.cast<Data>());
68 }
69
70 // Static cast:
71 // from Handle<Derived> to Handle<Base>
72 // from Handle<Data> to Handle<const Data>
73 // etc.
74
75 template<class Other>
76 Handle<Other>&
77 cast()
78 {
79 return (_cast_test<Other>(), *(Handle<Other>*) this);
80 }
81
82 template<class Other>
83 const Handle<Other>&
84 cast() const
85 {
86 return (_cast_test<Other>(), *(Handle<Other>*) this);
87 }
88
89 // Dynamic downcast:
90 // from Handle<Base> to Handle<Derived>
91
92 template<class Other>
93 const Handle<Other>&
94 dyn_cast() const
95 {
96 _counted->dyn_cast<Other>(); //test
97 return *(Handle<Other>*) this;
98 }
99
100 // Special null() instance
101 // to represent unassigned pointer.
102
103 static
104 Handle<Data>
105 null()
106 {
107 return Handle<Data>((Counted*) &_null);
108 }
109
110 private:
111
112 Counted* _counted;
113
114 Handle(Counted* counted)
115 : _counted(counted) { _counted->use(); }
116
117 template<class Other>
118 Other*
119 _cast_test() const { return (Data*) 0; }
120 };
121
122 #endif