00001 #ifndef GSGL_DATA_POINTER_H
00002 #define GSGL_DATA_POINTER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "data/data.hpp"
00038 #include "data/exception.hpp"
00039 #include "data/shared.hpp"
00040
00041 namespace gsgl
00042 {
00043
00044 namespace data
00045 {
00046
00047 template <typename T, bool ARRAY_PTR = false>
00048 class smart_pointer
00049 : public data_object
00050 {
00051 T * data;
00052
00053 smart_pointer(const smart_pointer & sp);
00054 smart_pointer & operator= (const smart_pointer & sp);
00055 public:
00056 explicit smart_pointer(T *data = 0);
00057 ~smart_pointer();
00058
00059 const T *ptr() const;
00060 T * ptr();
00061
00062 const T & value() const;
00063 T & value();
00064
00065 const T & operator* () const;
00066 T & operator* ();
00067
00068 const T * operator-> () const;
00069 T *operator-> ();
00070
00071 operator const T * () const;
00072 operator T * ();
00073
00074 bool operator== (const smart_pointer & p);
00075 };
00076
00077
00078 template <typename T, bool ARRAY_PTR>
00079 smart_pointer<T,ARRAY_PTR>::smart_pointer(T *data)
00080 : data_object(), data(data)
00081 {
00082 }
00083
00084
00085 template <typename T, bool ARRAY_PTR>
00086 smart_pointer<T,ARRAY_PTR>::smart_pointer(const smart_pointer & sp)
00087 {
00088 throw internal_exception(__FILE__, __LINE__, L"Cannot assign a smart pointer.");
00089 }
00090
00091
00092 template <typename T, bool ARRAY_PTR>
00093 smart_pointer<T,ARRAY_PTR> & smart_pointer<T,ARRAY_PTR>::operator= (const smart_pointer & sp)
00094 {
00095 throw internal_exception(__FILE__, __LINE__, L"Cannot assign a smart pointer.");
00096 }
00097
00098 template <typename T, bool ARRAY_PTR>
00099 smart_pointer<T,ARRAY_PTR>::~smart_pointer()
00100 {
00101 if (ARRAY_PTR)
00102 delete [] data;
00103 else
00104 delete data;
00105 }
00106
00107 template <typename T, bool ARRAY_PTR>
00108 const T *smart_pointer<T,ARRAY_PTR>::ptr() const
00109 {
00110 return data;
00111 }
00112
00113 template <typename T, bool ARRAY_PTR>
00114 T *smart_pointer<T,ARRAY_PTR>::ptr()
00115 {
00116 return data;
00117 }
00118
00119 template <typename T, bool ARRAY_PTR>
00120 const T & smart_pointer<T,ARRAY_PTR>::value() const
00121 {
00122 return *data;
00123 }
00124
00125 template <typename T, bool ARRAY_PTR>
00126 T & smart_pointer<T,ARRAY_PTR>::value()
00127 {
00128 return *data;
00129 }
00130
00131 template <typename T, bool ARRAY_PTR>
00132 const T & smart_pointer<T,ARRAY_PTR>::operator* () const
00133 {
00134 return *data;
00135 }
00136
00137 template <typename T, bool ARRAY_PTR>
00138 T & smart_pointer<T,ARRAY_PTR>::operator* ()
00139 {
00140 return *data;
00141 }
00142
00143 template <typename T, bool ARRAY_PTR>
00144 const T *smart_pointer<T,ARRAY_PTR>::operator-> () const
00145 {
00146 return data;
00147 }
00148
00149 template <typename T, bool ARRAY_PTR>
00150 T *smart_pointer<T,ARRAY_PTR>::operator-> ()
00151 {
00152 return data;
00153 }
00154
00155 template <typename T, bool ARRAY_PTR>
00156 smart_pointer<T,ARRAY_PTR>::operator const T * () const
00157 {
00158 return data;
00159 }
00160
00161 template <typename T, bool ARRAY_PTR>
00162 smart_pointer<T,ARRAY_PTR>::operator T * ()
00163 {
00164 return data;
00165 }
00166
00167
00168
00169
00170
00171 template <typename T, bool ARRAY_PTR = false>
00172 class shared_pointer_impl
00173 : public shared_object
00174 {
00175 T *data;
00176 public:
00177 shared_pointer_impl(T *data);
00178 virtual ~shared_pointer_impl();
00179
00180 template <typename T, bool ARRAY_PTR>
00181 friend class shared_pointer;
00182 };
00183
00184
00185
00186
00187
00188 template <typename T, bool ARRAY_PTR = false>
00189 class shared_pointer
00190 : public data_object
00191 {
00192 shared_pointer_impl<T, ARRAY_PTR> *impl;
00193
00194 public:
00195 shared_pointer(T *data = 0);
00196 shared_pointer(const shared_pointer & p);
00197
00198 shared_pointer & operator= (const shared_pointer & p);
00199 shared_pointer & operator= (T *data);
00200
00201 ~shared_pointer();
00202
00203 const T * ptr() const;
00204 T * ptr();
00205
00206 const T & value() const;
00207 T & value();
00208
00209 const T & operator* () const;
00210 T & operator* ();
00211
00212 const T * operator-> () const;
00213 T *operator-> ();
00214
00215 operator const T * () const;
00216 operator T * ();
00217
00218 bool operator== (const shared_pointer & p) const;
00219 };
00220
00221
00222
00223
00224 template <typename T, bool ARRAY_PTR>
00225 shared_pointer<T,ARRAY_PTR>::shared_pointer(T * data)
00226 : data_object(), impl(new shared_pointer_impl<T,ARRAY_PTR>(data))
00227 {
00228 impl->attach();
00229 }
00230
00231 template <typename T, bool ARRAY_PTR>
00232 shared_pointer<T,ARRAY_PTR>::shared_pointer(const shared_pointer & p)
00233 : data_object(), impl(p.impl)
00234 {
00235 impl->attach();
00236 }
00237
00238 template <typename T, bool ARRAY_PTR>
00239 shared_pointer<T,ARRAY_PTR> & shared_pointer<T,ARRAY_PTR>::operator= (const shared_pointer & p)
00240 {
00241 impl->detach();
00242 impl = p.impl;
00243 impl->attach();
00244
00245 return *this;
00246 }
00247
00248 template <typename T, bool ARRAY_PTR>
00249 shared_pointer<T,ARRAY_PTR> & shared_pointer<T,ARRAY_PTR>::operator= (T *data)
00250 {
00251 impl->detach();
00252 impl = new shared_pointer_impl<T,ARRAY_PTR>(data);
00253 impl->attach();
00254
00255 return *this;
00256 }
00257
00258 template <typename T, bool ARRAY_PTR>
00259 shared_pointer<T,ARRAY_PTR>::~shared_pointer()
00260 {
00261 impl->detach();
00262 }
00263
00264
00265 template <typename T, bool ARRAY_PTR>
00266 const T *shared_pointer<T,ARRAY_PTR>::ptr() const
00267 {
00268 return impl->data;
00269 }
00270
00271
00272 template <typename T, bool ARRAY_PTR>
00273 T *shared_pointer<T,ARRAY_PTR>::ptr()
00274 {
00275 return impl->data;
00276 }
00277
00278
00279 template <typename T, bool ARRAY_PTR>
00280 const T & shared_pointer<T,ARRAY_PTR>::value() const
00281 {
00282 return *impl->data;
00283 }
00284
00285
00286 template <typename T, bool ARRAY_PTR>
00287 T & shared_pointer<T,ARRAY_PTR>::value()
00288 {
00289 return *impl->data;
00290 }
00291
00292
00293 template <typename T, bool ARRAY_PTR>
00294 const T & shared_pointer<T,ARRAY_PTR>::operator* () const
00295 {
00296 return *impl->data;
00297 }
00298
00299
00300 template <typename T, bool ARRAY_PTR>
00301 T & shared_pointer<T,ARRAY_PTR>::operator* ()
00302 {
00303 return *impl->data;
00304 }
00305
00306
00307 template <typename T, bool ARRAY_PTR>
00308 const T *shared_pointer<T,ARRAY_PTR>::operator-> () const
00309 {
00310 return impl->data;
00311 }
00312
00313
00314 template <typename T, bool ARRAY_PTR>
00315 T *shared_pointer<T,ARRAY_PTR>::operator-> ()
00316 {
00317 return impl->data;
00318 }
00319
00320
00321 template <typename T, bool ARRAY_PTR>
00322 shared_pointer<T,ARRAY_PTR>::operator const T * () const
00323 {
00324 return impl->data;
00325 }
00326
00327
00328 template <typename T, bool ARRAY_PTR>
00329 shared_pointer<T,ARRAY_PTR>::operator T * ()
00330 {
00331 return impl->data;
00332 }
00333
00334
00335 template <typename T, bool ARRAY_PTR>
00336 bool shared_pointer<T,ARRAY_PTR>::operator== (const shared_pointer & p) const
00337 {
00338 return impl->data == p.impl->data;
00339 }
00340
00341
00342
00343
00344 template <typename T, bool ARRAY_PTR>
00345 shared_pointer_impl<T,ARRAY_PTR>::shared_pointer_impl(T *data)
00346 : shared_object(), data(data)
00347 {
00348 }
00349
00350 template <typename T, bool ARRAY_PTR>
00351 shared_pointer_impl<T,ARRAY_PTR>::~shared_pointer_impl()
00352 {
00353 if (ARRAY_PTR)
00354 delete [] data;
00355 else
00356 delete data;
00357 }
00358
00359
00360 }
00361
00362 }
00363
00364 #endif