|
activemq-cpp-3.4.0
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 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 // Used internally in Pointer. 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 // Pointer to our internal delete function, allows incompletes. 00063 deletionFuncPtr onDelete; 00064 00065 public: 00066 00067 typedef T* PointerType; // type returned by operator-> 00068 typedef T& ReferenceType; // type returned by operator* 00069 typedef REFCOUNTER CounterType; // Type of the Reference Counter 00070 00071 public: 00072 00079 Pointer() : REFCOUNTER(), value( NULL ), onDelete( onDeleteFunc ) {} 00080 00087 explicit Pointer( const PointerType value ) : REFCOUNTER(), value( value ), onDelete( onDeleteFunc ) { 00088 } 00089 00094 Pointer( const Pointer& value ) throw() : 00095 REFCOUNTER( value ), value( value.value ), onDelete( onDeleteFunc ) {} 00096 00101 template< typename T1, typename R1 > 00102 Pointer( const Pointer<T1, R1>& value ) throw() : 00103 REFCOUNTER( value ), value( value.get() ), onDelete( onDeleteFunc ) {} 00104 00112 template< typename T1, typename R1 > 00113 Pointer( const Pointer<T1, R1>& value, const STATIC_CAST_TOKEN& ) throw() : 00114 REFCOUNTER( value ), value( static_cast<T*>( value.get() ) ), onDelete( onDeleteFunc ) { 00115 } 00116 00127 template< typename T1, typename R1 > 00128 Pointer( const Pointer<T1, R1>& value, const DYNAMIC_CAST_TOKEN& ) : 00129 REFCOUNTER( value ), value( dynamic_cast<T*>( value.get() ) ), onDelete( onDeleteFunc ) { 00130 00131 if( this->value == NULL ) { 00132 00133 // Remove the reference we took in the Reference Counter's ctor since we 00134 // didn't actually create one as the dynamic cast failed. 00135 REFCOUNTER::release(); 00136 throw decaf::lang::exceptions::ClassCastException( 00137 __FILE__, __LINE__, 00138 "Failed to cast source pointer of type %s to this type: %s.", 00139 typeid( T1 ).name(), typeid( T ).name() ); 00140 } 00141 } 00142 00143 virtual ~Pointer() throw() { 00144 if( REFCOUNTER::release() == true ) { 00145 onDelete( this->value ); 00146 } 00147 } 00148 00157 void reset( T* value ) { 00158 Pointer( value ).swap( *this ); 00159 } 00160 00172 T* release() { 00173 T* temp = this->value; 00174 this->value = NULL; 00175 return temp; 00176 } 00177 00186 PointerType get() const { 00187 return this->value; 00188 } 00189 00194 void swap( Pointer& value ) throw() { 00195 std::swap( this->value, value.value ); 00196 REFCOUNTER::swap( value ); 00197 } 00198 00203 Pointer& operator= ( const Pointer& right ) throw() { 00204 if( this == (void*)&right ) { 00205 return *this; 00206 } 00207 00208 Pointer temp( right ); 00209 temp.swap( *this ); 00210 return *this; 00211 } 00212 template< typename T1, typename R1> 00213 Pointer& operator= ( const Pointer<T1, R1>& right ) throw() { 00214 if( this == (void*)&right ) { 00215 return *this; 00216 } 00217 00218 Pointer temp( right ); 00219 temp.swap( *this ); 00220 return *this; 00221 } 00222 00230 ReferenceType operator*() { 00231 if( this->value == NULL ) { 00232 throw decaf::lang::exceptions::NullPointerException( 00233 __FILE__, __LINE__, "Pointer operator& - Pointee is NULL." ); 00234 } 00235 00236 return *( this->value ); 00237 } 00238 ReferenceType operator*() const { 00239 if( this->value == NULL ) { 00240 throw decaf::lang::exceptions::NullPointerException( 00241 __FILE__, __LINE__, "Pointer operator& - Pointee is NULL." ); 00242 } 00243 00244 return *( this->value ); 00245 } 00246 00254 PointerType operator->() { 00255 if( this->value == NULL ) { 00256 throw decaf::lang::exceptions::NullPointerException( 00257 __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL." ); 00258 } 00259 return this->value; 00260 } 00261 PointerType operator->() const { 00262 if( this->value == NULL ) { 00263 throw decaf::lang::exceptions::NullPointerException( 00264 __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL." ); 00265 } 00266 return this->value; 00267 } 00268 00269 bool operator!() const { 00270 return this->value == NULL; 00271 } 00272 00273 inline friend bool operator==( const Pointer& left, const T* right ) { 00274 return left.get() == right; 00275 } 00276 00277 inline friend bool operator==( const T* left, const Pointer& right ) { 00278 return left == right.get(); 00279 } 00280 00281 inline friend bool operator!=( const Pointer& left, const T* right ) { 00282 return left.get() != right; 00283 } 00284 00285 inline friend bool operator!=( const T* left, const Pointer& right ) { 00286 return left != right.get(); 00287 } 00288 00289 template< typename T1, typename R1 > 00290 bool operator==( const Pointer<T1, R1>& right ) const { 00291 return this->value == right.get(); 00292 } 00293 00294 template< typename T1, typename R1 > 00295 bool operator!=( const Pointer<T1, R1>& right ) const { 00296 return !( this->value == right.get() ); 00297 } 00298 00299 template< typename T1 > 00300 Pointer<T1, CounterType> dynamicCast() const { 00301 return Pointer<T1, CounterType>( *this, DYNAMIC_CAST_TOKEN() ); 00302 } 00303 00304 template< typename T1 > 00305 Pointer<T1, CounterType> staticCast() const { 00306 return Pointer<T1, CounterType>( *this, STATIC_CAST_TOKEN() ); 00307 } 00308 00309 private: 00310 00311 // Internal Static deletion function. 00312 static void onDeleteFunc(T* value) { 00313 delete value; 00314 } 00315 00316 }; 00317 00319 template< typename T, typename R, typename U > 00320 inline bool operator==( const Pointer<T, R>& left, const U* right ) { 00321 return left.get() == right; 00322 } 00323 00325 template< typename T, typename R, typename U > 00326 inline bool operator==( const U* left, const Pointer<T, R>& right ) { 00327 return right.get() == left; 00328 } 00329 00331 template< typename T, typename R, typename U > 00332 inline bool operator!=( const Pointer<T, R>& left, const U* right ) { 00333 return !( left.get() == right ); 00334 } 00335 00337 template< typename T, typename R, typename U > 00338 inline bool operator!=( const U* left, const Pointer<T, R>& right ) { 00339 return right.get() != left; 00340 } 00341 00354 template< typename T, typename R = decaf::util::concurrent::atomic::AtomicRefCounter > 00355 class PointerComparator : public decaf::util::Comparator< Pointer<T,R> > { 00356 public: 00357 00358 virtual ~PointerComparator() {} 00359 00360 // Allows for operator less on types that implement Comparable or provide 00361 // a workable operator < 00362 virtual bool operator() ( const Pointer<T,R>& left, const Pointer<T,R>& right ) const { 00363 return *left < *right; 00364 } 00365 00366 // Requires that the type in the pointer is an instance of a Comparable. 00367 virtual int compare( const Pointer<T,R>& left, const Pointer<T,R>& right ) const { 00368 return *left < *right ? -1 : *right < *left ? 1 : 0; 00369 } 00370 00371 }; 00372 00373 }} 00374 00376 namespace std{ 00377 00382 template< typename T > 00383 struct less< decaf::lang::Pointer<T> > : 00384 public binary_function< decaf::lang::Pointer<T>, 00385 decaf::lang::Pointer<T>, bool> 00386 { 00387 bool operator()( const decaf::lang::Pointer<T>& left, 00388 const decaf::lang::Pointer<T>& right ) const 00389 { 00390 return less<T*>()( left.get(), right.get() ); 00391 } 00392 }; 00393 } 00394 00395 #endif /*_DECAF_LANG_POINTER_H_*/