/* * 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 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 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::*UnspecifiedBoolType)() const; public: typedef T* PointerType; /*SDO_API*/ RefCountingPointer(PointerType realPtr = 0); /*SDO_API*/ RefCountingPointer(const RefCountingPointer& rhs); template RefCountingPointer(const RefCountingPointer& 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::UnspecifiedBoolType() const { if (pointee) { return &RefCountingPointer::UnspecifiedBoolHelper; } return 0; } template operator RefCountingPointer() { return RefCountingPointer(pointee); } template operator const RefCountingPointer() const { return RefCountingPointer(pointee); } friend std::ostream& operator<< (std::ostream &os, const RefCountingPointer& ptr) { if (!ptr) { os << "RefCountingPointer is NULL" << std::endl; } else { ptr->printSelf(os); } return os; } // utility function for accessing the underlying raw pointer template friend otherType* getRawPointer(const RefCountingPointer& 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 void RefCountingPointer::init() { if (pointee == 0) return; pointee->addRef(); } template /*SDO_API*/ RefCountingPointer::RefCountingPointer(typename RefCountingPointer::PointerType realPtr) :pointee(realPtr) { init(); } template /*SDO_API*/ RefCountingPointer::RefCountingPointer(const RefCountingPointer& rhs) : pointee(rhs.pointee) { init(); } template /*SDO_API*/ RefCountingPointer::~RefCountingPointer() { if (pointee)pointee->releaseRef(); } template /*SDO_API*/ RefCountingPointer& RefCountingPointer::operator=(const RefCountingPointer& rhs) { if (pointee != rhs.pointee) { T *oldP = pointee; pointee = rhs.pointee; init(); if (oldP) oldP->releaseRef(); } return *this; } template /*SDO_API*/ bool RefCountingPointer::operator!() const { return (pointee == 0); } template /*SDO_API*/ T* RefCountingPointer::operator->() const { if (pointee == 0) throw SDONullPointerException(TUSCANY_SDO_EINFO, ""); return pointee; } template /*SDO_API*/ T& RefCountingPointer::operator*() const { return *pointee; } template otherType* getRawPointer(const RefCountingPointer& pointer) { return pointer.pointee; } template T dynamicCast(const RefCountingPointer& pointer) { return dynamic_cast(getRawPointer(pointer)); } template T staticCast(const RefCountingPointer& pointer) { return static_cast(getRawPointer(pointer)); } template bool operator==(const RefCountingPointer& first, const RefCountingPointer& second) { return (getRawPointer(first) == getRawPointer(second)); } template bool operator==(const RefCountingPointer& first, const otherType* second) { return (getRawPointer(first) == second); } template bool operator==(const T* first, const RefCountingPointer& second) { return (first == getRawPointer(second)); } template bool operator!=(const RefCountingPointer& first, const RefCountingPointer& second) { return !(first == second); } template bool operator!=(const RefCountingPointer& first, const otherType* second) { return !(first == second); } template bool operator!=(const T* first, const RefCountingPointer& second) { return !(first == second); } template bool operator<(const RefCountingPointer& first, const RefCountingPointer& second) { return (getRawPointer(first) < getRawPointer(second)); } template bool operator>(const RefCountingPointer& first, const RefCountingPointer& second) { return (second < first); } class DataObject; typedef RefCountingPointer DataObjectPtr; class DataObjectImpl; typedef RefCountingPointer DataObjectImplPtr; class Property; typedef RefCountingPointer PropertyPtr; class PropertyImpl; typedef RefCountingPointer PropertyImplPtr; class DataGraph; typedef RefCountingPointer DataGraphPtr; class DataFactory; typedef RefCountingPointer DataFactoryPtr; class DataFactoryImpl; typedef RefCountingPointer DataFactoryImplPtr; class Sequence; typedef RefCountingPointer SequencePtr; class SequenceImpl; typedef RefCountingPointer SequenceImplPtr; class ChangeSummary; typedef RefCountingPointer ChangeSummaryPtr; class ChangeSummaryImpl; typedef RefCountingPointer ChangeSummaryImplPtr; class XMLDocument; typedef RefCountingPointer XMLDocumentPtr; class XSDHelper; typedef RefCountingPointer XSDHelperPtr; class XSDHelperImpl; typedef RefCountingPointer XSDHelperImplPtr; class XMLHelper; typedef RefCountingPointer XMLHelperPtr; } } #endif