diff options
Diffstat (limited to 'sdo-cpp/trunk/runtime/core/src/commonj/sdo/RefCountingPointer.h')
-rw-r--r-- | sdo-cpp/trunk/runtime/core/src/commonj/sdo/RefCountingPointer.h | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/sdo-cpp/trunk/runtime/core/src/commonj/sdo/RefCountingPointer.h b/sdo-cpp/trunk/runtime/core/src/commonj/sdo/RefCountingPointer.h new file mode 100644 index 0000000000..c4cbc41197 --- /dev/null +++ b/sdo-cpp/trunk/runtime/core/src/commonj/sdo/RefCountingPointer.h @@ -0,0 +1,283 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +#ifndef _REFCOUNTINGPOINTER_H +#define _REFCOUNTINGPOINTER_H + + +#include "commonj/sdo/export.h" +#include "commonj/sdo/SDORuntimeException.h" + +#include <iostream> + +namespace commonj{ +namespace sdo{ + +/** + * RefcountingPointer is a template for all SDO pointers. + * The ref count increases with each use, and drops when one of these + * goes out of scope. + * Refcounting pointers are a lot like smart pointers, however in this + * implementation there is a cast method to a void*, so unlike real + * smart pointers, a user might call "delete mypointer", which would + * compile, but cause a crash. + * RefCountingPointers do not need to be deleted. + */ + +template <class T> +class RefCountingPointer { + // This private typedef is an offset pointer to a member function. + // It helps us with a trick for safe conversions to bool + typedef void (RefCountingPointer<T>::*UnspecifiedBoolType)() const; + + public: + typedef T* PointerType; + + /*SDO_API*/ RefCountingPointer(PointerType realPtr = 0); + /*SDO_API*/ RefCountingPointer(const RefCountingPointer& rhs); + template <typename otherType> + RefCountingPointer(const RefCountingPointer<otherType>& rhs) + : pointee(getRawPointer(rhs)) + { + init(); + } + /*SDO_API*/ ~RefCountingPointer(); + /*SDO_API*/ RefCountingPointer& operator=(const RefCountingPointer& rhs); + /*SDO_API*/ T* operator->() const; + /*SDO_API*/ T& operator*() const; + /*SDO_API*/ bool operator!() const; + + // Returns an unspecified boolean type to allow for testing if the + // associated pointer is null. The boolean type is not specified in order + // to avoid unintended implicit conversions. + operator typename RefCountingPointer<T>::UnspecifiedBoolType() const + { + if (pointee) { + return &RefCountingPointer<T>::UnspecifiedBoolHelper; + } + return 0; + } + + template <class otherType> + operator RefCountingPointer<otherType>() + { + return RefCountingPointer<otherType>(pointee); + } + + template <class otherType> + operator const RefCountingPointer<otherType>() const + { + return RefCountingPointer<otherType>(pointee); + } + + friend std::ostream& operator<< (std::ostream &os, const RefCountingPointer<T>& ptr) + { + if (!ptr) + { + os << "RefCountingPointer is NULL" << std::endl; + } + else + { + ptr->printSelf(os); + } + + return os; + } + + // utility function for accessing the underlying raw pointer + template <class otherType> + friend otherType* getRawPointer(const RefCountingPointer<otherType>& pointer); + + private: + // Defines a member function we can return the addresss to when + // evaluating whether the pointer is valid or not. This function + // serves no purpose beyond providing a non-zero value for use in + // boolean expressions. + void UnspecifiedBoolHelper() const {} + + PointerType pointee; + void init(); +}; + + + +template<class T> +void RefCountingPointer<T>::init() +{ + if (pointee == 0) return; + pointee->addRef(); +} + +template<class T> +/*SDO_API*/ RefCountingPointer<T>::RefCountingPointer(typename RefCountingPointer<T>::PointerType realPtr) +:pointee(realPtr) +{ + init(); +} + +template<class T> +/*SDO_API*/ RefCountingPointer<T>::RefCountingPointer(const RefCountingPointer& rhs) +: pointee(rhs.pointee) +{ + init(); +} + +template<class T> +/*SDO_API*/ RefCountingPointer<T>::~RefCountingPointer() +{ + if (pointee)pointee->releaseRef(); +} + +template<class T> +/*SDO_API*/ RefCountingPointer<T>& RefCountingPointer<T>::operator=(const RefCountingPointer& rhs) +{ + if (pointee != rhs.pointee) + { + T *oldP = pointee; + pointee = rhs.pointee; + init(); + if (oldP) oldP->releaseRef(); + } + return *this; +} + +template<class T> +/*SDO_API*/ bool RefCountingPointer<T>::operator!() const +{ + return (pointee == 0); +} + +template<class T> +/*SDO_API*/ T* RefCountingPointer<T>::operator->() const +{ + if (pointee == 0) + throw SDONullPointerException(TUSCANY_SDO_EINFO, + ""); + return pointee; +} + +template<class T> +/*SDO_API*/ T& RefCountingPointer<T>::operator*() const +{ + return *pointee; +} + +template <class otherType> +otherType* getRawPointer(const RefCountingPointer<otherType>& pointer) +{ + return pointer.pointee; +} + +template <class T, class otherType> +T dynamicCast(const RefCountingPointer<otherType>& pointer) +{ + return dynamic_cast<typename T::PointerType>(getRawPointer(pointer)); +} + +template <class T, class otherType> +T staticCast(const RefCountingPointer<otherType>& pointer) +{ + return static_cast<typename T::PointerType>(getRawPointer(pointer)); +} + +template <class T, class otherType> +bool operator==(const RefCountingPointer<T>& first, const RefCountingPointer<otherType>& second) +{ + return (getRawPointer(first) == getRawPointer(second)); +} + +template <class T, class otherType> +bool operator==(const RefCountingPointer<T>& first, const otherType* second) +{ + return (getRawPointer(first) == second); +} + +template <class T, class otherType> +bool operator==(const T* first, const RefCountingPointer<otherType>& second) +{ + return (first == getRawPointer(second)); +} + +template <class T, class otherType> +bool operator!=(const RefCountingPointer<T>& first, const RefCountingPointer<otherType>& second) +{ + return !(first == second); +} + +template <class T, class otherType> +bool operator!=(const RefCountingPointer<T>& first, const otherType* second) +{ + return !(first == second); +} + +template <class T, class otherType> +bool operator!=(const T* first, const RefCountingPointer<otherType>& second) +{ + return !(first == second); +} + +template <class T, class otherType> +bool operator<(const RefCountingPointer<T>& first, const RefCountingPointer<otherType>& second) +{ + return (getRawPointer(first) < getRawPointer(second)); +} + +template <class T, class otherType> +bool operator>(const RefCountingPointer<T>& first, const RefCountingPointer<otherType>& second) +{ + return (second < first); +} + +class DataObject; +typedef RefCountingPointer<DataObject> DataObjectPtr; +class DataObjectImpl; +typedef RefCountingPointer<DataObjectImpl> DataObjectImplPtr; +class Property; +typedef RefCountingPointer<Property> PropertyPtr; +class PropertyImpl; +typedef RefCountingPointer<PropertyImpl> PropertyImplPtr; +class DataGraph; +typedef RefCountingPointer<DataGraph> DataGraphPtr; +class DataFactory; +typedef RefCountingPointer<DataFactory> DataFactoryPtr; +class DataFactoryImpl; +typedef RefCountingPointer<DataFactoryImpl> DataFactoryImplPtr; +class Sequence; +typedef RefCountingPointer<Sequence> SequencePtr; +class SequenceImpl; +typedef RefCountingPointer<SequenceImpl> SequenceImplPtr; +class ChangeSummary; +typedef RefCountingPointer<ChangeSummary> ChangeSummaryPtr; +class ChangeSummaryImpl; +typedef RefCountingPointer<ChangeSummaryImpl> ChangeSummaryImplPtr; +class XMLDocument; +typedef RefCountingPointer<XMLDocument> XMLDocumentPtr; +class XSDHelper; +typedef RefCountingPointer<XSDHelper> XSDHelperPtr; +class XSDHelperImpl; +typedef RefCountingPointer<XSDHelperImpl> XSDHelperImplPtr; +class XMLHelper; +typedef RefCountingPointer<XMLHelper> XMLHelperPtr; + +} +} + +#endif |