activemq-cpp-3.4.0

src/main/decaf/lang/Pointer.h

Go to the documentation of this file.
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_*/