216 lines
4.8 KiB
C++
216 lines
4.8 KiB
C++
#ifndef MARISA_VECTOR_INLINE_H_
|
|
#define MARISA_VECTOR_INLINE_H_
|
|
|
|
namespace marisa {
|
|
|
|
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_THROW_IF(mapper == NULL, MARISA_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_THROW_IF(fixed_, MARISA_STATE_ERROR);
|
|
MARISA_THROW_IF(size_ == max_size(), MARISA_SIZE_ERROR);
|
|
reserve(size_ + 1);
|
|
new (&buf_[size_++]) T(x);
|
|
}
|
|
|
|
template <typename T>
|
|
void Vector<T>::pop_back() {
|
|
MARISA_THROW_IF(fixed_ || (size_ == 0), MARISA_STATE_ERROR);
|
|
buf_[--size_].~T();
|
|
}
|
|
|
|
template <typename T>
|
|
void Vector<T>::resize(std::size_t size) {
|
|
MARISA_THROW_IF(fixed_, MARISA_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_THROW_IF(fixed_, MARISA_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_THROW_IF(fixed_, MARISA_STATE_ERROR);
|
|
MARISA_THROW_IF(capacity > max_size(), MARISA_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_THROW_IF(fixed_, MARISA_STATE_ERROR);
|
|
if (size_ != capacity_) {
|
|
realloc(size_);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
void Vector<T>::fix() {
|
|
MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR);
|
|
fixed_ = true;
|
|
}
|
|
|
|
template <typename T>
|
|
void Vector<T>::swap(Vector *rhs) {
|
|
MARISA_THROW_IF(rhs == NULL, MARISA_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_THROW_IF(new_capacity > (MARISA_SIZE_MAX / sizeof(T)),
|
|
MARISA_SIZE_ERROR);
|
|
T * const new_buf = reinterpret_cast<T *>(
|
|
new (std::nothrow) char[sizeof(T) * new_capacity]);
|
|
MARISA_THROW_IF(new_buf == NULL, MARISA_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
|
|
|
|
#endif // MARISA_VECTOR_INLINE_H_
|