/* * e4refcount.cpp -- * * The base class for all interface classes, manages reference counts. * * Authors: Jacob Levy and Jean-Claude Wippler. * jyl@best.com jcw@equi4.com * * This implementation is modelled after the c4_View class in Metakit. * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "e4graphimpl.h" /* * This instance of e4_RefCount can be used by assigning it to fields or * variables of type e4_RefCount to remove remaining references to instances * that you want to discard. Especially useful for removing remaining * references in malloc'ed memory. */ e4_RefCount const invalidRefCount; /* * Default constructor: */ e4_RefCount::e4_RefCount() : impl(NULL) { } /* * Constructor which assigns a value to the implementation pointer. */ e4_RefCount::e4_RefCount(e4_RefCounter *ip) : impl(ip) { if (impl != NULL) { impl->IncrRefCount(); } } /* * Copying constructor: */ e4_RefCount::e4_RefCount(const e4_RefCount &referrer) { impl = referrer.impl; if (impl != NULL) { impl->IncrRefCount(); } } /* * Assignment operator: */ e4_RefCount & e4_RefCount::operator=(const e4_RefCount &referrer) { /* * Only do the assignment if the referrer is of the same kind * as us. */ if (Kind() != referrer.Kind()) { return *this; } /* * Do the assignment. */ if (impl != referrer.impl) { if (impl != NULL) { impl->DecrRefCount(); } impl = referrer.impl; if (impl != NULL) { impl->IncrRefCount(); } } return *this; } /* * Destructor: */ e4_RefCount::~e4_RefCount() { if (impl != NULL) { impl->DecrRefCount(); } } /* * Return the current refcount. If the instance is invalid then * returns -1. */ int e4_RefCount::RefCount() const { if (impl == NULL) { return -1; } return impl->RefCount(); } bool e4_RefCount::IsValid() const { if (impl == NULL) { return false; } return impl->IsValid(); } /* * Comparison operators. */ bool e4_RefCount::operator==(const e4_RefCount &compared) const { /* * First check -- compare the two impl pointers. If they're * equal and non-NULL then the two instances are the same. */ if ((impl != NULL) && (impl == compared.impl)) { return true; } /* * Handle invalid instances specially. */ if (!IsValid()) { /* * If the other instance is valid, then it can't be equal to this * instance. */ if (compared.IsValid()) { return false; } /* * OK, the other one is also invalid, so we must compare the kind. * They are equal only if both are invalid instances of the * same kind. */ if (Kind() != compared.Kind()) { return false; } /* * All invalid instances of the same kind are equal. */ return true; } /* * This instance is valid, so to be equal, its impl pointer must be * the same as the other instance. */ if (impl == compared.impl) { return true; } /* * Not equal: */ return false; } bool e4_RefCount::operator!=(const e4_RefCount &compared) const { /* * First check -- compare the two impl pointers. If they're * equal and non-NULL then the two instances are the same. */ if ((impl != NULL) && (impl == compared.impl)) { return false; } /* * Handle invalid instances specially: */ if (!IsValid()) { /* * If the other instance is valid, they are not equal, so return * true. */ if (compared.IsValid()) { return true; } /* * The other instance is also invalid. To determine equality we * must compare the two instances' kind. If their kinds are not * equal, then this operator is true. */ if (Kind() != compared.Kind()) { return true; } /* * All invalid instances of the same kind are equal, so return false. */ return false; } /* * Both instances are valid, so to be inequal their impl pointers must * be different. */ if (impl != compared.impl) { return true; } /* * The two instances turn out to be equal: */ return false; } /* * Return the kind identifier for this instance. This should be overridden * by classes deriving from e4_RefCount. */ e4_RefKind e4_RefCount::Kind() const { return E4_RKINVALID; } /* * Set and get user level data associated with each instance. */ void e4_RefCount::SetTransientUserData(void *data) const { if (impl != NULL) { impl->SetTransientUserData(data); } } void * e4_RefCount::GetTransientUserData() const { if (impl == NULL) { return NULL; } return impl->GetTransientUserData(); }