This version of the double-bounded array specifically
    	       removes the default copying.
#ifndef _BOUNDARR_H_
#define _BOUNDARR_H_
/*
 * This class implements an array with user-specified bounds.  Subscripting
 * is done with a at() function, and subscripts are bounds-checked.
 * Objects of this class may not be copied.
 */
#include <iostream>
#include <string>
#include <stdexcept>
#include <memory>
#include <algorithm>
template <typename T>
class BoundArr {
public:
        // Create a new array of the given dimensions
        BoundArr(int low, int high):
                m_space(new T[high-low+1]), m_low(low), m_high(high) { }
        // Convenience for conventional creation.
        BoundArr(int size): m_space(new T[size]), m_low(0), m_high(size-1) { }
        // Create an array as a copy of another.
        BoundArr(const BoundArr &other) = delete;
        // Perform an array assignment.  Delete our space, then make us a
        // copy of other.
        BoundArr & operator=(const BoundArr &other) = delete;
        // Find out how large this is.
        int low() const { return m_low; }
        int high() const { return m_high; }
        int size() const { return m_high - m_low + 1; }
        // Subscript the array.  The two versions are allowed, and will
        // be chosen based on the context of use.
        T &at(int subs) { return m_space[offset(subs)]; }
        T const &at(int subs) const { return m_space[offset(subs)]; }
        
        // Print the array to the stream.
        void print(std::ostream &out) const;
private:
        std::shared_ptr<T[]> m_space; // Actual storage space for the array.
        int m_low, m_high;      // Bounds
        // Check the bounds, throw if out, then 
        int offset(int sub) const;
};
// Check that the sub is in range, and throw if it is not.  Otherwise,
// return the sub adjusted to an offset for subscripting the base array.
template <typename T>
int BoundArr<T>::offset(int sub) const
{
        if(sub < m_low || m_high < sub)
                throw std::range_error("Bounds: sub " + std::to_string(sub) +
                                       " outside " + std::to_string(m_low) +
                                       ".." + std::to_string(m_high));
        return sub - m_low;
}
// Array printer
template <typename T>
void BoundArr<T>::print(std::ostream &out) const
{
        out << "<" << m_low << "|";
        for(int n = 0; n < size(); ++n) {
                out << " " << m_space[n];
        }
        out << " |" << m_high << ">";
}
// This exports the printing function to standard streams by defining
// the meaning of << on a stream and a BoundArr to be running the print
// method on the array to the stream.
template <typename T>
inline std::ostream & operator<<(std::ostream &strm, const BoundArr<T> &arr) 
{
        arr.print(strm);
        return strm;
}
#endif