Pointer class/handle
Only need to point out one thing.

Constructor:

    p = new T[sz];


Destructor:

    delete p;


This code is broken. If you allocation with new [] you MUST destroy with delete [].

In the operator+= and operator-=

Ptr&amp; operator+=(int i) {
    check_range(index+i);
    index += i;
    p+= i;
    return *this;
}

Ptr&amp; operator-=(int i) {
    check_range(index-i);
    index -= i;
    p -= i;
    return *this;
}


Thus moving p during the lifetime of the object is not a good idea (because you must call delete on the pointer returned by new). So if you are going to move p you need to keep track of the original pointer in another member. But I would not move it all. You are adjusting index so why adjust p?

These can't return by reference:

Ptr&amp; operator+(int i) {
    Ptr old{*this};
    return old+=1;
}

Ptr&amp; operator-(int i) {
    Ptr old{*this};
    return old-=1;
}


You have to return by value because you are creating new values.

I am surprised that this works:

    Ptr old{*this};


Because you have deleted the copy constructor.

Ptr(const Ptr&amp;) = delete;


If it compiles I am not sure what is happening. But it is definitely not good.

In the constructor you should prefer initializer list.

Ptr(T* t, int s = 1) {
    sz = s;              // Initializer list
    p = new T[sz];       // Initializer list.

    // This seems inefficient.
    // Since the line above has just called the constructor on each element
    // element in the array. You are now calling the assignment operator
    // on each element in the array.
    for (int i = 0; i &lt; sz; ++i) {
        p[i] = t[i];
    }
}


You can optimize the above

Ptr(T* t, int s = 1)
    : sz(s)
    , p(reinterpret_cast&lt;T*&gt;(new char[s * sizeof(T)])  // Allocate aligned but uninitialized memory.
{
    for (int i = 0; i &lt; sz; ++i) {
        new (p + i) T(t[i]);       // Its called placement new.
                                   // The `(p + i)` is the address where you want the
                                   // construction to take place (ie don't allocate)
                                   // Then we use the copy constructor to create the
                                   // copy
    }
}