/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */ /* $Id: vctFastCopy.h,v 1.4 2007/04/26 19:33:58 anton Exp $ Author(s): Anton Deguet Created on: 2006-11-10 (C) Copyright 2006-2007 Johns Hopkins University (JHU), All Rights Reserved. --- begin cisst license - do not edit --- This software is provided "as is" under an open source license, with no warranty. The complete license can be found in license.txt and http://www.cisst.org/cisst/license.txt. --- end cisst license --- */ #ifndef _vctFastCopy_h #define _vctFastCopy_h #include #include /*! \brief Container class for fast copy methods */ class vctFastCopy { public: /*! Helper function to throw an exception whenever sizes mismatch. This enforces that a standard message is sent. */ //@{ template inline static void ThrowUnlessValidMatrixSizes(const _matrixType1 & matrix1, const _matrixType2 & matrix2) throw(std::runtime_error) { if ((matrix1.rows() != matrix2.rows()) || (matrix1.cols() != matrix2.cols())) { cmnThrow(std::runtime_error("vctFastCopy: Matrix sizes mismatch")); } } template inline static void ThrowUnlessValidVectorSizes(const _vectorType1 & vector1, const _vectorType2 & vector2) throw(std::runtime_error) { if (vector1.size() != vector2.size()) { cmnThrow(std::runtime_error("vctFastCopy: Vector sizes mismatch")); } } //@} /*! Function to use memcpy whenever possible. This is not really and engine since it has no loop nor plugable operation, but it performs a similar size check as other engines. Ultimately, we could have a FastLinesCopyOf and FastColumnsCopyOf which would have and optimized loop to iterate thru the lines (or rows) to use memcpy on containers with compact lines (or rows). */ template inline static bool MatrixCopy(_destinationMatrixType & destination, const _sourceMatrixType & source, bool performSafetyChecks) { typedef _sourceMatrixType SourceMatrixType; typedef typename SourceMatrixType::size_type size_type; typedef typename SourceMatrixType::stride_type stride_type; typedef typename SourceMatrixType::value_type value_type; const size_type sourceRows = source.rows(); const size_type sourceCols = source.cols(); if (performSafetyChecks) { // test size ThrowUnlessValidMatrixSizes(source, destination); // test layout const stride_type destinationRowStride = destination.row_stride(); const stride_type destinationColStride = destination.col_stride(); const stride_type sourceRowStride = source.row_stride(); const stride_type sourceColStride = source.col_stride(); if (! ((destinationRowStride == sourceRowStride) && (destinationColStride == sourceColStride) && (((destinationColStride == 1) && (destinationRowStride == static_cast(sourceCols))) || ((destinationRowStride == 1) && (destinationColStride == static_cast(sourceRows)))) ) ) { return false; } } memcpy(destination.Pointer(), source.Pointer(), sourceRows * sourceCols * sizeof(value_type)); return true; } /*! Function to use memcpy whenever possible. This is not really and engine since it has no loop nor plugable operation, but it performs a similar size check as other engines. */ template inline static bool VectorCopy(_destinationVectorType & destination, const _sourceVectorType & source, bool performSafetyChecks) { typedef _sourceVectorType SourceVectorType; typedef typename SourceVectorType::size_type size_type; typedef typename SourceVectorType::stride_type stride_type; typedef typename SourceVectorType::value_type value_type; const size_type sourceSize = source.size(); if (performSafetyChecks) { // test size ThrowUnlessValidVectorSizes(source, destination); // test layout const stride_type destinationStride = destination.stride(); const stride_type sourceStride = source.stride(); if ((destinationStride != 1) || (sourceStride != 1)) { return false; } } memcpy(destination.Pointer(), source.Pointer(), sourceSize * sizeof(value_type)); return true; } }; #endif // _vctFastCopy_h // **************************************************************************** // Change History // **************************************************************************** // // $Log: vctFastCopy.h,v $ // Revision 1.4 2007/04/26 19:33:58 anton // All files in libraries: Applied new license text, separate copyright and // updated dates, added standard header where missing. // // Revision 1.3 2007/01/23 22:22:08 anton // vctFastCopy: Use source size to determine amount of data to copy so that if // safety checks are disabled and source is smaller than destination the copy // works (bug detected using Guard Malloc) // // Revision 1.2 2006/11/20 20:33:20 anton // Licensing: Applied new license to cisstCommon, cisstVector, cisstNumerical, // cisstInteractive, cisstImage and cisstOSAbstraction. // // Revision 1.1 2006/11/15 01:41:01 anton // cisstVector: Consistant implementation of FastCopyOf() for all containers. // See ticket #239. // // // ****************************************************************************