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

#ifndef __PTR_H_
#define __PTR_H_

template <class T>
class Ptr {
public:
    Ptr(T* rawPtr = 0);
    Ptr(const Ptr<T>& ptr);
    ~Ptr();

    void operator =(const Ptr<T>& ptr);

    bool operator ==(const Ptr<T>& ptr) const {
        return rawPtr_ == ptr.rawPtr_;
    }

    bool operator !=(const Ptr<T>& ptr) const {
        return rawPtr_ != ptr.rawPtr_;
    }

    inline const T* operator ->() const {
        return rawPtr_;
    }

    inline T* operator ->() {
        return rawPtr_;
    }

    inline T* value() const {
        return rawPtr_;
    }

    template <class OtherType>
    inline operator Ptr<OtherType>() const {
        return Ptr<OtherType>(rawPtr_);
    }

protected:
    T* rawPtr_;
};

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

template<class T>
Ptr<T>::Ptr(T* rawPtr) : rawPtr_(rawPtr) {
    if (rawPtr != 0) {
        rawPtr_->newRef();
    }
}

template<class T>
Ptr<T>::Ptr(const Ptr<T>& ptr) : rawPtr_(ptr.rawPtr_) {
    if (rawPtr_ != 0) {
        rawPtr_->newRef();
    }
}

template<class T>
Ptr<T>::~Ptr() {
    if (rawPtr_ != 0) {
        rawPtr_->deleteRef();
    }
}

template<class T> void
Ptr<T>::operator =(const Ptr<T>& ptr) {
    const T* save = rawPtr_;
    rawPtr_ = ptr.rawPtr_;
    if (rawPtr_ != 0) {
        rawPtr_->newRef();
    }
    if (save != 0) {
        save->deleteRef();
    }
}

#endif

