// Copyright (C) 1993-2002 David R. Cheriton.  All rights reserved.

#ifndef __PTRINTERFACE_H_
#define __PTRINTERFACE_H_

typedef long RefCount;

/**
 * PtrInterface defines a template interface for top-level reference-managed
 * classes.  The template parameter T is the class itself.
 * <p>
 * PtrInterface, or PtrInterfaceFrom should be used for all entity classes
 * that provide shared access, and therefore need reference management.
 * <p>
 * - Use PtrInterface for top-level interfaces.
 * - Use PtrInterfaceFrom for derived interfaces.
 *
 * @author David Cheriton, modified by Ed Swierk
 * @version Stanford CS 249 Winter 2002 version 1.0
 */
template <class T>
class PtrInterface {
public:
    PtrInterface() : references_(0) {
        // Nothing else to do.
    }

    RefCount references() const {
        return references_;
    }

    const PtrInterface<T> * newRef() const {
        references_ += 1;
        return this;
    }

    void deleteRef() const {
        int n = references_ - 1;
        references_ = n;
        if (n == 0) {
            const_cast<PtrInterface<T>*>(this)->onZeroReferences();
        }
    }

protected:
    virtual ~PtrInterface() {
        // Nothing to do.
    }

private:
    virtual void onZeroReferences() {
        delete this;
    }

    mutable RefCount references_;
};

#endif

