#ifndef _SAFEARR3_H_
#define _SAFEARR3_H_
#include <iostream>
#include <string>
#include <algorithm>
#include <memory>
#include <stdexcept>
using namespace std;
template <typename T>
class SafeArr {
public:
// Create a new array of the given size.
SafeArr(int asize) {
m_size = asize;
m_space.reset(new T[asize]);
}
// Create an array as a copy of another.
SafeArr(const SafeArr &other) {
copyin(other);
}
// Find out how large this is.
int size() const { return m_size; }
// Perform an array assignment. Delete our space, then make us a
// copy of other.
SafeArr & operator=(const SafeArr &other)
{
copyin(other);
return *this;
}
// Store into the array, or print an error message and don't
// change the aray.
void store(int pos, const T &tostore) {
if(pos < m_size && pos >= 0) {
m_space[pos] = tostore;
} else {
throw out_of_range("gsafearr3 store at " +
to_string(pos) + " out of range " +
"0.." + to_string(m_size-1));
}
}
// Fetch from pos, or, if pos is out of bounds, print a message
// and return T().
T fetch(int pos) const {
if(pos < m_size && pos >= 0) {
return m_space[pos];
} else {
throw out_of_range("gsafearr3 fetch at " +
to_string(pos) + " out of range " +
"0.." + to_string(m_size-1));
}
}
// Alternate version of fetch that works when there is no T()
// (No default constructor for T.) Fills in the result through
// the parameter
void fetch(int pos, T &fetched) const {
fetched = fetch(pos);
}
// Array printer. Works if T can be printed with <<.
void print(ostream &out, string sep = " ") const
{
for(int n = 0; n < m_size; ++n) {
out << m_space[n];
if(n < m_size-1) out << " ";
}
}
private:
unique_ptr<T[]> m_space; // Room for the array.
int m_size; // Size of the array.
// Make us a copy of the other array. Allocates m_space of
// the same size, then copies the contents of other.m_size into it,
// and copies m_size.
void copyin(const SafeArr &other) {
m_space.reset(new T[other.m_size]);
m_size = other.m_size;
copy(other.m_space.get(), other.m_space.get() + other.m_size,
m_space.get());
}
};
/*
* This allows the array to be printed with <<, assuming T can be.
*/
template <typename T>
ostream & operator<<(ostream & strm, const SafeArr<T> &arr)
{
arr.print(strm);
return strm;
}
#endif