Listing 5

#include <cassert>

const bool deletable = true;

template<typename T>
class new_ptr {
public:
  new_ptr(T* x) : m(x) { };
  T* m;
};

template<typename T>
inline new_ptr<T> new_cast(T* x) {
  return new_ptr<T>(x);
}

template<typename T, bool can_delete = false>
class ptr {
public:
  ptr() : m(NULL) { };
  ptr(const ptr& x) : m(x.m) { };
  ptr(T* x) : m(x) { };
  ptr(const ptr<T, deletable>& x) : m(x.raw_pointer()) { };
  T* operator->() const { return m; }
private:
  T* m;
};

template<typename T>
class ptr<T, deleteable> {
public:
  ptr() : m(NULL) { };
  ptr(const ptr& x) : m(x.m) { };
  ptr(const new_ptr<T>& x) : m(x.m) { };
  void Delete() { assert(m != NULL); delete m; assert((m = NULL) == NULL); }
  T* operator->() const { return m; }
  T* raw_pointer() const { return m; }
  private:
  T* m;
};