/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _LOG4CXX_HELPERS_OBJECT_PTR_H #define _LOG4CXX_HELPERS_OBJECT_PTR_H #include // // Helgrind (race detection tool for Valgrind) will complain if pointer // is not initialized in an atomic operation. Static analysis tools // (gcc's -Weffc++, for example) will complain if pointer is not initialized // in member initialization list. The use of a macro allows quick // switching between the initialization styles. // #if LOG4CXX_HELGRIND #define _LOG4CXX_OBJECTPTR_INIT(x) { exchange(x); #else #define _LOG4CXX_OBJECTPTR_INIT(x) : p(x) { #endif namespace log4cxx { namespace helpers { class Class; class LOG4CXX_EXPORT ObjectPtrBase { public: ObjectPtrBase(); virtual ~ObjectPtrBase(); static void checkNull(const int& null); static void* exchange(void** destination, void* newValue); virtual void* cast(const Class& cls) const = 0; }; /** smart pointer to a Object descendant */ template class ObjectPtrT : public ObjectPtrBase { public: ObjectPtrT(const int& null) _LOG4CXX_OBJECTPTR_INIT(0) ObjectPtrBase::checkNull(null); } ObjectPtrT() _LOG4CXX_OBJECTPTR_INIT(0) } ObjectPtrT(T * p1) _LOG4CXX_OBJECTPTR_INIT(p1) if (this->p != 0) { this->p->addRef(); } } ObjectPtrT(const ObjectPtrT& p1) _LOG4CXX_OBJECTPTR_INIT(p1.p) if (this->p != 0) { this->p->addRef(); } } ObjectPtrT(const ObjectPtrBase& p1) _LOG4CXX_OBJECTPTR_INIT(reinterpret_cast(p1.cast(T::getStaticClass()))) if (this->p != 0) { this->p->addRef(); } } ObjectPtrT(ObjectPtrBase& p1) _LOG4CXX_OBJECTPTR_INIT(reinterpret_cast(p1.cast(T::getStaticClass()))) if (this->p != 0) { this->p->addRef(); } } ~ObjectPtrT() { if (p != 0) { p->releaseRef(); } } ObjectPtrT& operator=(const ObjectPtrT& p1) { T* newPtr = p1.p; if (newPtr != 0) { newPtr->addRef(); } T* oldPtr = exchange(newPtr); if (oldPtr != 0) { oldPtr->releaseRef(); } return *this; } ObjectPtrT& operator=(const int& null) //throw(IllegalArgumentException) { // // throws IllegalArgumentException if null != 0 // ObjectPtrBase::checkNull(null); T* oldPtr = exchange(0); if (oldPtr != 0) { oldPtr->releaseRef(); } return *this; } ObjectPtrT& operator=(T* p1) { if (p1 != 0) { p1->addRef(); } T* oldPtr = exchange(p1); if (oldPtr != 0) { oldPtr->releaseRef(); } return *this; } ObjectPtrT& operator=(ObjectPtrBase& p1) { T* newPtr = reinterpret_cast(p1.cast(T::getStaticClass())); return operator=(newPtr); } ObjectPtrT& operator=(const ObjectPtrBase& p1) { T* newPtr = reinterpret_cast(p1.cast(T::getStaticClass())); return operator=(newPtr); } bool operator==(const ObjectPtrT& p1) const { return (this->p == p1.p); } bool operator!=(const ObjectPtrT& p1) const { return (this->p != p1.p); } bool operator<(const ObjectPtrT& p1) const { return (this->p < p1.p); } bool operator==(const T* p1) const { return (this->p == p1); } bool operator!=(const T* p1) const { return (this->p != p1); } bool operator<(const T* p1) const { return (this->p < p1); } T* operator->() const {return p; } T& operator*() const {return *p; } operator T*() const {return p; } private: T * p; virtual void* cast(const Class& cls) const { if (p != 0) { return const_cast(p->cast(cls)); } return 0; } T* exchange(const T* newValue) { return static_cast(ObjectPtrBase::exchange( reinterpret_cast(&p), const_cast(newValue))); } }; } } #endif //_LOG4CXX_HELPERS_OBJECT_PTR_H