1 #ifndef MARISA_VECTOR_INLINE_H_ 2 #define MARISA_VECTOR_INLINE_H_ 3 4 namespace marisa { 5 6 template <typename T> 7 Vector<T>::Vector() 8 : buf_(NULL), objs_(NULL), size_(0), capacity_(0), fixed_(false) {} 9 10 template <typename T> 11 Vector<T>::~Vector() { 12 if (buf_ != NULL) { 13 for (std::size_t i = 0; i < size_; ++i) { 14 buf_[i].~T(); 15 } 16 delete [] reinterpret_cast<char *>(buf_); 17 } 18 } 19 20 template <typename T> 21 void Vector<T>::mmap(Mapper *mapper, const char *filename, 22 long offset, int whence) { 23 MARISA_THROW_IF(mapper == NULL, MARISA_PARAM_ERROR); 24 Mapper temp_mapper; 25 temp_mapper.open(filename, offset, whence); 26 map(temp_mapper); 27 temp_mapper.swap(mapper); 28 } 29 30 template <typename T> 31 void Vector<T>::map(const void *ptr, std::size_t size) { 32 Mapper mapper(ptr, size); 33 map(mapper); 34 } 35 36 template <typename T> 37 void Vector<T>::map(Mapper &mapper) { 38 UInt32 size; 39 mapper.map(&size); 40 Vector temp; 41 mapper.map(&temp.objs_, size); 42 temp.size_ = size; 43 temp.fix(); 44 temp.swap(this); 45 } 46 47 template <typename T> 48 void Vector<T>::load(const char *filename, 49 long offset, int whence) { 50 Reader reader; 51 reader.open(filename, offset, whence); 52 read(reader); 53 } 54 55 template <typename T> 56 void Vector<T>::fread(std::FILE *file) { 57 Reader reader(file); 58 read(reader); 59 } 60 61 template <typename T> 62 void Vector<T>::read(int fd) { 63 Reader reader(fd); 64 read(reader); 65 } 66 67 template <typename T> 68 void Vector<T>::read(std::istream &stream) { 69 Reader reader(&stream); 70 read(reader); 71 } 72 73 template <typename T> 74 void Vector<T>::read(Reader &reader) { 75 UInt32 size; 76 reader.read(&size); 77 Vector temp; 78 temp.resize(size); 79 reader.read(temp.buf_, size); 80 temp.swap(this); 81 } 82 83 template <typename T> 84 void Vector<T>::save(const char *filename, bool trunc_flag, 85 long offset, int whence) const { 86 Writer writer; 87 writer.open(filename, trunc_flag, offset, whence); 88 write(writer); 89 } 90 91 template <typename T> 92 void Vector<T>::fwrite(std::FILE *file) const { 93 Writer writer(file); 94 write(writer); 95 } 96 97 template <typename T> 98 void Vector<T>::write(int fd) const { 99 Writer writer(fd); 100 write(writer); 101 } 102 103 template <typename T> 104 void Vector<T>::write(std::ostream &stream) const { 105 Writer writer(&stream); 106 write(writer); 107 } 108 109 template <typename T> 110 void Vector<T>::write(Writer &writer) const { 111 writer.write(size_); 112 writer.write(objs_, size_); 113 } 114 115 template <typename T> 116 void Vector<T>::push_back(const T &x) { 117 MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR); 118 MARISA_THROW_IF(size_ == max_size(), MARISA_SIZE_ERROR); 119 reserve(size_ + 1); 120 new (&buf_[size_++]) T(x); 121 } 122 123 template <typename T> 124 void Vector<T>::pop_back() { 125 MARISA_THROW_IF(fixed_ || (size_ == 0), MARISA_STATE_ERROR); 126 buf_[--size_].~T(); 127 } 128 129 template <typename T> 130 void Vector<T>::resize(std::size_t size) { 131 MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR); 132 reserve(size); 133 for (std::size_t i = size_; i < size; ++i) { 134 new (&buf_[i]) T; 135 } 136 for (std::size_t i = size; i < size_; ++i) { 137 buf_[i].~T(); 138 } 139 size_ = (UInt32)size; 140 } 141 142 template <typename T> 143 void Vector<T>::resize(std::size_t size, const T &x) { 144 MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR); 145 reserve(size); 146 for (std::size_t i = size_; i < size; ++i) { 147 new (&buf_[i]) T(x); 148 } 149 for (std::size_t i = size; i < size_; ++i) { 150 buf_[i].~T(); 151 } 152 size_ = (UInt32)size; 153 } 154 155 template <typename T> 156 void Vector<T>::reserve(std::size_t capacity) { 157 MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR); 158 MARISA_THROW_IF(capacity > max_size(), MARISA_SIZE_ERROR); 159 if (capacity <= capacity_) { 160 return; 161 } 162 std::size_t new_capacity = capacity; 163 if (capacity_ > (capacity / 2)) { 164 if (capacity_ > (max_size() / 2)) { 165 new_capacity = max_size(); 166 } else { 167 new_capacity = capacity_ * 2; 168 } 169 } 170 realloc(new_capacity); 171 } 172 173 template <typename T> 174 void Vector<T>::shrink() { 175 MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR); 176 if (size_ != capacity_) { 177 realloc(size_); 178 } 179 } 180 181 template <typename T> 182 void Vector<T>::fix() { 183 MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR); 184 fixed_ = true; 185 } 186 187 template <typename T> 188 void Vector<T>::swap(Vector *rhs) { 189 MARISA_THROW_IF(rhs == NULL, MARISA_PARAM_ERROR); 190 Swap(&buf_, &rhs->buf_); 191 Swap(&objs_, &rhs->objs_); 192 Swap(&size_, &rhs->size_); 193 Swap(&capacity_, &rhs->capacity_); 194 Swap(&fixed_, &rhs->fixed_); 195 } 196 197 template <typename T> 198 void Vector<T>::realloc(std::size_t new_capacity) { 199 MARISA_THROW_IF(new_capacity > (MARISA_SIZE_MAX / sizeof(T)), 200 MARISA_SIZE_ERROR); 201 T * const new_buf = reinterpret_cast<T *>( 202 new (std::nothrow) char[sizeof(T) * new_capacity]); 203 MARISA_THROW_IF(new_buf == NULL, MARISA_MEMORY_ERROR); 204 for (std::size_t i = 0; i < size_; ++i) { 205 new (&new_buf[i]) T(buf_[i]); 206 buf_[i].~T(); 207 } 208 delete [] reinterpret_cast<char *>(buf_); 209 buf_ = new_buf; 210 objs_ = new_buf; 211 capacity_ = (UInt32)new_capacity; 212 } 213 214 } // namespace marisa 215 216 #endif // MARISA_VECTOR_INLINE_H_ 217