#ifndef oo_ObjArray_H__
#define oo_ObjArray_H__
#include "ObjBase.h"
#include "../Self.h"
#include <vector>
#include <string>
#include <typeinfo>
#include <cstdio>
#include <cstdlib>
namespace meow {
/*!
* @brief 純粹把 \c std::vector 包起來, 變成繼承自 ObjBase
*
* @author cathook
*/
template<class T>
class ObjArray: public ObjBase {
private:
struct Myself {
std::vector<T> array_;
Myself() {
}
~Myself() {
}
Myself& copyFrom(Myself const& b) {
array_ = b.array_;
return *this;
}
};
Self<Myself> const self;
public:
ObjArray(): self(true) {
}
ObjArray(ObjArray const& a): self(false) {
self().copyFrom(a.self);
}
ObjArray(std::vector<T> const& a): self(true) {
self()->array_ = a;
}
ObjArray(size_t sz, T const& e): self(true) {
self()->array_.resize(sz, e);
}
~ObjArray() {
}
ObjArray& copyFrom(ObjArray const& a) {
self().copyFrom(a.self);
return *this;
}
ObjArray& referenceFrom(ObjArray const& a) {
self().referenceFrom(a.self);
return *this;
}
size_t size() const {
return self->array_.size();
}
bool empty() const {
return self->array_.empty();
}
size_t size(size_t res, T const& i) {
self()->array_.resize(res, i);
return size();
}
size_t size(size_t res) {
self()->array_.resize(res);
return size();
}
void clear() {
self()->array_.clear();
}
T const& entry(size_t i) const {
return self->array_[i];
}
T const& entry(size_t i, T const& e) {
self()->array_[i] = e;
return entry(i);
}
T const& putBack(T const& e) {
self()->array_.push_back(e);
return entry(size() - 1);
}
bool popBack() {
if (empty()) return false;
self()->array_.pop_back();
return true;
}
ObjArray& operator=(ObjArray const& a) {
return copyFrom(a);
}
T const& operator[](size_t i) const {
return self->array_[i];
}
T& operator[](size_t i) {
return self()->array_[i];
}
bool write(FILE* f, bool bin, unsigned int fg) const {
size_t sz = size();
if (bin) {
if (fwrite(&sz, sizeof(size_t), 1, f) < 1) return false;
}
else {
if (fprintf(f, "%lu\n", sz) < 1) return false;
}
for (size_t i = 0; i < sz; i++) {
if (self->array_[i].write(f, bin, fg) == false) return false;
}
return true;
}
bool read(FILE* f, bool bin, unsigned int fg) {
size_t sz;
if (bin) {
if (fread(&sz, sizeof(size_t), 1, f) < 1) return false;
}
else {
if (fscanf(f, "%lu\n", &sz) < 0) return false;
}
size(sz);
for (size_t i = 0; i < sz; i++) {
if (self()->array_[i].read(f, bin, fg) == false) return false;
}
return true;
}
ObjBase* create() const {
return new ObjArray();
}
ObjBase* copyFrom(ObjBase const* b) {
return &(copyFrom(*b));
}
char const* ctype() const {
return typeid(*this).name();
}
std::string type() const {
return std::string(ctype());
}
};
}
#endif // oo_ObjArray_H__