Loading...
Searching...
No Matches
Copy.h
Go to the documentation of this file.
//# Copy.h: Copy objects from one C-style array to another.
//# Copyright (C) 1994-1997,1999-2002,2005,2015
//# Associated Universities, Inc. Washington DC, USA.
//# National Astronomical Observatory of Japan
//# 2-21-1, Osawa, Mitaka, Tokyo, 181-8588, Japan.
//#
//# This library is free software; you can redistribute it and/or modify it
//# under the terms of the GNU Library General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or (at your
//# option) any later version.
//#
//# This library is distributed in the hope that it will be useful, but WITHOUT
//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
//# License for more details.
//#
//# You should have received a copy of the GNU Library General Public License
//# along with this library; if not, write to the Free Software Foundation,
//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
//#
//# Correspondence concerning AIPS++ should be addressed as follows:
//# Internet email: casa-feedback@nrao.edu.
//# Postal address: AIPS++ Project Office
//# National Radio Astronomy Observatory
//# 520 Edgemont Road
//# Charlottesville, VA 22903-2475 USA
#ifndef CASA_COPY_H
#define CASA_COPY_H
//# Includes
#include <casacore/casa/aips.h>
#include <casacore/casa/BasicSL/Complex.h>
#include <algorithm>
namespace casacore { //# NAMESPACE CASACORE - BEGIN
// <summary>
// Copy objects from one C-style array to another.
// </summary>
// <use visibility=export>
// <reviewed reviewer="Friso Olnon" date="1995/03/14" tests="tCopy" demos="">
// </reviewed>
// <synopsis>
// Objset is used to fill a C-style array of objects.
//
// Objcopy and objmove are used to copy objects from one place to
// another. Optionally a stride can be supplied.
//
// The functions are equivalent to C's <src>memcpy</src> and
// <src>memmove</src>.
// When possible C++ standard library functions are used to implement them
//
// Similar to memcpy and memmove, the difference between objcopy
// and objmove is that objmove takes account of an overlap of source and
// destination. In general, objcopy is slighty (but only slighty) faster.
// </synopsis>
// <example>
// Setting and copying arrays of built-in types:
// <srcblock>
// // Create int array of 4 elements
// size_t size=4;
// int* ia = new int[size];
// // Initialize all elements to value 99
// objset(ia, 99, size);
// // Change all odd elements to 66 -> [99 66 99 66]
// objset(ia+1, 66, 5, 2);
//
// // Create another 4-element int array
// int* ia2 = new int[size];
// // Copy array ia into array ia2 -> [99 66 99 66]
// objmove(ia2, ia, size);
// // Copy the even elements of ia to the odd elements of ia2
// // -> [99 99 99 99]
// objcopy(ia2+1, ia, size/2, 2, 2);
// </srcblock>
//
// Setting and copying arrays of a randomly chosen type:
// <srcblock>
// // Create 4-element array of 3-element Block<int> objects
// size_t size=4;
// Block<int>* ta = new Block<int>[size];
// Block<int> set(3);
// // Initialize the array -> [[123][123][123][123]]
// set[0] = 1; set[1] = 2; set[2] = 3;
// objset(ta, set, size);
// // Change odd Blocks to [777]-> [[123][777][123][777]]
// set[0] = set[1] = set[2] = 7;
// objset(ta + 1, set, size/2, 2);
//
// // Create another Block<int> array
// Block<int>* ta2 = new Block<int>[size];
// // Copy the even elements of ta to the first elements of ta2
// // -> [[123][123]...]
// objcopy(ta2, ta, size/2, 1, 2);
// </srcblock>
// </example>
// <group name=throw>
// Throw the various AipsErrors when incorrect arguments used
void objthrowmv1(const void *to, const void *from, const size_t n);
void objthrowmv2(const void *to, const void *from, const size_t n,
const size_t toStride, const size_t fromStride);
void objthrowcp1(const void *to, const void *from, const size_t n);
void objthrowcp2(const void *to, const void *from, const size_t n,
const size_t toStride, const size_t fromStride);
void objthrowfl1(const void *to, const size_t n);
void objthrowfl2(const void *to, const size_t n,
const size_t toStride);
// </group>
// <summary> Test routines </summary>
// <group name=test>
// Test on how to handle the overlap in move
void objtestmv(size_t &nLeft, size_t &startLeft, size_t &startRight,
const void *to, const void *from, const size_t n,
const size_t toStride, const size_t fromStride,
const void *toPn, const void *fromPn,
const size_t fromMto, const size_t toMfrom);
// </group>
// <summary> Copy methods </summary>
// <group name=copy>
// The general function to copy <src>n</src> objects from one place
// to another if overlap between <src>to</src> and <src>from</src> fields
// is possible. Strides may be specified, i.e. you may copy from every
// <src>fromStride</src>-th position into every <src>toStride</src>-th
// one.
//
// The function will call <src>std::copy()</src> when possible.
// Objmove works correctly if the source and destination overlap in any way.
//
// An exception will be thrown if the source or the destination does not
// exist (and <em>n</em> is non-zero) or if the strides are non-positive.
// <thrown>
// <li> AipsError
// </thrown>
//
// <group>
template<class T> void objmove(T* to, const T* from, size_t n) {
objthrowmv1(to,from,n);
(to<from || to >= from+n) ? std::copy(from,from+n,to)
: std::copy_backward(from,from+n,to+n); }
template<class T> void objmove(T* to, const T* from, size_t n,
size_t toStride, size_t fromStride) {
if (!n) return;
objthrowmv2(to,from,n,toStride,fromStride);
if (toStride*fromStride == 1) { objmove(to, from, n);
return; }
size_t nLeft, startLeft, startRight;
size_t fromMto=0; size_t toMfrom=0;
if (toStride > fromStride && from > to)
fromMto = (from-to)/(toStride-fromStride);
else if (toStride < fromStride && from < to)
toMfrom = (to-from)/(fromStride-toStride);
objtestmv(nLeft, startLeft, startRight, to, from, n,
toStride, fromStride, to+n*toStride, from+n*fromStride,
fromMto, toMfrom);
n -= nLeft;
if (nLeft) {
const T* fromPtr = from + startLeft*fromStride;
T* toPtr = to + startLeft*toStride;
while (nLeft--) { *toPtr = *fromPtr;
fromPtr += fromStride;
toPtr += toStride; }; };
// Do the moves from the right.
if (n) {
const T* fromPtr = from + startRight*fromStride;
T* toPtr = to + startRight*toStride;
while (n--) { fromPtr -= fromStride; toPtr -= toStride;
*toPtr = *fromPtr; }; };
}
// </group>
// The non-general function to copy <src>n</src> objects from one place
// to another. Strides may be specified, i.e. you may copy from every
// <src>fromStride</src>-th position into every <src>toStride</src>-th
// one.
//
// Objcopy/objcopyctor does not take an overlap of source and destination into account.
// Objmove should be used if that is an issue.
//
// Objcopyctor copy objects from <src>from</src> by calling copy constructor
// on each element in <src>to</src>.
//
// An exception will be thrown if the source or the destination does not
// exist or if the strides are non-positive.
// <thrown>
// <li> AipsError
// </thrown>
//
// <group>
template<class T> void objcopy(T* to, const T* from, size_t n) {
objthrowcp1(to,from,n); std::copy(from, from+n, to); }
template<class T> void objcopy(T* to, const T* from, size_t n,
size_t toStride, size_t fromStride) {
objthrowcp2(to,from,n,toStride,fromStride); while (n--) {
*to = *from; to += toStride; from += fromStride; } }
template<class T> void objcopyctor(T* to, const T* from, size_t n) {
objthrowcp1(to, from, n);
size_t i;
try {
for (i = 0; i < n; ++i) {
::new (&to[i]) T(from[i]);
}
} catch (...) {
while (i > 0) { // roll back
to[--i].~T();
}
throw;
}
}
template<class T> void objcopyctor(T* to, const T* from, size_t n,
size_t toStride, size_t fromStride) {
objthrowcp2(to, from, n, toStride, fromStride);
size_t i = 0;
try {
for (i = 0; i < n; ++i) {
::new (to) T(*from);
to += toStride;
from += fromStride;
}
} catch (...) {
while (i > 0) { // roll back
--i;
to -= toStride;
to->~T();
}
throw;
}
}
// </group>
// Fill <src>n</src> elements of an array of objects with the given
// value, optionally with a stride. Note that the fillValue is passed
// by value.
//
// An exception will be thrown if the destination array does not exist
// or if the stride is non-positive.
//
// <thrown>
// <li> AipsError
// </thrown>
//
// <group>
template<class T> void objset(T* to, const T fillValue, size_t n) {
objthrowfl1(to,n); std::fill_n(to, n, fillValue); }
template<class T> void objset(T* to, const T fillValue, size_t n,
size_t toStride) {
objthrowfl2(to,n,toStride);
while (n--){*to = fillValue; to += toStride; }; }
// </group>
// </group>
} //# NAMESPACE CASACORE - END
#ifndef CASACORE_NO_AUTO_TEMPLATES
#include <casacore/casa/Utilities/Copy.tcc>
#endif //# CASACORE_NO_AUTO_TEMPLATES
#endif
casacore
this file contains all the compiler specific defines
Definition mainpage.dox:28
casacore::Copy_global_functions_copy
Copy methods .
Definition Copy.h:129
casacore::Copy_global_functions_copy::objcopyctor
void objcopyctor(T *to, const T *from, size_t n)
Definition Copy.h:203
casacore::Copy_global_functions_copy::objcopy
void objcopy(T *to, const T *from, size_t n)
The non-general function to copy n objects from one place to another.
Definition Copy.h:196
casacore::Copy_global_functions_copy::objset
void objset(T *to, const T fillValue, size_t n, size_t toStride)
Definition Copy.h:253
casacore::Copy_global_functions_copy::objcopyctor
void objcopyctor(T *to, const T *from, size_t n, size_t toStride, size_t fromStride)
Definition Copy.h:217
casacore::Copy_global_functions_copy::objmove
void objmove(T *to, const T *from, size_t n)
The general function to copy n objects from one place to another if overlap between to and from field...
Definition Copy.h:143
casacore::Copy_global_functions_copy::objset
void objset(T *to, const T fillValue, size_t n)
Fill n elements of an array of objects with the given value, optionally with a stride.
Definition Copy.h:250
casacore::Copy_global_functions_copy::objcopy
void objcopy(T *to, const T *from, size_t n, size_t toStride, size_t fromStride)
Definition Copy.h:198
casacore::Copy_global_functions_copy::objmove
void objmove(T *to, const T *from, size_t n, size_t toStride, size_t fromStride)
Definition Copy.h:147
casacore::Copy_global_functions_test
Test routines .
Definition Copy.h:118
casacore::Copy_global_functions_test::objtestmv
void objtestmv(size_t &nLeft, size_t &startLeft, size_t &startRight, const void *to, const void *from, const size_t n, const size_t toStride, const size_t fromStride, const void *toPn, const void *fromPn, const size_t fromMto, const size_t toMfrom)
Test on how to handle the overlap in move.
casacore::Copy_global_functions_throw
Definition Copy.h:103
casacore::Copy_global_functions_throw::objthrowmv1
void objthrowmv1(const void *to, const void *from, const size_t n)
Throw the various AipsErrors when incorrect arguments used.
casacore::Copy_global_functions_throw::objthrowcp1
void objthrowcp1(const void *to, const void *from, const size_t n)
casacore::Copy_global_functions_throw::objthrowfl1
void objthrowfl1(const void *to, const size_t n)
casacore::Copy_global_functions_throw::objthrowmv2
void objthrowmv2(const void *to, const void *from, const size_t n, const size_t toStride, const size_t fromStride)
casacore::Copy_global_functions_throw::objthrowfl2
void objthrowfl2(const void *to, const size_t n, const size_t toStride)
casacore::Copy_global_functions_throw::objthrowcp2
void objthrowcp2(const void *to, const void *from, const size_t n, const size_t toStride, const size_t fromStride)