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