1#ifndef MARISA_ALPHA_VECTOR_INLINE_H_
2#define MARISA_ALPHA_VECTOR_INLINE_H_
3
4namespace marisa_alpha {
5
6template <typename T>
7Vector<T>::Vector()
8    : buf_(NULL), objs_(NULL), size_(0), capacity_(0), fixed_(false) {}
9
10template <typename T>
11Vector<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
20template <typename T>
21void Vector<T>::mmap(Mapper *mapper, const char *filename,
22    long offset, int whence) {
23  MARISA_ALPHA_THROW_IF(mapper == NULL, MARISA_ALPHA_PARAM_ERROR);
24  Mapper temp_mapper;
25  temp_mapper.open(filename, offset, whence);
26  map(temp_mapper);
27  temp_mapper.swap(mapper);
28}
29
30template <typename T>
31void Vector<T>::map(const void *ptr, std::size_t size) {
32  Mapper mapper(ptr, size);
33  map(mapper);
34}
35
36template <typename T>
37void 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
47template <typename T>
48void 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
55template <typename T>
56void Vector<T>::fread(std::FILE *file) {
57  Reader reader(file);
58  read(reader);
59}
60
61template <typename T>
62void Vector<T>::read(int fd) {
63  Reader reader(fd);
64  read(reader);
65}
66
67template <typename T>
68void Vector<T>::read(std::istream &stream) {
69  Reader reader(&stream);
70  read(reader);
71}
72
73template <typename T>
74void 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
83template <typename T>
84void 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
91template <typename T>
92void Vector<T>::fwrite(std::FILE *file) const {
93  Writer writer(file);
94  write(writer);
95}
96
97template <typename T>
98void Vector<T>::write(int fd) const {
99  Writer writer(fd);
100  write(writer);
101}
102
103template <typename T>
104void Vector<T>::write(std::ostream &stream) const {
105  Writer writer(&stream);
106  write(writer);
107}
108
109template <typename T>
110void Vector<T>::write(Writer &writer) const {
111  writer.write(size_);
112  writer.write(objs_, size_);
113}
114
115template <typename T>
116void Vector<T>::push_back(const T &x) {
117  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
118  MARISA_ALPHA_THROW_IF(size_ == max_size(), MARISA_ALPHA_SIZE_ERROR);
119  reserve(size_ + 1);
120  new (&buf_[size_++]) T(x);
121}
122
123template <typename T>
124void Vector<T>::pop_back() {
125  MARISA_ALPHA_THROW_IF(fixed_ || (size_ == 0), MARISA_ALPHA_STATE_ERROR);
126  buf_[--size_].~T();
127}
128
129template <typename T>
130void Vector<T>::resize(std::size_t size) {
131  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_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
142template <typename T>
143void Vector<T>::resize(std::size_t size, const T &x) {
144  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_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
155template <typename T>
156void Vector<T>::reserve(std::size_t capacity) {
157  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
158  MARISA_ALPHA_THROW_IF(capacity > max_size(), MARISA_ALPHA_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
173template <typename T>
174void Vector<T>::shrink() {
175  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
176  if (size_ != capacity_) {
177    realloc(size_);
178  }
179}
180
181template <typename T>
182void Vector<T>::fix() {
183  MARISA_ALPHA_THROW_IF(fixed_, MARISA_ALPHA_STATE_ERROR);
184  fixed_ = true;
185}
186
187template <typename T>
188void Vector<T>::swap(Vector *rhs) {
189  MARISA_ALPHA_THROW_IF(rhs == NULL, MARISA_ALPHA_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
197template <typename T>
198void Vector<T>::realloc(std::size_t new_capacity) {
199  MARISA_ALPHA_THROW_IF(new_capacity > (MARISA_ALPHA_SIZE_MAX / sizeof(T)),
200      MARISA_ALPHA_SIZE_ERROR);
201  T * const new_buf = reinterpret_cast<T *>(
202      new (std::nothrow) char[sizeof(T) * new_capacity]);
203  MARISA_ALPHA_THROW_IF(new_buf == NULL, MARISA_ALPHA_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_alpha
215
216#endif  // MARISA_ALPHA_VECTOR_INLINE_H_
217