Documentation for OpenFLUID 2.2.0
Matrix.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 /**
34  @file Matrix.hpp
35 
36  @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
37  */
38 
39 
40 #ifndef __OPENFLUID_CORE_MATRIX_HPP__
41 #define __OPENFLUID_CORE_MATRIX_HPP__
42 
43 
44 #include <memory>
45 
46 #include <openfluid/dllexport.hpp>
48 
49 
50 namespace openfluid { namespace core {
51 
52 
53 /**
54  Template class for matrix data
55 */
56 template <class T>
58 {
59  protected :
60 
61  std::unique_ptr<T[]> m_Data;
62 
63  unsigned long m_ColsNbr;
64 
65  unsigned long m_RowsNbr;
66 
67  bool allocate(unsigned long ColsNbr, unsigned long RowsNbr);
68 
69  void init();
70 
71 
72  public :
73 
74  /**
75  Default constructor, creates an empty Matrix
76  */
77  Matrix();
78 
79  /**
80  Copy constructor
81  */
82  Matrix(const Matrix& Other);
83 
84  /**
85  Constructor, creates a Matrix containing Size elements
86  */
87  Matrix(unsigned long ColsNbr,unsigned long RowsNbr);
88 
89  /**
90  Constructor, creates a Matrix containing Size elements, initialized with value InitValue
91  */
92  Matrix(unsigned long ColsNbr,unsigned long RowsNbr,const T& InitValue);
93 
94  /**
95  Assignment operator
96  */
97  Matrix<T>& operator=(const Matrix& Other);
98 
99  /**
100  Move assignment operator
101  */
103 
104  /**
105  Destructor
106  */
107  virtual ~Matrix() = default;
108 
109  /**
110  Returns the number of columns of the Matrix
111  @return number of columns
112  */
113  inline unsigned long getColsNbr() const
114  {
115  return m_ColsNbr;
116  }
117 
118  /**
119  Returns the number of rows of the Matrix
120  @return number of rows
121  */
122  inline unsigned long getRowsNbr() const
123  {
124  return m_RowsNbr;
125  }
126 
127  /**
128  Returns the full size of the Matrix (number of columns x number of rows)
129  @return size of the Matrix
130  */
131  inline unsigned long getSize() const
132  {
133  return (m_ColsNbr * m_RowsNbr);
134  }
135 
136  /**
137  Returns the full size of the Matrix
138  */
139  inline unsigned long size() const
140  {
141  return (m_ColsNbr * m_RowsNbr);
142  }
143 
144 
145  /**
146  Returns a pointer to the content of the Matrix (like C arrays)
147  */
148  T* data() const
149  {
150  return static_cast<T*>(m_Data.get());
151  }
152 
153  /**
154  Sets data from a pointer to a content (like C arrays)
155  */
156  void setData(T* Data, unsigned long ColsNbr, unsigned long RowsNbr);
157 
158  /**
159  Returns the element of the Matrix for index Index
160  */
161  T getElement(unsigned long ColIndex, unsigned long RowIndex) const;
162 
163  /**
164  Returns the element of the Matrix for index Index
165  */
166  inline T at(unsigned long ColIndex, unsigned long RowIndex) const
167  {
168  return getElement(ColIndex,RowIndex);
169  }
170 
171  /**
172  Returns the element of the Matrix for index Index
173  */
174  inline T get(unsigned long ColIndex, unsigned long RowIndex) const
175  { return getElement(ColIndex,RowIndex); };
176 
177 
178  /**
179  Sets a new value for element at the given index
180  */
181  void setElement(unsigned long ColIndex, unsigned long RowIndex, const T& Val);
182 
183  /**
184  Sets a new value for element at the given index
185  */
186  inline void set(unsigned long ColIndex, unsigned long RowIndex, const T& Val)
187  {
188  setElement(ColIndex,RowIndex,Val);
189  }
190 
191  /**
192  Fills the Matrix with given value
193  */
194  void fill(const T& Val);
195 
196  /**
197  Clears the Matrix (empty and size is 0)
198  */
199  void clear();
200 
201 };
202 
203 
204 // =====================================================================
205 // =====================================================================
206 
207 
208 template <class T>
210  m_ColsNbr(0),m_RowsNbr(0)
211 {
212  init();
213 }
214 
215 
216 // =====================================================================
217 // =====================================================================
218 
219 
220 template <class T>
222 {
223  init();
224 
225  if (!allocate(Other.m_ColsNbr,Other.m_RowsNbr))
226  {
227  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
228  }
229 
230  std::copy(Other.m_Data.get(), Other.m_Data.get() + (Other.m_ColsNbr*Other.m_RowsNbr), m_Data.get());
231 }
232 
233 
234 // =====================================================================
235 // =====================================================================
236 
237 
238 template <class T>
239 Matrix<T>::Matrix(unsigned long ColsNbr, unsigned long RowsNbr)
240 {
241  init();
242 
243  if (!allocate(ColsNbr,RowsNbr))
244  {
245  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
246  }
247 }
248 
249 
250 // =====================================================================
251 // =====================================================================
252 
253 
254 template <class T>
255 Matrix<T>::Matrix(unsigned long ColsNbr, unsigned long RowsNbr, const T& InitValue)
256 {
257  init();
258 
259  if (!allocate(ColsNbr,RowsNbr))
260  {
261  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
262  }
263 
264  fill(InitValue);
265 }
266 
267 
268 // =====================================================================
269 // =====================================================================
270 
271 
272 template <class T>
274 {
275 
276  if (this != &Other)
277  {
278  clear();
279 
280  if (!allocate(Other.m_ColsNbr,Other.m_RowsNbr))
281  {
282  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
283  }
284 
285  std::copy(Other.m_Data.get(), Other.m_Data.get() + (Other.m_ColsNbr*Other.m_RowsNbr), m_Data.get());
286  }
287 
288  return *this;
289 }
290 
291 
292 // =====================================================================
293 // =====================================================================
294 
295 
296 template <class T>
298 {
299 
300  if (this != &Other)
301  {
302  clear();
303 
304  m_ColsNbr = Other.m_ColsNbr;
305  m_RowsNbr = Other.m_RowsNbr;
306  m_Data = std::move(Other.m_Data);
307 
308  Other.m_ColsNbr = 0;
309  Other.m_RowsNbr = 0;
310  }
311 
312  return *this;
313 }
314 
315 
316 // =====================================================================
317 // =====================================================================
318 
319 
320 template <class T>
322 {
323  m_Data.reset();
324  m_ColsNbr = 0;
325  m_RowsNbr = 0;
326 }
327 
328 
329 // =====================================================================
330 // =====================================================================
331 
332 
333 template <class T>
334 bool Matrix<T>::allocate(unsigned long ColsNbr, unsigned long RowsNbr)
335 {
336  if (ColsNbr > 0 && RowsNbr > 0)
337  {
338  m_Data.reset();
339  m_Data = std::move(std::make_unique<T[]>(ColsNbr*RowsNbr));
340  if (m_Data)
341  {
342  m_RowsNbr = RowsNbr;
343  m_ColsNbr = ColsNbr;
344  }
345  else
346  {
347  return false;
348  }
349  }
350 
351  return true;
352 }
353 
354 
355 // =====================================================================
356 // =====================================================================
357 
358 
359 template <class T>
360 void Matrix<T>::setData(T* Data, unsigned long ColsNbr, unsigned long RowsNbr)
361 {
362  clear();
363 
364  if (!allocate(ColsNbr,RowsNbr))
365  {
366  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
367  }
368 
369  std::copy(Data, Data + (ColsNbr*RowsNbr), m_Data.get());
370 }
371 
372 
373 // =====================================================================
374 // =====================================================================
375 
376 
377 template <class T>
378 T Matrix<T>::getElement(unsigned long ColIndex, unsigned long RowIndex) const
379 {
380  if (ColIndex >= m_ColsNbr || RowIndex >= m_RowsNbr)
381  {
382  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"element access range error");
383  }
384 
385  return m_Data[ColIndex*m_RowsNbr+RowIndex];
386 }
387 
388 
389 // =====================================================================
390 // =====================================================================
391 
392 
393 template <class T>
394 void Matrix<T>::setElement(unsigned long ColIndex, unsigned long RowIndex, const T& Val)
395 {
396  if (ColIndex >= m_ColsNbr || RowIndex >= m_RowsNbr)
397  {
398  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"element access range error");
399  }
400 
401  m_Data[ColIndex*m_RowsNbr+RowIndex] = Val;
402 }
403 
404 
405 // =====================================================================
406 // =====================================================================
407 
408 
409 template <class T>
410 void Matrix<T>::fill(const T& Val)
411 {
412  std::fill(m_Data.get(), m_Data.get() + (m_ColsNbr*m_RowsNbr),Val);
413 }
414 
415 
416 // =====================================================================
417 // =====================================================================
418 
419 
420 template <class T>
422 {
423  init();
424 }
425 
426 
427 } }
428 
429 #endif /* __OPENFLUID_CORE_MATRIX_HPP__ */
Definition: FrameworkException.hpp:51
Definition: Matrix.hpp:58
void fill(const T &Val)
Definition: Matrix.hpp:410
unsigned long m_ColsNbr
Definition: Matrix.hpp:63
bool allocate(unsigned long ColsNbr, unsigned long RowsNbr)
Definition: Matrix.hpp:334
T * data() const
Definition: Matrix.hpp:148
void setData(T *Data, unsigned long ColsNbr, unsigned long RowsNbr)
Definition: Matrix.hpp:360
unsigned long getColsNbr() const
Definition: Matrix.hpp:113
std::unique_ptr< T[]> m_Data
Definition: Matrix.hpp:61
unsigned long m_RowsNbr
Definition: Matrix.hpp:65
Matrix(unsigned long ColsNbr, unsigned long RowsNbr, const T &InitValue)
Definition: Matrix.hpp:255
void set(unsigned long ColIndex, unsigned long RowIndex, const T &Val)
Definition: Matrix.hpp:186
T getElement(unsigned long ColIndex, unsigned long RowIndex) const
Definition: Matrix.hpp:378
Matrix< T > & operator=(Matrix &&Other)
Definition: Matrix.hpp:297
void clear()
Definition: Matrix.hpp:421
unsigned long size() const
Definition: Matrix.hpp:139
T at(unsigned long ColIndex, unsigned long RowIndex) const
Definition: Matrix.hpp:166
void init()
Definition: Matrix.hpp:321
Matrix()
Definition: Matrix.hpp:209
unsigned long getSize() const
Definition: Matrix.hpp:131
virtual ~Matrix()=default
void setElement(unsigned long ColIndex, unsigned long RowIndex, const T &Val)
Definition: Matrix.hpp:394
Matrix(const Matrix &Other)
Definition: Matrix.hpp:221
Matrix(unsigned long ColsNbr, unsigned long RowsNbr)
Definition: Matrix.hpp:239
Matrix< T > & operator=(const Matrix &Other)
Definition: Matrix.hpp:273
unsigned long getRowsNbr() const
Definition: Matrix.hpp:122
T get(unsigned long ColIndex, unsigned long RowIndex) const
Definition: Matrix.hpp:174
#define OPENFLUID_API
Definition: dllexport.hpp:86
Definition: ApplicationException.hpp:47