// -*-c++-*-
// A reference counted pointer class

#ifndef _smart_ptr_h
#define _smart_ptr_h

#include <stdlib.h>

template <class T>
class smart_ptr {
public:
  explicit smart_ptr(T *x = 0) { rep = new Rep(x); }
  smart_ptr(const smart_ptr<T> &sp) {
    rep = sp.rep;
    rep->count++;
  }
  ~smart_ptr() { if (--rep->count <= 0) delete rep; }
  
  T *release() {
    T *ret = rep->obj;
    rep->obj = 0;
    return ret;
  }

  const T* get() const { return rep->obj; }
  T* get() { return rep->obj; }
  const T* operator->() const { return rep->obj; }
  T* operator->() { return rep->obj; }
  
  T& operator*() { if (rep->obj) return *(rep->obj); else abort(); }
  const T& operator*() const {
    if (rep->obj) return *(rep->obj); else abort();
  }

  smart_ptr<T>& operator=(const smart_ptr<T>& sp) {
    if (&sp != this) {
      if (--rep->count <= 0)
	delete rep;
      rep = sp.rep;
      rep->count++;
    }
    return *this;
  }

private:

  struct Rep {
    Rep(T *p) { count = 1; obj = p; }
    ~Rep() { delete obj; }
    int count;
    T *obj;
  };

  Rep *rep;
};
  
#endif  // _smart_ptr_h
