Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
ArrayView_UnitTests.cpp
Go to the documentation of this file.
1/*
2// @HEADER
3// ***********************************************************************
4//
5// Teuchos: Common Tools Package
6// Copyright (2004) Sandia Corporation
7//
8// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9// license for use of this work by or on behalf of the U.S. Government.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39//
40// ***********************************************************************
41// @HEADER
42*/
43
45
47
48
49namespace {
50
51
54using Teuchos::RCP;
55using Teuchos::rcp;
56using Teuchos::Array;
58using Teuchos::arcp;
60using Teuchos::arrayView;
61using Teuchos::av_const_cast;
62using Teuchos::av_reinterpret_cast;
64using Teuchos::as;
65using Teuchos::null;
67
68
69TEUCHOS_UNIT_TEST( ArrayView, assignSelf )
70{
71 ArrayView<int> av;
72 av = av;
74 TEST_ASSERT(!nonnull(av));
75}
76
77
78TEUCHOS_UNIT_TEST( ArrayView, assignFuncSelf )
79{
80 Array<int> a = generateArray<int>(n);
81 ArrayView<int> av = a;
82 av.assign(av);
83}
84
85
86TEUCHOS_UNIT_TEST( ArrayView, av_const_cast_null )
87{
88 ArrayView<const int> av_int1 = null;
89 ArrayView<int> av_int2 = av_const_cast<int>(av_int1);
90 TEST_ASSERT(is_null(av_int2));
91}
92
93
94TEUCHOS_UNIT_TEST( ArrayView, av_const_cast )
95{
96 ArrayRCP<const int> arcp_int = arcp<int>(n);
97 ArrayView<const int> av_int1 = arcp_int();
98 ArrayView<int> av_int2 = av_const_cast<int>(av_int1);
99 TEST_ASSERT(nonnull(av_int2));
100 TEST_EQUALITY(av_int2.getRawPtr(), av_int1.getRawPtr());
101 TEST_EQUALITY(av_int2.data(), av_int1.data());
102 TEST_EQUALITY(av_int2.getRawPtr(), arcp_int.getRawPtr());
103 TEST_EQUALITY(av_int2.data(), arcp_int.getRawPtr());
104}
105
106
107TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_null )
108{
109 ArrayView<char> av_char = null;
110 ArrayView<int> av_int = av_reinterpret_cast<int>(av_char);
111 TEST_ASSERT(is_null(av_int));
112}
113
114
115TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_char_to_int )
116{
117
118 const int sizeOfInt = sizeof(int);
119 const int sizeOfChar = sizeof(char);
120 const int num_ints = n;
121 const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
122 out << "num_ints = " << num_ints << "\n";
123 out << "num_chars = " << num_chars << "\n";
124
125 ArrayRCP<char> arcp_char = arcp<char>(num_chars);
126 ArrayView<int> av_int = av_reinterpret_cast<int>(arcp_char());
127 TEST_EQUALITY(av_int.size(), num_ints);
128 TEST_EQUALITY(implicit_ptr_cast<void>(&av_int[0]),
129 implicit_ptr_cast<void>(&arcp_char[0]));
130 TEST_EQUALITY(implicit_ptr_cast<void>((&av_int[num_ints-1])+1),
131 implicit_ptr_cast<void>((&arcp_char[num_chars-1])+1));
132
133}
134
135
136TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_int_to_char )
137{
138
139 const int sizeOfInt = sizeof(int);
140 const int sizeOfChar = sizeof(char);
141 const int num_ints = n;
142 const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
143 out << "num_ints = " << num_ints << "\n";
144 out << "num_chars = " << num_chars << "\n";
145
146 ArrayRCP<int> arcp_int = arcp<int>(num_ints);
147 ArrayView<char> av_char = av_reinterpret_cast<char>(arcp_int());
148 TEST_EQUALITY(av_char.size(), num_chars);
149 TEST_EQUALITY(implicit_ptr_cast<void>(&arcp_int[0]),
150 implicit_ptr_cast<void>(&av_char[0]));
151 TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
152 implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
153 TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
154 implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
155
156}
157
158
159TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView_construct_zero_size, T )
160{
161 Array<T> a;
162 const ArrayView<T> av = arrayView(a.getRawPtr(), a.size());
163 TEST_EQUALITY_CONST(av.size(), 0);
164 TEST_ASSERT(is_null(av));
165 TEST_ASSERT(!nonnull(av));
166}
167
168
169TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView, T )
170{
171 Array<T> a = generateArray<T>(n);
172 const ArrayView<T> av = arrayView(&a[0], a.size());
173 TEST_COMPARE_ARRAYS( a, av );
174}
175
176
177TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, null_zero_ArrayView_operator, T )
178{
179 const ArrayView<T> av_0;
180 const ArrayView<T> av = av_0(0, 0);
181 TEST_ASSERT(is_null(av));
182}
183
184
185TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, null_zero_ArrayView_func, T )
186{
187 const ArrayView<T> av_0;
188 const ArrayView<T> av = av_0.view(0, 0);
189 TEST_ASSERT(is_null(av));
190}
191
192
193TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, raw_ptr_self_view, T )
194{
195 T *data = new T[10];
196 ArrayView<T> view(data, 10);
197 view = view(0, 5);
198 TEST_EQUALITY(view.getRawPtr(), data);
199 TEST_EQUALITY(view.data(), data);
200 TEST_EQUALITY_CONST(view.size(), 5);
201 ArrayView<const T> cview = view.getConst();
202 TEST_EQUALITY(cview.getRawPtr(), const_cast<const T*>(data));
203 TEST_EQUALITY(cview.data(), const_cast<const T*>(data));
204 TEST_EQUALITY_CONST(cview.size(), 5);
205#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
206 ArrayRCP<const T> cview_arcp = cview.access_private_arcp();
207 TEST_EQUALITY(cview_arcp.getRawPtr(), const_cast<const T*>(data));
208 TEST_EQUALITY_CONST(cview_arcp.size(), 5);
209#endif
210 delete [] data;
211}
212
213
214TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, raw_ptr_self_view_const, T )
215{
216 T const * data = new T[10];
217 ArrayView<const T> view(data, 10);
218 view = view(0, 5);
219 TEST_EQUALITY(view.getRawPtr(), data);
220 TEST_EQUALITY(view.data(), data);
221 TEST_EQUALITY_CONST(view.size(), 5);
222 ArrayView<const T> cview = view.getConst();
223 TEST_EQUALITY(cview.getRawPtr(), data);
224 TEST_EQUALITY(cview.data(), data);
225 TEST_EQUALITY_CONST(cview.size(), 5);
226#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
227 ArrayRCP<const T> cview_arcp = cview.access_private_arcp();
228 TEST_EQUALITY(cview_arcp.getRawPtr(), data);
229 TEST_EQUALITY_CONST(cview_arcp.size(), 5);
230#endif
231 delete [] data;
232}
233
234
235template<typename T>
236void resizeRawView(
237 Teuchos::ArrayView<T> &view_inout, Teuchos::Ordinal offset, Teuchos::Ordinal size
238 )
239{
240 if (view_inout.size() == 0 && size == 0) { return; }
241#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
242 const T &next_to_last = view_inout[offset+size-1];
243 (void)next_to_last;
244#endif
245 view_inout = arrayView<T>(&view_inout[offset], size);
246}
247
248
249TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, resize_raw_ptr_self_view, T )
250{
251 T *data = new T[10];
252 ArrayView<T> view(data, 10);
253 resizeRawView(view, 0, 5);
254 TEST_EQUALITY(view.getRawPtr(), data);
255 TEST_EQUALITY(view.data(), data);
256 TEST_EQUALITY_CONST(view.size(), 5);
257 delete [] data;
258 // NOTE: The above works because we are creating a completely new ArrayView
259 // object and are not viewing the original array object which is going away.
260}
261
262
263TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, assignmentOperator, T )
264{
265 Array<T> a = generateArray<T>(n);
266 ArrayView<T> av1;
267 av1 = a;
268 ArrayView<T> av2;
269 av2 = av1;
270 TEST_EQUALITY( av1.getRawPtr(), a.getRawPtr() );
271 TEST_EQUALITY( av1.data(), a.data() );
272 TEST_EQUALITY( av1.getRawPtr(), a.data() );
273 TEST_EQUALITY( av1.data(), a.getRawPtr() );
274 TEST_EQUALITY( av1.size(), as<int>(a.size()) );
275 TEST_EQUALITY( av1.getRawPtr(), av2.getRawPtr() );
276 TEST_EQUALITY( av1.data(), av2.data() );
277 TEST_EQUALITY( av1.data(), av2.getRawPtr() );
278 TEST_EQUALITY( av1.getRawPtr(), av2.data() );
279 TEST_EQUALITY( av1.size(), av2.size() );
280 TEST_COMPARE_ARRAYS( av1, a );
281 TEST_COMPARE_ARRAYS( av1, av2 );
282 av1 = null;
283 TEST_EQUALITY_CONST( av1.getRawPtr(), 0 );
284 TEST_EQUALITY_CONST( av1.data(), 0 );
285 TEST_EQUALITY_CONST( av1.size(), 0 );
286 av2 = null;
287 TEST_EQUALITY_CONST( av2.getRawPtr(), 0 );
288 TEST_EQUALITY_CONST( av2.data(), 0 );
289 TEST_EQUALITY_CONST( av2.size(), 0 );
290}
291
292
293TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, iterators, T )
294{
295 typedef typename ArrayView<T>::iterator iter_t;
296 typedef Teuchos::ScalarTraits<T> ST;
297 ECHO(Array<T> a = generateArray<T>(n));
298 ECHO(ArrayView<T> av = a);
299 ECHO(const iter_t av_begin = av.begin());
300 ECHO(const iter_t av_end = av.end());
301#ifdef TEUCHOS_DEBUG
302 TEST_ASSERT(av_begin.shares_resource(av_end));
303#endif
304 ECHO(std::fill(av_begin, av_end, ST::random()));
305 ECHO(Array<T> a2 = generateArray<T>(n));
306 ECHO(ArrayView<T> av2 = a2);
307 ECHO(std::copy(av.begin(), av.end(), av2.begin()));
308 TEST_COMPARE_ARRAYS(a, a2);
309}
310
311
312TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView_convertToConst, T )
313{
314 const int nsize = 3;
315 T t[nsize];
316 t[0] = 1;
317 t[1] = 2;
318 t[2] = 3;
319 ArrayView<const T> av1 = arrayView<T>(&t[0], nsize);
320 TEST_EQUALITY_CONST(av1[0], 1);
321 TEST_EQUALITY_CONST(av1[1], 2);
322 TEST_EQUALITY_CONST(av1[2], 3);
323}
324
325
326TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_std_vector, T )
327{
328 ArrayView<T> av;
329 T* badPtr = 0;
330 {
331 std::vector<T> v(n);
332 av = v;
333 badPtr = &v[0];
334 }
335 // Access the raw pointer but it now points to invalid memory!
336 TEST_EQUALITY(av.getRawPtr(), badPtr);
337 TEST_EQUALITY(av.data(), badPtr);
338 // Above, we have no way to detect that the underlying std::vector object
339 // has gone away. This is the whole point of needing Teuchos::Array and
340 // having an integrated set of utility classes that all work together!
341}
342
343
344TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_rcp_std_vector, T )
345{
346 ArrayView<T> av;
347 {
348 ArrayRCP<T> ap = arcp(rcp(new std::vector<T>(n)));
349 av = ap();
350 }
351#ifdef TEUCHOS_DEBUG
352 TEST_THROW(av.getRawPtr(), DanglingReferenceError);
353 TEST_THROW(av.data(), DanglingReferenceError);
354#endif
355 // Above, because we wrapped the initial std::vector in an RCP object, we
356 // can sucessfully detect when the object goes away in debug mode!
357}
358
359
360#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
361
362
363#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
364
365
366//
367// Instantiations
368//
369
370
371
372#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
373
374# define DEBUG_UNIT_TEST_GROUP( T )
375
376#else // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
377
378# define DEBUG_UNIT_TEST_GROUP( T )
379
380#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
381
382
383#define UNIT_TEST_GROUP( T ) \
384 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_construct_zero_size, T ) \
385 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView, T ) \
386 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_operator, T ) \
387 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_func, T ) \
388 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, raw_ptr_self_view, T ) \
389 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, raw_ptr_self_view_const, T ) \
390 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, resize_raw_ptr_self_view, T ) \
391 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, assignmentOperator, T ) \
392 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, iterators, T ) \
393 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_convertToConst, T ) \
394 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_std_vector, T ) \
395 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_rcp_std_vector, T ) \
396 DEBUG_UNIT_TEST_GROUP( T )
397
398
400UNIT_TEST_GROUP(float)
401UNIT_TEST_GROUP(double)
402
403
404} // namespace
#define UNIT_TEST_GROUP(T)
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_THROW(code, ExceptType)
Assert that the statement 'code' throws the exception 'ExceptType' (otherwise the test fails).
#define TEST_COMPARE_ARRAYS(a1, a2)
Assert that a1.size()==a2.size() and a[i]==b[i], i=0....
#define ECHO(statement)
Echo the given statement before it is executed.
#define TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(TEST_GROUP, TEST_NAME, TYPE)
Macro for defining a templated unit test with one template parameter.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Reference-counted smart pointer for managing arrays.
Nonowning array view.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
Dangling reference error exception class.
Smart reference counting pointer class for automatic garbage collection.
Concrete serial communicator subclass.
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool nonnull(const boost::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
Teuchos::Array< T > generateArray(const int n_in)
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
TypeTo * implicit_ptr_cast(TypeFrom *t)
Perform an implicit cast of pointer types with a pointer being returned.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.