/* * 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 { public: /*SDO_API*/ RefCountingPointer(T* realPtr = 0); /*SDO_API*/ RefCountingPointer(const RefCountingPointer& rhs); /*SDO_API*/ ~RefCountingPointer(); /*SDO_API*/ RefCountingPointer& operator=(const RefCountingPointer& rhs); /*SDO_API*/ bool operator==(RefCountingPointer& test) const; /*SDO_API*/ T* operator->() const; /*SDO_API*/ T& operator*() const; /*SDO_API*/ bool operator!() const; #ifdef MFT // MFT == member function templates // Notes on the items below. // In our code, we use subclasses to expose the API, and super // classes to implement. E,g DataObject and DataObjectImpl. // In some cases, we know that the DataObject given to us is a // DataObjectImpl, and cast it. With RefCountingPointers, however, // the cast cannot work, as the RefCountingPointer to the superclass // is not related to the RCP to the subclass. Recent changes in the // C++ language allow this to work by defining an operator which // causes a pointer of the other type to be returned, as long as pointee // is acceptable as a parameter to the cosntructor of the other type // of pointer. This works in C++.NET, but not in C++6: operator RefCountingPointer() { return RefCountingPointer(pointee); } // Since we are using C6, a possible workround is to provide a method // which returns the dumb pointer, then construct a pointer to the // base class from the pointer returned. This is that the operator T* does. // The code in DataObject could be simpler if we used C7,and we should // discusss changing. #else operator T*() {return pointee;} #endif template operator RefCountingPointer() { 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; } private: T *pointee; void init(); }; template void RefCountingPointer::init() { if (pointee == 0) return; pointee->addRef(); } template /*SDO_API*/ RefCountingPointer::RefCountingPointer(T* 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*/ bool RefCountingPointer::operator==(RefCountingPointer& test) const { return (pointee == test.pointee); } template /*SDO_API*/ T* RefCountingPointer::operator->() const { if (pointee == 0) SDO_THROW_EXCEPTION("Pointer",SDONullPointerException, ""); return pointee; } template /*SDO_API*/ T& RefCountingPointer::operator*() const { return *pointee; } class DataObject; typedef RefCountingPointer DataObjectPtr; class DataGraph; typedef RefCountingPointer DataGraphPtr; class DataFactory; typedef RefCountingPointer DataFactoryPtr; class Sequence; typedef Sequence* SequencePtr; class ChangeSummary; typedef ChangeSummary* ChangeSummaryPtr; class XMLDocument; typedef RefCountingPointer XMLDocumentPtr; class XSDHelper; typedef RefCountingPointer XSDHelperPtr; class XMLHelper; typedef RefCountingPointer XMLHelperPtr; }; }; #endif