casacore
Copy.h
Go to the documentation of this file.
1//# Copy.h: Copy objects from one C-style array to another.
2//# Copyright (C) 1994-1997,1999-2002,2005,2015
3//# Associated Universities, Inc. Washington DC, USA.
4//# National Astronomical Observatory of Japan
5//# 2-21-1, Osawa, Mitaka, Tokyo, 181-8588, Japan.
6//#
7//# This library is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU Library General Public License as published by
9//# the Free Software Foundation; either version 2 of the License, or (at your
10//# option) any later version.
11//#
12//# This library is distributed in the hope that it will be useful, but WITHOUT
13//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15//# License for more details.
16//#
17//# You should have received a copy of the GNU Library General Public License
18//# along with this library; if not, write to the Free Software Foundation,
19//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning AIPS++ should be addressed as follows:
22//# Internet email: aips2-request@nrao.edu.
23//# Postal address: AIPS++ Project Office
24//# National Radio Astronomy Observatory
25//# 520 Edgemont Road
26//# Charlottesville, VA 22903-2475 USA
27//#
28//# $Id$
29
30#ifndef CASA_COPY_H
31#define CASA_COPY_H
32
33//# Includes
34#include <casacore/casa/aips.h>
35#include <casacore/casa/BasicSL/Complex.h>
36#include <algorithm>
37
38namespace casacore { //# NAMESPACE CASACORE - BEGIN
39
40 // <summary>
41 // Copy objects from one C-style array to another.
42 // </summary>
43
44 // <use visibility=export>
45 // <reviewed reviewer="Friso Olnon" date="1995/03/14" tests="tCopy" demos="">
46 // </reviewed>
47
48 // <synopsis>
49 // Objset is used to fill a C-style array of objects.
50 //
51 // Objcopy and objmove are used to copy objects from one place to
52 // another. Optionally a stride can be supplied.
53 //
54 // The functions are equivalent to C's <src>memcpy</src> and
55 // <src>memmove</src>.
56 // When possible C++ standard library functions are used to implement them
57 //
58 // Similar to memcpy and memmove, the difference between objcopy
59 // and objmove is that objmove takes account of an overlap of source and
60 // destination. In general, objcopy is slighty (but only slighty) faster.
61 // </synopsis>
62
63 // <example>
64 // Setting and copying arrays of built-in types:
65 // <srcblock>
66 // // Create int array of 4 elements
67 // size_t size=4;
68 // int* ia = new int[size];
69 // // Initialize all elements to value 99
70 // objset(ia, 99, size);
71 // // Change all odd elements to 66 -> [99 66 99 66]
72 // objset(ia+1, 66, 5, 2);
73 //
74 // // Create another 4-element int array
75 // int* ia2 = new int[size];
76 // // Copy array ia into array ia2 -> [99 66 99 66]
77 // objmove(ia2, ia, size);
78 // // Copy the even elements of ia to the odd elements of ia2
79 // // -> [99 99 99 99]
80 // objcopy(ia2+1, ia, size/2, 2, 2);
81 // </srcblock>
82 //
83 // Setting and copying arrays of a randomly chosen type:
84 // <srcblock>
85 // // Create 4-element array of 3-element Block<int> objects
86 // size_t size=4;
87 // Block<int>* ta = new Block<int>[size];
88 // Block<int> set(3);
89 // // Initialize the array -> [[123][123][123][123]]
90 // set[0] = 1; set[1] = 2; set[2] = 3;
91 // objset(ta, set, size);
92 // // Change odd Blocks to [777]-> [[123][777][123][777]]
93 // set[0] = set[1] = set[2] = 7;
94 // objset(ta + 1, set, size/2, 2);
95 //
96 // // Create another Block<int> array
97 // Block<int>* ta2 = new Block<int>[size];
98 // // Copy the even elements of ta to the first elements of ta2
99 // // -> [[123][123]...]
100 // objcopy(ta2, ta, size/2, 1, 2);
101 // </srcblock>
102 // </example>
103
104 // <group name=throw>
105 // Throw the various AipsErrors when incorrect arguments used
106 void objthrowmv1(const void *to, const void *from, const size_t n);
107 void objthrowmv2(const void *to, const void *from, const size_t n,
108 const size_t toStride, const size_t fromStride);
109 void objthrowcp1(const void *to, const void *from, const size_t n);
110 void objthrowcp2(const void *to, const void *from, const size_t n,
111 const size_t toStride, const size_t fromStride);
112 void objthrowfl1(const void *to, const size_t n);
113 void objthrowfl2(const void *to, const size_t n,
114 const size_t toStride);
115 // </group>
116
117 // <summary> Test routines </summary>
118 // <group name=test>
119 // Test on how to handle the overlap in move
120 void objtestmv(size_t &nLeft, size_t &startLeft, size_t &startRight,
121 const void *to, const void *from, const size_t n,
122 const size_t toStride, const size_t fromStride,
123 const void *toPn, const void *fromPn,
124 const size_t fromMto, const size_t toMfrom);
125 // </group>
126
127 // <summary> Copy methods </summary>
128 // <group name=copy>
129 // The general function to copy <src>n</src> objects from one place
130 // to another if overlap between <src>to</src> and <src>from</src> fields
131 // is possible. Strides may be specified, i.e. you may copy from every
132 // <src>fromStride</src>-th position into every <src>toStride</src>-th
133 // one.
134 //
135 // The function will call <src>std::copy()</src> when possible.
136 // Objmove works correctly if the source and destination overlap in any way.
137 //
138 // An exception will be thrown if the source or the destination does not
139 // exist (and <em>n</em> is non-zero) or if the strides are non-positive.
140 // <thrown>
141 // <li> AipsError
142 // </thrown>
143 //
144 // <group>
145 template<class T> void objmove(T* to, const T* from, size_t n) {
146 objthrowmv1(to,from,n);
147 (to<from || to >= from+n) ? std::copy(from,from+n,to)
148 : std::copy_backward(from,from+n,to+n); }
149 template<class T> void objmove(T* to, const T* from, size_t n,
150 size_t toStride, size_t fromStride) {
151 if (!n) return;
152 objthrowmv2(to,from,n,toStride,fromStride);
153 if (toStride*fromStride == 1) { objmove(to, from, n);
154 return; }
155 size_t nLeft, startLeft, startRight;
156 size_t fromMto=0; size_t toMfrom=0;
157 if (toStride > fromStride && from > to)
158 fromMto = (from-to)/(toStride-fromStride);
159 else if (toStride < fromStride && from < to)
160 toMfrom = (to-from)/(fromStride-toStride);
161 objtestmv(nLeft, startLeft, startRight, to, from, n,
162 toStride, fromStride, to+n*toStride, from+n*fromStride,
163 fromMto, toMfrom);
164 n -= nLeft;
165 if (nLeft) {
166 const T* fromPtr = from + startLeft*fromStride;
167 T* toPtr = to + startLeft*toStride;
168 while (nLeft--) { *toPtr = *fromPtr;
169 fromPtr += fromStride;
170 toPtr += toStride; }; };
171 // Do the moves from the right.
172 if (n) {
173 const T* fromPtr = from + startRight*fromStride;
174 T* toPtr = to + startRight*toStride;
175 while (n--) { fromPtr -= fromStride; toPtr -= toStride;
176 *toPtr = *fromPtr; }; };
177 }
178 // </group>
179
180 // The non-general function to copy <src>n</src> objects from one place
181 // to another. Strides may be specified, i.e. you may copy from every
182 // <src>fromStride</src>-th position into every <src>toStride</src>-th
183 // one.
184 //
185 // Objcopy/objcopyctor does not take an overlap of source and destination into account.
186 // Objmove should be used if that is an issue.
187 //
188 // Objcopyctor copy objects from <src>from</src> by calling copy constructor
189 // on each element in <src>to</src>.
190 //
191 // An exception will be thrown if the source or the destination does not
192 // exist or if the strides are non-positive.
193 // <thrown>
194 // <li> AipsError
195 // </thrown>
196 //
197 // <group>
198 template<class T> void objcopy(T* to, const T* from, size_t n) {
199 objthrowcp1(to,from,n); std::copy(from, from+n, to); }
200 template<class T> void objcopy(T* to, const T* from, size_t n,
201 size_t toStride, size_t fromStride) {
202 objthrowcp2(to,from,n,toStride,fromStride); while (n--) {
203 *to = *from; to += toStride; from += fromStride; } }
204
205 template<class T> void objcopyctor(T* to, const T* from, size_t n) {
206 objthrowcp1(to, from, n);
207 size_t i;
208 try {
209 for (i = 0; i < n; ++i) {
210 ::new (&to[i]) T(from[i]);
211 }
212 } catch (...) {
213 while (i > 0) { // roll back
214 to[--i].~T();
215 }
216 throw;
217 }
218 }
219 template<class T> void objcopyctor(T* to, const T* from, size_t n,
220 size_t toStride, size_t fromStride) {
221 objthrowcp2(to, from, n, toStride, fromStride);
222 size_t i = 0;
223 try {
224 for (i = 0; i < n; ++i) {
225 ::new (to) T(*from);
226 to += toStride;
227 from += fromStride;
228 }
229 } catch (...) {
230 while (i > 0) { // roll back
231 --i;
232 to -= toStride;
233 to->~T();
234 }
235 throw;
236 }
237 }
238 // </group>
239
240 // Fill <src>n</src> elements of an array of objects with the given
241 // value, optionally with a stride. Note that the fillValue is passed
242 // by value.
243 //
244 // An exception will be thrown if the destination array does not exist
245 // or if the stride is non-positive.
246 //
247 // <thrown>
248 // <li> AipsError
249 // </thrown>
250 //
251 // <group>
252 template<class T> void objset(T* to, const T fillValue, size_t n) {
253 objthrowfl1(to,n); std::fill_n(to, n, fillValue); }
254
255 template<class T> void objset(T* to, const T fillValue, size_t n,
256 size_t toStride) {
257 objthrowfl2(to,n,toStride);
258 while (n--){*to = fillValue; to += toStride; }; }
259
260 // </group>
261
262 // </group>
263
264} //# NAMESPACE CASACORE - END
265
266#ifndef CASACORE_NO_AUTO_TEMPLATES
267#include <casacore/casa/Utilities/Copy.tcc>
268#endif //# CASACORE_NO_AUTO_TEMPLATES
269#endif
this file contains all the compiler specific defines
Definition: mainpage.dox:28
StatsData< AccumType > copy(const StatsData< AccumType > &stats)
void objcopyctor(T *to, const T *from, size_t n)
Definition: Copy.h:205
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:198
void objset(T *to, const T fillValue, size_t n, size_t toStride)
Definition: Copy.h:255
void objcopyctor(T *to, const T *from, size_t n, size_t toStride, size_t fromStride)
Definition: Copy.h:219
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:145
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:252
void objcopy(T *to, const T *from, size_t n, size_t toStride, size_t fromStride)
Definition: Copy.h:200
void objmove(T *to, const T *from, size_t n, size_t toStride, size_t fromStride)
Definition: Copy.h:149
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.
void objthrowmv1(const void *to, const void *from, const size_t n)
Throw the various AipsErrors when incorrect arguments used.
void objthrowcp1(const void *to, const void *from, const size_t n)
void objthrowfl1(const void *to, 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 objthrowfl2(const void *to, const size_t n, const size_t toStride)
void objthrowcp2(const void *to, const void *from, const size_t n, const size_t toStride, const size_t fromStride)