xref: /aoo4110/main/cosv/inc/cosv/tpl/dyn.hxx (revision b1cdbd2c)
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 transfered
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 explicitely - 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