1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef CSV_DYN_HXX
25 #define CSV_DYN_HXX
26
27
28
29
30 namespace csv
31 {
32
33
34 /** Dyn owns an object on the heap, which will be automatically
35 deleted in its D'tor.
36
37 Dyn's main purpose is for class members on the heap:
38 You can't forget to delete them in the D'tor. Constness will be transferred
39 to the hold object.
40
41 Dyn forbids the CopyC'tor and operator=(). So you can't incidentally
42 run into problems with compiler defined CopyC'tor or operator=() of the
43 owning class. If you need those, you have to define them explicitly - as
44 you should do anyway with all classes, that own members on the heap.
45
46 Dyn also works with incomplete types.
47 You only need to write
48 class DX;
49 but needn't include #include <DX>.hxx.
50 This is a difference to std::auto_ptr, where it is not absolutely clear
51 if it is allowed to use it with incomplete types.
52
53 You can also use Dyn within function bodies, to make them exception safe.
54
55 @attention
56 If you use Dyn with an incomplete type, the owning class needs to
57 define a non-inline D'tor. Else the compiler will complain.
58 */
59 template <class DX>
60 class Dyn
61 {
62 public:
63 // LIFECYCLE
64 /// From now on, let_dpObject is owned by this Dyn-object.
65 explicit Dyn(
66 DX * let_dpObject = 0);
67 ~Dyn();
68 // OPERATORS
69 /** This deletes a prevoiusly existing dpObject!
70 From now on, let_dpObject is owned by this Dyn-object.
71 */
72 Dyn<DX> & operator=(
73 DX * let_dpObject);
74 /// @return true, if any valid object is hold, false else.
75 operator bool() const;
76
77 const DX * operator->() const;
78 DX * operator->();
79
80 const DX & operator*() const;
81 DX & operator*();
82
83 // OPERATIONS
84 /** @return The hold object on the heap.
85
86 @ATTENTION
87 The caller of the function is responsible to delete
88 the returned object
89
90 @postcond
91 this->dpObject == 0.
92 */
93 DX * Release();
94
95 // INQUIRY
96 /// Shorthand for operator->(), if implicit overloading of -> can not be used.
97 const DX * Ptr() const;
98
99 // ACCESS
100 /// Shorthand for operator->(), if implicit overloading of -> can not be used.
101 DX * Ptr();
102 /// So const objects can return mutable pointers to the owned object.
103 DX * MutablePtr() const;
104
105 private:
106 /* Does NOT set dpObject to zero! Because it is only used
107 internally in situations where dpObject is set immediately
108 after.
109 */
110 void Delete();
111
112 /** Forbidden function!
113 -------------------
114 Help ensure, that classes with
115 dynamic pointers use a selfdefined copy constructor
116 and operator=(). If the default versions of these
117 functions are used, the compiler will throw an error.
118 **/
119 Dyn( const Dyn<DX> & );
120 /** Forbidden function!
121 -------------------
122 Help ensure, that classes with
123 dynamic pointers use a selfdefined copy constructor
124 and operator=(). If the default versions of these
125 functions are used, the compiler will throw an error.
126 **/
127 Dyn<DX> & operator=( const Dyn<DX> & );
128
129 // DATA
130 /// An owned heap object. Needs to be deleted by this class.
131 DX * dpObject;
132 };
133
134
135
136
137 // IMPLEMENTATION
138 template <class DX>
139 void
Delete()140 Dyn<DX>::Delete()
141 {
142 if (dpObject != 0)
143 delete dpObject;
144 }
145
146 template <class DX>
147 inline
Dyn(DX * let_dpObject)148 Dyn<DX>::Dyn( DX * let_dpObject )
149 : dpObject(let_dpObject) {}
150
151 template <class DX>
152 inline
~Dyn()153 Dyn<DX>::~Dyn()
154 { Delete(); }
155
156
157 template <class DX>
158 inline Dyn<DX> &
operator =(DX * let_dpObject)159 Dyn<DX>::operator=( DX * let_dpObject )
160 {
161 if ( dpObject == let_dpObject )
162 return *this;
163
164 Delete();
165 dpObject = let_dpObject;
166 return *this;
167 }
168
169 template <class DX>
170 inline
171 Dyn<DX>::operator bool() const
172 { return dpObject != 0; }
173
174 template <class DX>
175 inline
176 const DX *
operator ->() const177 Dyn<DX>::operator->() const
178 { return dpObject; }
179
180 template <class DX>
181 inline DX *
operator ->()182 Dyn<DX>::operator->()
183 { return dpObject; }
184
185 template <class DX>
186 inline const DX &
operator *() const187 Dyn<DX>::operator*() const
188 { csv_assert(dpObject != 0);
189 return *dpObject;
190 }
191
192 template <class DX>
193 inline DX &
operator *()194 Dyn<DX>::operator*()
195 { csv_assert(dpObject != 0);
196 return *dpObject;
197 }
198
199 template <class DX>
200 inline DX *
Release()201 Dyn<DX>::Release()
202 { DX * ret = dpObject;
203 dpObject = 0;
204 return ret;
205 }
206
207 template <class DX>
208 inline const DX *
Ptr() const209 Dyn<DX>::Ptr() const
210 { return dpObject; }
211
212 template <class DX>
213 inline DX *
Ptr()214 Dyn<DX>::Ptr()
215 { return dpObject; }
216
217 template <class DX>
218 inline DX *
MutablePtr() const219 Dyn<DX>::MutablePtr() const
220 { return dpObject; }
221
222 } // namespace csv
223
224
225
226
227 #ifndef CSV_HIDE_DYN
228 #define Dyn ::csv::Dyn
229 #endif
230
231
232
233
234 #endif
235