cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vctFastCopy.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5 
6  Author(s): Anton Deguet
7  Created on: 2006-11-10
8 
9  (C) Copyright 2006-2007 Johns Hopkins University (JHU), All Rights
10  Reserved.
11 
12 --- begin cisst license - do not edit ---
13 
14 This software is provided "as is" under an open source license, with
15 no warranty. The complete license can be found in license.txt and
16 http://www.cisst.org/cisst/license.txt.
17 
18 --- end cisst license ---
19 */
20 
21 #pragma once
22 #ifndef _vctFastCopy_h
23 #define _vctFastCopy_h
24 
26 #include <cisstCommon/cmnThrow.h>
28 
29 #include <string.h> // for memcpy
30 
40 class vctFastCopy {
41 
42 protected:
46  template <class _vector1Type, class _vector2Type>
47  inline static bool VectorSizeCompatible(const _vector1Type & vector1,
48  const _vector2Type & vector2)
49  {
50  return (vector1.size() == vector2.size());
51  }
52 
53  template <class _container1Type, class _container2Type>
54  inline static bool ContainerSizesCompatible(const _container1Type & container1,
55  const _container2Type & container2)
56  {
57  return (container1.sizes() == container2.sizes());
58  }
59 
60  template <class _vector1Type, class _vector2Type>
61  inline static bool VectorStrideCompatible(const _vector1Type & vector1,
62  const _vector2Type & vector2)
63  {
64  return ((vector1.stride() == 1) && (vector2.stride() == 1));
65  }
66 
67 
68  template <class _matrix1Type, class _matrix2Type>
69  inline static bool MatrixStridesCompatible(const _matrix1Type & matrix1,
70  const _matrix2Type & matrix2)
71  {
72  return (
73  /* compact and same storage order */
74  (matrix1.IsCompact() && matrix2.IsCompact()
75  && (matrix1.strides() == matrix2.strides()))
76  ||
77  /* or row compact */
78  ((matrix1.row_stride() == 1) && matrix2.row_stride() == 1)
79  ||
80  /* or column compact */
81  ((matrix1.col_stride() == 1) && matrix2.col_stride() == 1));
82  }
83 
84  template <class _nArray1Type, class _nArray2Type>
85  inline static bool NArrayStridesCompatible(const _nArray1Type & nArray1,
86  const _nArray2Type & nArray2)
87  {
88  return (nArray1.IsCompact() && nArray2.IsCompact()
89  && (nArray1.strides() == nArray2.strides()));
90  }
92 
93 
97  template <class _vector1Type, class _vector2Type>
98  inline static void ThrowUnlessValidVectorSizes(const _vector1Type & vector1,
99  const _vector2Type & vector2)
100  throw(std::runtime_error)
101  {
102  if (!VectorSizeCompatible(vector1, vector2)) {
103  cmnThrow(std::runtime_error("vctFastCopy: Vector sizes mismatch"));
104  }
105  }
106 
107  template <class _container1Type, class _container2Type>
108  inline static void ThrowUnlessValidContainerSizes(const _container1Type & container1,
109  const _container2Type & container2)
110  throw(std::runtime_error)
111  {
112  if (!ContainerSizesCompatible(container1, container2)) {
113  cmnThrow(std::runtime_error("vctFastCopy: Container sizes mismatch"));
114  }
115  }
117 
118 public:
119 
122  static const bool SkipChecks = false;
123  static const bool PerformChecks = true;
125 
128  template <class _vector1Type, class _vector2Type>
129  inline static bool VectorCopyCompatible(const _vector1Type & vector1,
130  const _vector2Type & vector2)
131  {
132  return (!cmnRequiresDeepCopy<typename _vector1Type::value_type>()
133  && !cmnRequiresDeepCopy<typename _vector2Type::value_type>()
134  && VectorSizeCompatible(vector1, vector2)
135  && VectorStrideCompatible(vector1, vector2));
136  }
137 
138  template <class _matrix1Type, class _matrix2Type>
139  inline static bool MatrixCopyCompatible(const _matrix1Type & matrix1,
140  const _matrix2Type & matrix2)
141  {
142  return (!cmnRequiresDeepCopy<typename _matrix1Type::value_type>()
143  && !cmnRequiresDeepCopy<typename _matrix2Type::value_type>()
144  && ContainerSizesCompatible(matrix1, matrix2)
145  && MatrixStridesCompatible(matrix1, matrix2));
146  }
147 
148  template <class _nArray1Type, class _nArray2Type>
149  inline static bool NArrayCopyCompatible(const _nArray1Type & nArray1,
150  const _nArray2Type & nArray2)
151  {
152  return (!cmnRequiresDeepCopy<typename _nArray1Type::value_type>()
153  && !cmnRequiresDeepCopy<typename _nArray2Type::value_type>()
154  && ContainerSizesCompatible(nArray1, nArray2)
155  && NArrayStridesCompatible(nArray1, nArray2));
156  }
158 
159 
164  template <class _destinationVectorType, class _sourceVectorType>
165  inline static bool VectorCopy(_destinationVectorType & destination,
166  const _sourceVectorType & source,
167  bool performSafetyChecks)
168  {
169  typedef _sourceVectorType SourceVectorType;
170  typedef typename SourceVectorType::value_type value_type;
171 
172  if (performSafetyChecks) {
173  // test size
174  ThrowUnlessValidVectorSizes(source, destination);
175 
176  // test layout
177  if (! VectorStrideCompatible(destination, source)) {
178  return false;
179  }
180  }
181  memcpy(destination.Pointer(), source.Pointer(), source.size() * sizeof(value_type));
182  return true;
183  }
184 
185 
211  template <class _destinationMatrixType, class _sourceMatrixType>
212  inline static bool MatrixCopy(_destinationMatrixType & destination,
213  const _sourceMatrixType & source,
214  bool performSafetyChecks)
215  {
216  typedef _sourceMatrixType SourceMatrixType;
217  typedef typename SourceMatrixType::value_type value_type;
218 
219  if (performSafetyChecks) {
220  // test size
221  ThrowUnlessValidContainerSizes(source, destination);
222 
223  // test layout
224  if (! MatrixStridesCompatible(destination, source)) {
225  return false;
226  }
227  }
228  // at that point we know the matrices are compatible. We need to know if we memcpy all or by rows or column
229  if (destination.IsCompact() && source.IsCompact()) {
230  memcpy(destination.Pointer(), source.Pointer(), source.size() * sizeof(value_type));
231  return true;
232  } else {
233  typedef _destinationMatrixType DestinationMatrixType;
234  typedef _sourceMatrixType SourceMatrixType;
235 
238 
239  typedef typename DestinationMatrixType::pointer DestinationPointerType;
240  typedef typename SourceMatrixType::const_pointer SourcePointerType;
241 
242  const size_type rows = destination.rows();
243  const size_type cols = destination.cols();
244 
245  DestinationPointerType destinationPointer = destination.Pointer();
246  SourcePointerType sourcePointer = source.Pointer();
247 
248  const stride_type destinationRowStride = destination.row_stride();
249  const stride_type sourceRowStride = source.row_stride();
250  const stride_type destinationColStride = destination.col_stride();
251  const stride_type sourceColStride = source.col_stride();
252 
253 
254  if ((destinationColStride == 1) && (sourceColStride == 1)) {
255  /* copy row by row */
256  const size_type sizeOfRow = cols * sizeof(value_type);
257 
258  const DestinationPointerType destinationRowEnd = destinationPointer + rows * destinationRowStride;
259 
260  for (;
261  destinationPointer != destinationRowEnd;
262  destinationPointer += destinationRowStride, sourcePointer += sourceRowStride) {
263  memcpy(destinationPointer, sourcePointer, sizeOfRow);
264  }
265  return true;
266  } else {
267  /* copy column by column */
268  const size_type sizeOfCol = rows * sizeof(value_type);
269  const DestinationPointerType destinationColEnd = destinationPointer + cols * destinationColStride;
270 
271  for (;
272  destinationPointer != destinationColEnd;
273  destinationPointer += destinationColStride, sourcePointer += sourceColStride) {
274  memcpy(destinationPointer, sourcePointer, sizeOfCol);
275  }
276  return true;
277  }
278  }
279  }
280 
281 
287  template <class _destinationNArrayType, class _sourceNArrayType>
288  inline static bool NArrayCopy(_destinationNArrayType & destination,
289  const _sourceNArrayType & source,
290  bool performSafetyChecks)
291  {
292  typedef _sourceNArrayType SourceNArrayType;
293  typedef typename SourceNArrayType::value_type value_type;
294 
295  if (performSafetyChecks) {
296  // test size
297  ThrowUnlessValidContainerSizes(source, destination);
298 
299  // test layout
300  if (! NArrayStridesCompatible(destination, source)) {
301  return false;
302  }
303  }
304  memcpy(destination.Pointer(), source.Pointer(), source.size() * sizeof(value_type));
305  return true;
306  }
307 };
308 
309 
310 #endif // _vctFastCopy_h
311 
static bool ContainerSizesCompatible(const _container1Type &container1, const _container2Type &container2)
Definition: vctFastCopy.h:54
static void ThrowUnlessValidVectorSizes(const _vector1Type &vector1, const _vector2Type &vector2)
Definition: vctFastCopy.h:98
Portability across compilers and operating systems tools.
static bool NArrayCopyCompatible(const _nArray1Type &nArray1, const _nArray2Type &nArray2)
Definition: vctFastCopy.h:149
static bool VectorCopy(_destinationVectorType &destination, const _sourceVectorType &source, bool performSafetyChecks)
Definition: vctFastCopy.h:165
size_t size_type
Definition: vctContainerTraits.h:35
static const bool PerformChecks
Definition: vctFastCopy.h:123
static bool VectorStrideCompatible(const _vector1Type &vector1, const _vector2Type &vector2)
Definition: vctFastCopy.h:61
static bool MatrixCopy(_destinationMatrixType &destination, const _sourceMatrixType &source, bool performSafetyChecks)
Definition: vctFastCopy.h:212
static bool MatrixCopyCompatible(const _matrix1Type &matrix1, const _matrix2Type &matrix2)
Definition: vctFastCopy.h:139
static const bool SkipChecks
Definition: vctFastCopy.h:122
static bool MatrixStridesCompatible(const _matrix1Type &matrix1, const _matrix2Type &matrix2)
Definition: vctFastCopy.h:69
Container class for fast copy related methods.
Definition: vctFastCopy.h:40
#define cmnThrow(a)
Definition: MinimalCmn.h:4
static void ThrowUnlessValidContainerSizes(const _container1Type &container1, const _container2Type &container2)
Definition: vctFastCopy.h:108
static bool NArrayStridesCompatible(const _nArray1Type &nArray1, const _nArray2Type &nArray2)
Definition: vctFastCopy.h:85
ptrdiff_t stride_type
Definition: vctContainerTraits.h:37
static bool VectorSizeCompatible(const _vector1Type &vector1, const _vector2Type &vector2)
Definition: vctFastCopy.h:47
static bool VectorCopyCompatible(const _vector1Type &vector1, const _vector2Type &vector2)
Definition: vctFastCopy.h:129
Declaration of the template function cmnThrow.
static bool NArrayCopy(_destinationNArrayType &destination, const _sourceNArrayType &source, bool performSafetyChecks)
Definition: vctFastCopy.h:288
Declaration of cmnRequiresDeepCopy.