00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _DECAF_LANG_POINTER_H_
00019 #define _DECAF_LANG_POINTER_H_
00020
00021 #include <decaf/util/Config.h>
00022 #include <decaf/lang/exceptions/NullPointerException.h>
00023 #include <decaf/lang/exceptions/ClassCastException.h>
00024 #include <decaf/util/concurrent/atomic/AtomicRefCounter.h>
00025 #include <decaf/util/Comparator.h>
00026 #include <memory>
00027 #include <typeinfo>
00028 #include <algorithm>
00029 #include <functional>
00030
00031 namespace decaf {
00032 namespace lang {
00033
00034
00035 struct STATIC_CAST_TOKEN {};
00036 struct DYNAMIC_CAST_TOKEN {};
00037
00052 template<typename T, typename REFCOUNTER = decaf::util::concurrent::atomic::AtomicRefCounter>
00053 class Pointer : public REFCOUNTER {
00054 private:
00055
00056 typedef void (*deletionFuncPtr)(T* p);
00057
00058 private:
00059
00060 T* value;
00061
00062
00063 deletionFuncPtr onDelete;
00064
00065 public:
00066
00067 typedef T* PointerType;
00068 typedef T& ReferenceType;
00069 typedef REFCOUNTER CounterType;
00070
00071 public:
00072
00079 Pointer() : REFCOUNTER(), value(NULL), onDelete(onDeleteFunc) {}
00080
00088 explicit Pointer(const PointerType value) : REFCOUNTER(), value(value), onDelete(onDeleteFunc) {}
00089
00097 Pointer(const Pointer& value) : REFCOUNTER(value), value(value.value), onDelete(onDeleteFunc) {}
00098
00106 template<typename T1, typename R1>
00107 Pointer(const Pointer<T1, R1>& value) : REFCOUNTER(value), value(value.get()), onDelete(onDeleteFunc) {}
00108
00117 template<typename T1, typename R1>
00118 Pointer(const Pointer<T1, R1>& value, const STATIC_CAST_TOKEN&) :
00119 REFCOUNTER(value), value(static_cast<T*> (value.get())), onDelete(onDeleteFunc) {}
00120
00132 template<typename T1, typename R1>
00133 Pointer(const Pointer<T1, R1>& value, const DYNAMIC_CAST_TOKEN&) :
00134 REFCOUNTER(value), value(dynamic_cast<T*> (value.get())), onDelete(onDeleteFunc) {
00135
00136 if (this->value == NULL) {
00137
00138
00139 REFCOUNTER::release();
00140 throw decaf::lang::exceptions::ClassCastException(
00141 __FILE__, __LINE__, "Failed to cast source pointer of type %s to this type: %s.",
00142 typeid(T1).name(), typeid(T).name());
00143 }
00144 }
00145
00146 virtual ~Pointer() {
00147 if (REFCOUNTER::release() == true) {
00148 onDelete(this->value);
00149 }
00150 }
00151
00161 void reset(T* value = NULL) {
00162 Pointer(value).swap(*this);
00163 }
00164
00174 T* release() {
00175 T* temp = this->value;
00176 this->value = NULL;
00177 return temp;
00178 }
00179
00188 PointerType get() const {
00189 return this->value;
00190 }
00191
00198 void swap(Pointer& value) {
00199 std::swap(this->value, value.value);
00200 REFCOUNTER::swap(value);
00201 }
00202
00207 Pointer& operator=(const Pointer& right) {
00208 if (this == (void*) &right) {
00209 return *this;
00210 }
00211
00212 Pointer temp(right);
00213 temp.swap(*this);
00214 return *this;
00215 }
00216 template<typename T1, typename R1>
00217 Pointer& operator=(const Pointer<T1, R1>& right) {
00218 if (this == (void*) &right) {
00219 return *this;
00220 }
00221
00222 Pointer temp(right);
00223 temp.swap(*this);
00224 return *this;
00225 }
00226
00234 ReferenceType operator*() {
00235 if (this->value == NULL) {
00236 throw decaf::lang::exceptions::NullPointerException(
00237 __FILE__, __LINE__, "Pointer operator& - Pointee is NULL.");
00238 }
00239
00240 return *(this->value);
00241 }
00242 ReferenceType operator*() const {
00243 if (this->value == NULL) {
00244 throw decaf::lang::exceptions::NullPointerException(
00245 __FILE__, __LINE__, "Pointer operator& - Pointee is NULL.");
00246 }
00247
00248 return *(this->value);
00249 }
00250
00258 PointerType operator->() {
00259 if (this->value == NULL) {
00260 throw decaf::lang::exceptions::NullPointerException(
00261 __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL.");
00262 }
00263 return this->value;
00264 }
00265 PointerType operator->() const {
00266 if (this->value == NULL) {
00267 throw decaf::lang::exceptions::NullPointerException(
00268 __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL.");
00269 }
00270 return this->value;
00271 }
00272
00273 bool operator!() const {
00274 return this->value == NULL;
00275 }
00276
00277 inline friend bool operator==(const Pointer& left, const T* right) {
00278 return left.get() == right;
00279 }
00280
00281 inline friend bool operator==(const T* left, const Pointer& right) {
00282 return left == right.get();
00283 }
00284
00285 inline friend bool operator!=(const Pointer& left, const T* right) {
00286 return left.get() != right;
00287 }
00288
00289 inline friend bool operator!=(const T* left, const Pointer& right) {
00290 return left != right.get();
00291 }
00292
00293 template<typename T1, typename R1>
00294 bool operator==(const Pointer<T1, R1>& right) const {
00295 return this->value == right.get();
00296 }
00297
00298 template<typename T1, typename R1>
00299 bool operator!=(const Pointer<T1, R1>& right) const {
00300 return !(this->value == right.get());
00301 }
00302
00303 template<typename T1>
00304 Pointer<T1, CounterType> dynamicCast() const {
00305 return Pointer<T1, CounterType> (*this, DYNAMIC_CAST_TOKEN());
00306 }
00307
00308 template<typename T1>
00309 Pointer<T1, CounterType> staticCast() const {
00310 return Pointer<T1, CounterType> (*this, STATIC_CAST_TOKEN());
00311 }
00312
00313 private:
00314
00315
00316 static void onDeleteFunc(T* value) {
00317 delete value;
00318 }
00319
00320 };
00321
00323 template<typename T, typename R, typename U>
00324 inline bool operator==(const Pointer<T, R>& left, const U* right) {
00325 return left.get() == right;
00326 }
00327
00329 template<typename T, typename R, typename U>
00330 inline bool operator==(const U* left, const Pointer<T, R>& right) {
00331 return right.get() == left;
00332 }
00333
00335 template<typename T, typename R, typename U>
00336 inline bool operator!=(const Pointer<T, R>& left, const U* right) {
00337 return !(left.get() == right);
00338 }
00339
00341 template<typename T, typename R, typename U>
00342 inline bool operator!=(const U* left, const Pointer<T, R>& right) {
00343 return right.get() != left;
00344 }
00345
00347 template<typename T, typename R>
00348 std::ostream& operator<<(std::ostream &out, const Pointer<T, R>& pointer) {
00349 out << pointer.get();
00350 return out;
00351 }
00352
00365 template<typename T, typename R = decaf::util::concurrent::atomic::AtomicRefCounter>
00366 class PointerComparator: public decaf::util::Comparator<Pointer<T, R> > {
00367 public:
00368
00369 virtual ~PointerComparator() {}
00370
00371
00372
00373 virtual bool operator()(const Pointer<T, R>& left, const Pointer<T, R>& right) const {
00374 return *left < *right;
00375 }
00376
00377
00378 virtual int compare(const Pointer<T, R>& left, const Pointer<T, R>& right) const {
00379 return *left < *right ? -1 : *right < *left ? 1 : 0;
00380 }
00381
00382 };
00383
00384 }}
00385
00387 namespace std {
00388
00393 template<typename T>
00394 struct less<decaf::lang::Pointer<T> > {
00395
00396 typedef decaf::lang::Pointer<T> first_argument_type;
00397 typedef decaf::lang::Pointer<T> second_argument_type;
00398 typedef bool result_type;
00399
00400 bool operator()(const decaf::lang::Pointer<T>& left, const decaf::lang::Pointer<T>& right) const {
00401 return less<T*> ()(left.get(), right.get());
00402 }
00403 };
00404 }
00405
00406 #endif