Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
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 
49 namespace {
50 
51 
54 using Teuchos::RCP;
55 using Teuchos::rcp;
56 using Teuchos::Array;
57 using Teuchos::ArrayRCP;
58 using Teuchos::arcp;
59 using Teuchos::ArrayView;
60 using Teuchos::arrayView;
61 using Teuchos::av_const_cast;
62 using Teuchos::av_reinterpret_cast;
64 using Teuchos::as;
65 using Teuchos::null;
67 
68 
69 TEUCHOS_UNIT_TEST( ArrayView, assignSelf )
70 {
71  ArrayView<int> av;
72  av = av;
73  TEST_ASSERT(is_null(av));
74  TEST_ASSERT(!nonnull(av));
75 }
76 
77 
78 TEUCHOS_UNIT_TEST( ArrayView, assignFuncSelf )
79 {
80  Array<int> a = generateArray<int>(n);
81  ArrayView<int> av = a;
82  av.assign(av);
83 }
84 
85 
86 TEUCHOS_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 
94 TEUCHOS_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.getRawPtr(), arcp_int.getRawPtr());
102 }
103 
104 
105 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_null )
106 {
107  ArrayView<char> av_char = null;
108  ArrayView<int> av_int = av_reinterpret_cast<int>(av_char);
109  TEST_ASSERT(is_null(av_int));
110 }
111 
112 
113 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_char_to_int )
114 {
115 
116  const int sizeOfInt = sizeof(int);
117  const int sizeOfChar = sizeof(char);
118  const int num_ints = n;
119  const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
120  out << "num_ints = " << num_ints << "\n";
121  out << "num_chars = " << num_chars << "\n";
122 
123  ArrayRCP<char> arcp_char = arcp<char>(num_chars);
124  ArrayView<int> av_int = av_reinterpret_cast<int>(arcp_char());
125  TEST_EQUALITY(av_int.size(), num_ints);
126  TEST_EQUALITY(implicit_ptr_cast<void>(&av_int[0]),
127  implicit_ptr_cast<void>(&arcp_char[0]));
128  TEST_EQUALITY(implicit_ptr_cast<void>((&av_int[num_ints-1])+1),
129  implicit_ptr_cast<void>((&arcp_char[num_chars-1])+1));
130 
131 }
132 
133 
134 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_int_to_char )
135 {
136 
137  const int sizeOfInt = sizeof(int);
138  const int sizeOfChar = sizeof(char);
139  const int num_ints = n;
140  const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
141  out << "num_ints = " << num_ints << "\n";
142  out << "num_chars = " << num_chars << "\n";
143 
144  ArrayRCP<int> arcp_int = arcp<int>(num_ints);
145  ArrayView<char> av_char = av_reinterpret_cast<char>(arcp_int());
146  TEST_EQUALITY(av_char.size(), num_chars);
147  TEST_EQUALITY(implicit_ptr_cast<void>(&arcp_int[0]),
148  implicit_ptr_cast<void>(&av_char[0]));
149  TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
150  implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
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 
154 }
155 
156 
157 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView_construct_zero_size, T )
158 {
159  Array<T> a;
160  const ArrayView<T> av = arrayView(a.getRawPtr(), a.size());
161  TEST_EQUALITY_CONST(av.size(), 0);
162  TEST_ASSERT(is_null(av));
163  TEST_ASSERT(!nonnull(av));
164 }
165 
166 
168 {
169  Array<T> a = generateArray<T>(n);
170  const ArrayView<T> av = arrayView(&a[0], a.size());
171  TEST_COMPARE_ARRAYS( a, av );
172 }
173 
174 
175 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, null_zero_ArrayView_operator, T )
176 {
177  const ArrayView<T> av_0;
178  const ArrayView<T> av = av_0(0, 0);
179  TEST_ASSERT(is_null(av));
180 }
181 
182 
183 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, null_zero_ArrayView_func, T )
184 {
185  const ArrayView<T> av_0;
186  const ArrayView<T> av = av_0.view(0, 0);
187  TEST_ASSERT(is_null(av));
188 }
189 
190 
191 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, raw_ptr_self_view, T )
192 {
193  T *data = new T[10];
194  ArrayView<T> view(data, 10);
195  view = view(0, 5);
196  TEST_EQUALITY(view.getRawPtr(), data);
197  TEST_EQUALITY_CONST(view.size(), 5);
198  ArrayView<const T> cview = view.getConst();
199  TEST_EQUALITY(cview.getRawPtr(), const_cast<const T*>(data));
200  TEST_EQUALITY_CONST(cview.size(), 5);
201 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
202  ArrayRCP<const T> cview_arcp = cview.access_private_arcp();
203  TEST_EQUALITY(cview_arcp.getRawPtr(), const_cast<const T*>(data));
204  TEST_EQUALITY_CONST(cview_arcp.size(), 5);
205 #endif
206  delete [] data;
207 }
208 
209 
210 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, raw_ptr_self_view_const, T )
211 {
212  T const * data = new T[10];
213  ArrayView<const T> view(data, 10);
214  view = view(0, 5);
215  TEST_EQUALITY(view.getRawPtr(), data);
216  TEST_EQUALITY_CONST(view.size(), 5);
217  ArrayView<const T> cview = view.getConst();
218  TEST_EQUALITY(cview.getRawPtr(), data);
219  TEST_EQUALITY_CONST(cview.size(), 5);
220 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
221  ArrayRCP<const T> cview_arcp = cview.access_private_arcp();
222  TEST_EQUALITY(cview_arcp.getRawPtr(), data);
223  TEST_EQUALITY_CONST(cview_arcp.size(), 5);
224 #endif
225  delete [] data;
226 }
227 
228 
229 template<typename T>
230 void resizeRawView(
231  Teuchos::ArrayView<T> &view_inout, Teuchos::Ordinal offset, Teuchos::Ordinal size
232  )
233 {
234  if (view_inout.size() == 0 && size == 0) { return; }
235 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
236  const T &next_to_last = view_inout[offset+size-1];
237  (void)next_to_last;
238 #endif
239  view_inout = arrayView<T>(&view_inout[offset], size);
240 }
241 
242 
243 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, resize_raw_ptr_self_view, T )
244 {
245  T *data = new T[10];
246  ArrayView<T> view(data, 10);
247  resizeRawView(view, 0, 5);
248  TEST_EQUALITY(view.getRawPtr(), data);
249  TEST_EQUALITY_CONST(view.size(), 5);
250  delete [] data;
251  // NOTE: The above works because we are creating a completely new ArrayView
252  // object and are not viewing the original array object which is going away.
253 }
254 
255 
256 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, assignmentOperator, T )
257 {
258  Array<T> a = generateArray<T>(n);
259  ArrayView<T> av1;
260  av1 = a;
261  ArrayView<T> av2;
262  av2 = av1;
263  TEST_EQUALITY( av1.getRawPtr(), a.getRawPtr() );
264  TEST_EQUALITY( av1.size(), as<int>(a.size()) );
265  TEST_EQUALITY( av1.getRawPtr(), av2.getRawPtr() );
266  TEST_EQUALITY( av1.size(), av2.size() );
267  TEST_COMPARE_ARRAYS( av1, a );
268  TEST_COMPARE_ARRAYS( av1, av2 );
269  av1 = null;
270  TEST_EQUALITY_CONST( av1.getRawPtr(), 0 );
271  TEST_EQUALITY_CONST( av1.size(), 0 );
272  av2 = null;
273  TEST_EQUALITY_CONST( av2.getRawPtr(), 0 );
274  TEST_EQUALITY_CONST( av2.size(), 0 );
275 }
276 
277 
278 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, iterators, T )
279 {
280  typedef typename ArrayView<T>::iterator iter_t;
281  typedef Teuchos::ScalarTraits<T> ST;
282  ECHO(Array<T> a = generateArray<T>(n));
283  ECHO(ArrayView<T> av = a);
284  ECHO(const iter_t av_begin = av.begin());
285  ECHO(const iter_t av_end = av.end());
286 #ifdef TEUCHOS_DEBUG
287  TEST_ASSERT(av_begin.shares_resource(av_end));
288 #endif
289  ECHO(std::fill(av_begin, av_end, ST::random()));
290  ECHO(Array<T> a2 = generateArray<T>(n));
291  ECHO(ArrayView<T> av2 = a2);
292  ECHO(std::copy(av.begin(), av.end(), av2.begin()));
293  TEST_COMPARE_ARRAYS(a, a2);
294 }
295 
296 
297 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView_convertToConst, T )
298 {
299  const int nsize = 3;
300  T t[nsize];
301  t[0] = 1;
302  t[1] = 2;
303  t[2] = 3;
304  ArrayView<const T> av1 = arrayView<T>(&t[0], nsize);
305  TEST_EQUALITY_CONST(av1[0], 1);
306  TEST_EQUALITY_CONST(av1[1], 2);
307  TEST_EQUALITY_CONST(av1[2], 3);
308 }
309 
310 
311 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_std_vector, T )
312 {
313  ArrayView<T> av;
314  T* badPtr = 0;
315  {
316  std::vector<T> v(n);
317  av = v;
318  badPtr = &v[0];
319  }
320  // Access the raw pointer but it now points to invalid memory!
321  TEST_EQUALITY(av.getRawPtr(), badPtr);
322  // Above, we have no way to detect that the underlying std::vector object
323  // has gone away. This is the whole point of needing Teuchos::Array and
324  // having an integrated set of utility classes that all work together!
325 }
326 
327 
328 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_rcp_std_vector, T )
329 {
330  ArrayView<T> av;
331  {
332  ArrayRCP<T> ap = arcp(rcp(new std::vector<T>(n)));
333  av = ap();
334  }
335 #ifdef TEUCHOS_DEBUG
336  TEST_THROW(av.getRawPtr(), DanglingReferenceError);
337 #endif
338  // Above, because we wrapped the initial std::vector in an RCP object, we
339  // can sucessfully detect when the object goes away in debug mode!
340 }
341 
342 
343 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
344 
345 
346 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
347 
348 
349 //
350 // Instantiations
351 //
352 
353 
354 
355 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
356 
357 # define DEBUG_UNIT_TEST_GROUP( T )
358 
359 #else // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
360 
361 # define DEBUG_UNIT_TEST_GROUP( T )
362 
363 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
364 
365 
366 #define UNIT_TEST_GROUP( T ) \
367  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_construct_zero_size, T ) \
368  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView, T ) \
369  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_operator, T ) \
370  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_func, T ) \
371  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, raw_ptr_self_view, T ) \
372  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, raw_ptr_self_view_const, T ) \
373  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, resize_raw_ptr_self_view, T ) \
374  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, assignmentOperator, T ) \
375  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, iterators, T ) \
376  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_convertToConst, T ) \
377  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_std_vector, T ) \
378  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_rcp_std_vector, T ) \
379  DEBUG_UNIT_TEST_GROUP( T )
380 
381 
382 UNIT_TEST_GROUP(int)
383 UNIT_TEST_GROUP(float)
384 UNIT_TEST_GROUP(double)
385 
386 
387 } // namespace
Dangling reference error exception class.
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object...
ArrayView< T > arrayView(T *p, typename ArrayView< T >::size_type size)
Construct a const or non-const view to const or non-const data.
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define UNIT_TEST_GROUP(T)
#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 TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_THROW(code, ExceptType)
Assert that the statement &#39;code&#39; throws the exception &#39;ExceptType&#39; (otherwise the test fails)...
size_type size() const
The total number of items in the managed array.
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP<Array<T> > object as an ArrayRCP<T> object.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
This structure defines some basic traits for a scalar field type.
ArrayView< T2 > av_reinterpret_cast(const ArrayView< T1 > &p1)
Reinterpret cast of underlying ArrayView type from T1* to T2*.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
ArrayView< T2 > av_const_cast(const ArrayView< T1 > &p1)
Const cast of underlying ArrayView type from const T* to T*.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
TypeTo * implicit_ptr_cast(TypeFrom *t)
Perform an implicit cast of pointer types with a pointer being returned.
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
Teuchos::Array< T > generateArray(const int n_in)
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
#define TEST_COMPARE_ARRAYS(a1, a2)
Assert that a1.size()==a2.size() and a[i]==b[i], i=0....
Nonowning array view.
Smart reference counting pointer class for automatic garbage collection.
bool nonnull(const ArrayRCP< T > &p)
Returns true if p.get()!=NULL.
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...