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 140 Dyn<DX>::Delete() 141 { 142 if (dpObject != 0) 143 delete dpObject; 144 } 145 146 template <class DX> 147 inline 148 Dyn<DX>::Dyn( DX * let_dpObject ) 149 : dpObject(let_dpObject) {} 150 151 template <class DX> 152 inline 153 Dyn<DX>::~Dyn() 154 { Delete(); } 155 156 157 template <class DX> 158 inline Dyn<DX> & 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 * 177 Dyn<DX>::operator->() const 178 { return dpObject; } 179 180 template <class DX> 181 inline DX * 182 Dyn<DX>::operator->() 183 { return dpObject; } 184 185 template <class DX> 186 inline const DX & 187 Dyn<DX>::operator*() const 188 { csv_assert(dpObject != 0); 189 return *dpObject; 190 } 191 192 template <class DX> 193 inline DX & 194 Dyn<DX>::operator*() 195 { csv_assert(dpObject != 0); 196 return *dpObject; 197 } 198 199 template <class DX> 200 inline DX * 201 Dyn<DX>::Release() 202 { DX * ret = dpObject; 203 dpObject = 0; 204 return ret; 205 } 206 207 template <class DX> 208 inline const DX * 209 Dyn<DX>::Ptr() const 210 { return dpObject; } 211 212 template <class DX> 213 inline DX * 214 Dyn<DX>::Ptr() 215 { return dpObject; } 216 217 template <class DX> 218 inline DX * 219 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