#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 #include #include #include #include template 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 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 int BoundArr::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 void BoundArr::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 inline std::ostream & operator<<(std::ostream &strm, const BoundArr &arr) { arr.print(strm); return strm; } #endif