This is the first of several implementations of the
    	       double-bounded array.  It mostly works, but has a problem
	       that we will examine later.
#ifndef _BOUNDARR_H_
#define _BOUNDARR_H_
/*
 * This class sort of implements an array with user-specified bounds.  
 * Subscripting is done with a at() function, and subscripts are 
 * bounds-checked.  This is actually a broken implementation since
 * Objects in this version do not copy correctly.
 */
#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) { }
        // 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 return the return the offset
        // in the private array corresponding to sub.
        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