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