Home | History | Annotate | Download | only in marisa
      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