aboutsummaryrefslogblamecommitdiffstats
path: root/meowpp/oo/ObjArray.h
blob: 44175248070752f9bc99c58c5439a8b8c3b6b01e (plain) (tree)





































































































































































                                                                     
#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__