C++程序  |  217行  |  4.98 KB

#ifndef MARISA_ALPHA_VECTOR_INLINE_H_
#define MARISA_ALPHA_VECTOR_INLINE_H_

namespace marisa_alpha {

template <typename T>
Vector<T>::Vector()
    : buf_(NULL), objs_(NULL), size_(0), capacity_(0), fixed_(false) {}

template <typename T>
Vector<T>::~Vector() {
  if (buf_ != NULL) {
    for (std::size_t i = 0; i < size_; ++i) {
      buf_[i].~T();
    }
    delete [] reinterpret_cast<char *>(buf_);
  }
}

template <typename T>
void Vector<T>::mmap(Mapper *mapper, const char *filename,
    long offset, int whence) {
  MARISA_ALPHA_THROW_IF(mapper == NULL, MARISA_ALPHA_PARAM_ERROR);
  Mapper temp_mapper;
  temp_mapper.open(filename, offset, whence);
  map(temp_mapper);
  temp_mapper.swap(mapper);
}

template <typename T>
void Vector<T>::map(const void *ptr, std::size_t size) {
  Mapper mapper(ptr, size);
  map(mapper);
}

template <typename T>
void Vector<T>::map(Mapper &mapper) {
  UInt32 size;
  mapper.map(&size);
  Vector temp;
  mapper.map(&temp.objs_, size);
  temp.size_ = size;
  temp.fix();
  temp.swap(this);
}

template <typename T>
void Vector<T>::load(const char *filename,
    long offset, int whence) {
  Reader reader;
  reader.open(filename, offset, whence);
  read(reader);
}

template <typename T>
void Vector<T>::fread(std::FILE *file) {
  Reader reader(file);
  read(reader);
}

template <typename T>
void Vector<T>::read(int fd) {
  Reader reader(fd);
  read(reader);
}

template <typename T>
void Vector<T>::read(std::istream &stream) {
  Reader reader(&stream);
  read(reader);
}

template <typename T>
void Vector<T>::read(Reader &reader) {
  UInt32 size;
  reader.read(&size);
  Vector temp;
  temp.resize(size);
  reader.read(temp.buf_, size);
  temp.swap(this);
}

template <typename T>
void Vector<T>::save(const char *filename, bool trunc_flag,
    long offset, int whence) const {
  Writer writer;
  writer.open(filename, trunc_flag, offset, whence);
  write(writer);
}

template <typename T>
void Vector<T>::fwrite(std::FILE *file) const {
  Writer writer(file);
  write(writer);
}

template <typename T>
void Vector<T>::write(int fd) const {
  Writer writer(fd);
  write(writer);
}

template <typename T>
void Vector<T>::write(std::ostream &stream) const {
  Writer writer(&stream);
  write(writer);
}

template <typename T>
void Vector<T>::write(Writer &writer) const {
  writer.write(size_);
  writer.write(objs_, size_);
}

template <typename T>
void Vector<T>::push_back(const T &x) {
  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
  MARISA_ALPHA_THROW_IF(size_ == max_size(), MARISA_ALPHA_SIZE_ERROR);
  reserve(size_ + 1);
  new (&buf_[size_++]) T(x);
}

template <typename T>
void Vector<T>::pop_back() {
  MARISA_ALPHA_THROW_IF(fixed_ || (size_ == 0), MARISA_ALPHA_STATE_ERROR);
  buf_[--size_].~T();
}

template <typename T>
void Vector<T>::resize(std::size_t size) {
  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
  reserve(size);
  for (std::size_t i = size_; i < size; ++i) {
    new (&buf_[i]) T;
  }
  for (std::size_t i = size; i < size_; ++i) {
    buf_[i].~T();
  }
  size_ = (UInt32)size;
}

template <typename T>
void Vector<T>::resize(std::size_t size, const T &x) {
  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
  reserve(size);
  for (std::size_t i = size_; i < size; ++i) {
    new (&buf_[i]) T(x);
  }
  for (std::size_t i = size; i < size_; ++i) {
    buf_[i].~T();
  }
  size_ = (UInt32)size;
}

template <typename T>
void Vector<T>::reserve(std::size_t capacity) {
  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
  MARISA_ALPHA_THROW_IF(capacity > max_size(), MARISA_ALPHA_SIZE_ERROR);
  if (capacity <= capacity_) {
    return;
  }
  std::size_t new_capacity = capacity;
  if (capacity_ > (capacity / 2)) {
    if (capacity_ > (max_size() / 2)) {
      new_capacity = max_size();
    } else {
      new_capacity = capacity_ * 2;
    }
  }
  realloc(new_capacity);
}

template <typename T>
void Vector<T>::shrink() {
  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
  if (size_ != capacity_) {
    realloc(size_);
  }
}

template <typename T>
void Vector<T>::fix() {
  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
  fixed_ = true;
}

template <typename T>
void Vector<T>::swap(Vector *rhs) {
  MARISA_ALPHA_THROW_IF(rhs == NULL, MARISA_ALPHA_PARAM_ERROR);
  Swap(&buf_, &rhs->buf_);
  Swap(&objs_, &rhs->objs_);
  Swap(&size_, &rhs->size_);
  Swap(&capacity_, &rhs->capacity_);
  Swap(&fixed_, &rhs->fixed_);
}

template <typename T>
void Vector<T>::realloc(std::size_t new_capacity) {
  MARISA_ALPHA_THROW_IF(new_capacity > (MARISA_ALPHA_SIZE_MAX / sizeof(T)),
      MARISA_ALPHA_SIZE_ERROR);
  T * const new_buf = reinterpret_cast<T *>(
      new (std::nothrow) char[sizeof(T) * new_capacity]);
  MARISA_ALPHA_THROW_IF(new_buf == NULL, MARISA_ALPHA_MEMORY_ERROR);
  for (std::size_t i = 0; i < size_; ++i) {
    new (&new_buf[i]) T(buf_[i]);
    buf_[i].~T();
  }
  delete [] reinterpret_cast<char *>(buf_);
  buf_ = new_buf;
  objs_ = new_buf;
  capacity_ = (UInt32)new_capacity;
}

}  // namespace marisa_alpha

#endif  // MARISA_ALPHA_VECTOR_INLINE_H_