PreallocatedArray code review
So I wrote a collection class that like std::array, it stores its
elements as values in the objects without using indirection, but also
allows less than the entire allocation to be used. I'm sure I've made C
++ newbie errors writing this, so could someone help me find them?
I assure you that I do have need for such a class, hard as that may be
to believe; I'm storing data directly in special file-backed memory.
But that isn't relevant to the implementation.
- Jimmy H.
#ifndef PREALLOCATED_ARRAY_H
#define PREALLOCATED_ARRAY_H
#include <stdexcept>
#include <utility>
template <class T, size_t N>
class PreallocatedArray {
char memory[sizeof(T) * N];
size_t valid_size;
public:
PreallocatedArray() : valid_size(0) { }
PreallocatedArray(PreallocatedArray <T, N> &other) :
valid_size(other.valid_size) {
for (size_t s(0); s < valid_size; ++s) {
new (&operator [](s)) T(other[s]);
}
}
T &at(size_t pos) {
if (pos >= valid_size) throw std::out_of_range("Overran Limit");
return operator[](pos);
}
const T &at(size_t pos) const {
if (pos >= valid_size) throw std::out_of_range("Overran Limit");
return operator[](pos);
}
T &operator [] (size_t pos) {
return ((T *)memory)[pos];
}
const T &operator [] (size_t pos) const {
return ((T *)memory)[pos];
}
T *begin() {
return &operator [](0);
}
T *end() {
return &operator [](valid_size);
}
const T *cbegin() {
return &operator [](0);
}
const T *cend() {
return &operator [](valid_size);
}
bool empty() {
return valid_size == 0;
}
size_t size() {
return valid_size;
}
size_t max_size() {
return N;
}
void resize(size_t new_size) {
if (new_size > max_size()) throw std::out_of_range("Exceeds
alloc");
if (new_size > valid_size) {
// Grow
for (; valid_size < new_size; ++valid_size) {
void *addr(memory + valid_size * sizeof(T));
new (addr) T;
}
} else {
// Shrink
for (; valid_size > new_size; --valid_size) {
(&operator[](valid_size - 1))->~T();
}
}
}
~PreallocatedArray() {
for(size_t s(0); s < valid_size; ++s) {
(&operator[](s))->~T();
}
}
void swap(PreallocatedArray<T, N> &other) {
using std::swap;
for (size_t s(0); s < N; ++s) {
if (s < other.valid_size && s < valid_size) {
std::swap(operator[](s), other[s]);
} else if (s < other.valid_size && s >= valid_size) {
new (&operator[](s)) T(std::move(other[s]));
(&other[s])->~T();
} else if (s >= other.valid_size && s < valid_size) {
new (&other[s]) T(std::move(operator[](s)));
(&operator[](s))->~T();
} else {
break;
}
}
swap(valid_size, other.valid_size);
}
PreallocatedArray<T, N> &operator =(const PreallocatedArray &other)
{
for(size_t s(0); s < N; ++s) {
if (s < valid_size && s < other.valid_size) {
operator[](s) = other[s];
} else if (s >= valid_size && s < other.valid_size) {
new (&operator[](s)) T(other[s]);
} else if (s < valid_size && s >= other.valid_size) {
(&operator[](s))->~T();
} else {
break;
}
}
valid_size = other.valid_size;
}
friend void swap(PreallocatedArray<T, N> &a,
PreallocatedArray<T, N> &b) {
a.swap(b);
}
};
#endif
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]