core/vector.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef mia_core_vector_hh
22 #define mia_core_vector_hh
23 
24 #include <mia/core/defines.hh>
25 #include <mia/core/errormacro.hh>
26 #include <memory>
27 #include <cstring>
28 #include <cassert>
29 
31 
32 
40 template <typename T>
41 struct array_destructor {
43  virtual void operator () (T *p) {
44  delete[] p;
45  }
46 };
47 
54 template <typename T>
55 struct array_void_destructor {
57  virtual void operator () (T *) {
58  }
59 };
61 
73 template <typename T>
74 class Vector {
75 public:
76 
78  typedef T& reference;
79  typedef const T& const_reference;
80  typedef T *iterator;
81  typedef const T *const_iterator;
82  typedef size_t size_type;
83  typedef T value_type;
85 
92  Vector(size_t n, bool clean = true):
93  m_size(n),
94  m_data(new T[n], array_destructor<T>()),
95  m_cdata(m_data.get())
96  {
97  if (clean)
98  memset(m_data.get(), 0, m_size*sizeof(T));
99  }
100 
105  Vector(const Vector<T>& other):
106  m_size(other.m_size),
107  m_data(other.m_data),
108  m_cdata(other.m_cdata)
109  {
110  }
111 
114  {
115  m_size = other.m_size;
116  m_data = other.m_data;
117  m_cdata = other.m_cdata;
118  return *this;
119  }
120 
127  Vector(size_t n, T *init):
128  m_size(n),
129  m_data(init, array_void_destructor<T>()),
130  m_cdata(init)
131  {
132  }
133 
140  Vector(size_t n, const T *init):
141  m_size(n),
142  m_cdata(init)
143  {
144  }
145 
146 
150  reference operator[] (size_t i) {
151  assert(i < m_size);
152  DEBUG_ASSERT_RELEASE_THROW(m_data && m_data.unique(),
153  "Vector::operator[]: No writeable data availabe or not unique,"
154  " call Vector::make_unique() first or enforce the use of "
155  "'Vector::operator[](...) const'");
156  return m_data.get()[i];
157  }
158 
162  const_reference operator[] (size_t i) const {
163  assert(i < m_size);
164  return m_cdata[i];
165  }
166 
170  iterator begin() {
171  DEBUG_ASSERT_RELEASE_THROW(m_data && m_data.unique(),
172  "Vector::begin(): No writeable data availabe or not unique, "
173  "call Vector::make_unique() first or enforce the use of "
174  "'Vector::begin() const'");
175  return m_data.get();
176  }
177 
181  iterator end() {
182  DEBUG_ASSERT_RELEASE_THROW(m_data && m_data.unique(),
183  "Vector::begin(): No writeable data availabe or not unique, "
184  "call Vector::make_unique() first or enforce the use of "
185  "'Vector::end() const'");
186  return m_data.get() + m_size;
187  }
188 
189 
193  const_iterator begin() const{
194  return m_cdata;
195  }
196 
200  const_iterator end() const{
201  return m_cdata + m_size;
202  }
203 
207  size_type size() const
208  {
209  return m_size;
210  }
211 
217  void make_unique()
218  {
219  // if we have writable dataand is it already unique
220  // then do nothing
221  if (m_data && m_data.unique())
222  return;
223 
224  // create the new array and copy from the constant origial
225  // in case we didn't have writable data
226  m_data.reset(new T[m_size], array_destructor<T>());
227  std::copy(m_cdata, m_cdata + m_size, m_data.get());
228  m_cdata = m_data.get();
229  }
230 
231 private:
232  size_t m_size;
233  std::shared_ptr<T> m_data;
234  const T *m_cdata;
235 };
236 
237 
244 
246 
247 
248 #endif