OpenStructure
pod_vector.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // This file is part of the OpenStructure project <www.openstructure.org>
3 //
4 // Copyright (C) 2008-2011 by the OpenStructure authors
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 3.0 of the License, or (at your option)
9 // any later version.
10 // This library is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 //------------------------------------------------------------------------------
19 #ifndef OST_POD_VECTOR_HH
20 #define OST_POD_VECTOR_HH
21 
22 /*
23  Author: Marco Biasini
24  */
25 
26 #include <ost/module_config.hh>
27 
28 #include <cassert>
29 #include <memory>
30 #include <iterator>
31 #include <string>
32 #include <iostream>
33 namespace ost {
34 
37 template <typename T>
38 class TEMPLATE_DEF_EXPORT PodVector {
39 public:
40  PodVector(): begin_(NULL), end_(NULL), capacity_(NULL) {}
41  PodVector(const PodVector<T>& rhs)
42  {
43  this->do_reserve(rhs.capacity());
44  this->raw_set(rhs.data(), rhs.size());
45  }
47  {
48  if (begin_) {
49  free(begin_);
50  }
51  }
52  typedef T value_type;
53  typedef T& reference;
54  typedef const T& const_reference;
55  typedef T* iterator;
56  typedef std::reverse_iterator<iterator> reverse_iterator;
57  typedef const T* const_iterator;
58  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
59 
60  iterator begin() { return begin_; }
61  iterator end() { return end_; }
62  const_iterator begin() const { return begin_; }
63  const_iterator end() const { return end_; }
64 
67  const_reverse_iterator rbegin() const
68  {
69  return const_reverse_iterator(begin_);
70  }
71  const_reverse_iterator rend() const
72  {
73  return const_reverse_iterator(end_);
74  }
75 
76  size_t capacity() const { return capacity_-begin_; }
77  size_t size() const { return end_-begin_; }
78 
79  reference front()
80  {
81  return *begin_;
82  }
83  const_reference front() const
84  {
85  return *begin_;
86  }
87 
88  void push_back(const_reference val)
89  {
90  if (end_>=capacity_) {
91  this->do_reserve(this->capacity()*2);
92  }
93  memcpy(end_, &val, sizeof(value_type));
94  ++end_;
95  }
96 
97  void pop_back()
98  {
99  --end_;
100  }
101 
102  void clear()
103  {
104  this->do_reserve(0);
105  end_=begin_;
106  }
107 
108  void reserve(size_t n)
109  {
110  return do_reserve(n);
111  }
112 
113  reference operator[](size_t index)
114  {
115  return begin_[index];
116  }
117  const_reference operator[](size_t index) const
118  {
119  return begin_[index];
120  }
121  T* data() { return begin_; }
122 
123  const T* data() const { return begin_; }
124 
125  void raw_set(T* data, size_t n)
126  {
127  this->do_reserve(n);
128  memcpy(begin_, data, sizeof(T)*n);
129  end_=begin_+n;
130  }
131 private:
132  void do_reserve(size_t n);
133  value_type* begin_;
134  value_type* end_;
135  value_type* capacity_;
136 };
137 
138 template <typename T>
139 void PodVector<T>::do_reserve(size_t n)
140 {
141  size_t old_size=this->size();
142  n=(n==0 ? 1 : n);
143  if (n==this->capacity()) {
144  return;
145  }
146  begin_=reinterpret_cast<T*>(realloc(begin_, n*sizeof(T)));
147  end_=begin_+old_size;
148  capacity_=begin_+n;
149 }
150 
151 }
152 
153 #endif