// ********************************************************************** // // Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #pragma once #include #include // // "Handle" or "smart pointer" class for classes derived from // IceUtil::Shared, IceUtil::SimpleShared, or IceInternal::GCShared. // namespace IceUtil { template class HandleBase { public: typedef T element_type; T* get() const { return _ptr; } T* operator->() const { if(!_ptr) { // // We don't throw directly NullHandleException here to // keep the code size of this method to a minimun (the // assembly code for throwing an exception is much bigger // than just a function call). This maximises the chances // of inlining by compiler optimization. // throwNullHandleException(__FILE__, __LINE__); } return _ptr; } T& operator*() const { if(!_ptr) { // // We don't throw directly NullHandleException here to // keep the code size of this method to a minimun (the // assembly code for throwing an exception is much bigger // than just a function call). This maximises the chances // of inlining by compiler optimization. // throwNullHandleException(__FILE__, __LINE__); } return *_ptr; } operator bool() const { return _ptr ? true : false; } void swap(HandleBase& other) { std::swap(_ptr, other._ptr); } T* _ptr; private: void throwNullHandleException(const char *, int) const; }; template inline void HandleBase::throwNullHandleException(const char* file, int line) const { throw NullHandleException(file, line); } template inline bool operator==(const HandleBase& lhs, const HandleBase& rhs) { T* l = lhs.get(); U* r = rhs.get(); if(l && r) { return *l == *r; } // Note: don't use if { } else { }. This causes lots warnings when // compiling with GCC and optimization enabled. See bug 2330. return !l && !r; } template inline bool operator!=(const HandleBase& lhs, const HandleBase& rhs) { return !operator==(lhs, rhs); } template inline bool operator<(const HandleBase& lhs, const HandleBase& rhs) { T* l = lhs.get(); U* r = rhs.get(); if(l && r) { return *l < *r; } // Note: don't use if { } else { }. This causes lots warnings when // compiling with GCC and optimization enabled. See bug 2330. return !l && r; } template inline bool operator<=(const HandleBase& lhs, const HandleBase& rhs) { return lhs < rhs || lhs == rhs; } template inline bool operator>(const HandleBase& lhs, const HandleBase& rhs) { return !(lhs < rhs || lhs == rhs); } template inline bool operator>=(const HandleBase& lhs, const HandleBase& rhs) { return !(lhs < rhs); } template class Handle : public HandleBase { public: Handle(T* p = 0) { this->_ptr = p; if(this->_ptr) { this->_ptr->__incRef(); } } template Handle(const Handle& r) { this->_ptr = r._ptr; if(this->_ptr) { this->_ptr->__incRef(); } } Handle(const Handle& r) { this->_ptr = r._ptr; if(this->_ptr) { this->_ptr->__incRef(); } } ~Handle() { if(this->_ptr) { this->_ptr->__decRef(); } } Handle& operator=(T* p) { if(this->_ptr != p) { if(p) { p->__incRef(); } T* ptr = this->_ptr; this->_ptr = p; if(ptr) { ptr->__decRef(); } } return *this; } template Handle& operator=(const Handle& r) { if(this->_ptr != r._ptr) { if(r._ptr) { r._ptr->__incRef(); } T* ptr = this->_ptr; this->_ptr = r._ptr; if(ptr) { ptr->__decRef(); } } return *this; } Handle& operator=(const Handle& r) { if(this->_ptr != r._ptr) { if(r._ptr) { r._ptr->__incRef(); } T* ptr = this->_ptr; this->_ptr = r._ptr; if(ptr) { ptr->__decRef(); } } return *this; } template static Handle dynamicCast(const HandleBase& r) { return Handle(dynamic_cast(r._ptr)); } template static Handle dynamicCast(Y* p) { return Handle(dynamic_cast(p)); } }; }