Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
ArrayView_test.cpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Teuchos: Common Tools Package
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40// @HEADER
41
42#include "Teuchos_ArrayView.hpp"
47#include "Teuchos_Version.hpp"
48#include "Teuchos_getConst.hpp"
49#include "Teuchos_as.hpp"
51
52
53// Uncomment to show compile errors from invalid usage
54//#define SHOW_INVALID_COPY_CONSTRUCTION
55//#define SHOW_INVALID_CONST_ASSIGN
56//#define SHOW_INVALID_CONST_ITER_MODIFICATION
57
58//
59// Define local macros to make defining tests easier for this particular test
60// code.
61//
62// Note, macros with these types of names should only exist in a *.cpp file
63// after all #includes are done!
64//
65
66
67#define TEST_EQUALITY_CONST( v1, v2 ) \
68 TEUCHOS_TEST_EQUALITY_CONST( v1, v2, out, success )
69
70#define TEST_EQUALITY( v1, v2 ) \
71 TEUCHOS_TEST_EQUALITY( v1, v2, out, success )
72
73#define TEST_ITER_EQUALITY( iter1, iter2 ) \
74 TEUCHOS_TEST_ITER_EQUALITY( iter1, iter2, out, success )
75
76#define TEST_ARRAY_ELE_EQUALITY( a, i, val ) \
77 TEUCHOS_TEST_ARRAY_ELE_EQUALITY( a, i, val, false, out, local_success )
78
79#define TEST_COMPARE( v1, comp, v2 ) \
80 TEUCHOS_TEST_COMPARE( v1, comp, v2, out, success )
81
82#define TEST_COMPARE_ARRAYS( a1, a2 ) \
83 { \
84 const bool result = compareArrays(a1,#a1,a2,#a2,out); \
85 if (!result) success = false; \
86 }
87
88#define TEST_THROW( code, ExceptType ) \
89 TEUCHOS_TEST_THROW( code, ExceptType, out, success )
90
91#define TEST_NOTHROW( code ) \
92 TEUCHOS_TEST_NOTHROW( code, out, success )
93
94
95//
96// Main templated array test function
97//
98
99
100template<class T>
101bool testArrayView( const int n, Teuchos::FancyOStream &out )
102{
103
104 using Teuchos::ArrayView;
105 using Teuchos::arrayView;
106 using Teuchos::arrayViewFromVector;
107 using Teuchos::outArg;
110 using Teuchos::getConst;
111 using Teuchos::as;
112 typedef typename ArrayView<T>::size_type size_type;
113 // mfh 03 Apr 2014: The point of the above line of code is to ensure
114 // that ArrayView<T> has a public size_type typedef. However, the
115 // above line of code in isolation causes some compilers to warn
116 // about a declared but unused typedef. We deal with this by
117 // declaring a variable (actually, the oxymoron "const variable") of
118 // type size_type, then using the "cast to void" trick to forestall
119 // compiler warnings for the declared but unused variable. (Fun
120 // fact: "oxymoron" means "sharp dull" and is itself an oxymoron.)
121 // The "cast to void" trick doesn't always work, but if it doesn't,
122 // it's easy to make it go away by printing it to the output stream
123 // 'out'.
124 const size_type arbitrarySizeTypeValue = 0;
125 (void) arbitrarySizeTypeValue;
126
127 bool success = true;
128
129 out
130 << "\n***"
131 << "\n*** Testing "<<TypeNameTraits<ArrayView<T> >::name()<<" of size = "<<n
132 << "\n***\n";
133
134 Teuchos::OSTab tab(out);
135
136 //
137 out << "\nA) Initial setup testing ...\n\n";
138 //
139
140 {
141 out << "\nTesting basic null construction!\n\n";
142 ArrayView<T> av2 = Teuchos::null;
143 TEST_EQUALITY_CONST(is_null(av2),true);
144 TEST_EQUALITY_CONST(av2.size(),0);
145 TEST_EQUALITY_CONST(av2.getRawPtr(),0);
146 TEST_EQUALITY_CONST(av2.getRawPtr(),av2.data());
147 TEST_ITER_EQUALITY(av2.begin(),av2.end());
148#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
152 TEST_THROW(av2.assign(av2), Teuchos::NullReferenceError);
155#endif
156 ArrayView<const T> cav2(av2); // Tests copy constructor and implicit conversion operator!
157 TEST_EQUALITY_CONST(cav2.size(),0);
158 TEST_EQUALITY_CONST(cav2.getRawPtr(),0);
159 TEST_EQUALITY_CONST(cav2.getRawPtr(),cav2.data());
160 TEST_ITER_EQUALITY(cav2.begin(),av2.end());
161#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
166#endif
167#ifdef SHOW_INVALID_CONST_ASSIGN
168 TEST_NOTHROW(cav2.assign(av2)); // Should not compile!
169#endif
170 }
171
172 std::vector<T> v(n);
173
174 const ArrayView<T> av = arrayViewFromVector(v);
175 TEST_EQUALITY_CONST(is_null(av), false);
176 TEST_EQUALITY( as<int>(av.size()), n );
177
178 const ArrayView<const T> cav = av;
179
180 {
181 out << "\nInitializing data for std::vector v through view av ...\n";
182 for( int i = 0; i < n; ++i )
183 av[i] = i; // tests non-const operator[](i)
184 }
185
186 {
187 out << "\nTest that v[i] == i through ArrayView<const T> ...\n";
188 const ArrayView<const T> cav2 = cav;
189 bool local_success = true;
190 for( int i = 0; i < n; ++i ) {
191 TEST_ARRAY_ELE_EQUALITY( cav2, i, as<T>(i) );
192 }
193 if (local_success) out << "passed\n";
194 else success = false;
195 }
196
197 {
198 out << "\nTest explicit copy to std::vector from non-const array view ...\n";
199 std::vector<T> v2 = Teuchos::createVector(av);
200 TEST_COMPARE_ARRAYS( v2, v );
201 }
202
203 {
204 out << "\nTest explicit copy to std::vector from const array view ...\n";
205 std::vector<T> v2 = Teuchos::createVector(cav);
206 TEST_COMPARE_ARRAYS( v2, v );
207 }
208
209 {
210 out << "\nTest shallow implicit conversion from ArrayView<T> to ArrayView<T> ...\n";
211 ArrayView<T> av2(av);
212 TEST_COMPARE_ARRAYS( av2, av );
213 }
214
215 {
216 out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<const T> ...\n";
217 ArrayView<const T> cav2(cav);
218 TEST_COMPARE_ARRAYS( cav2, cav );
219 }
220
221 {
222 out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<T> ...\n";
223 ArrayView<const T> cav2(av);
224 TEST_COMPARE_ARRAYS( cav2, av );
225 }
226
227 {
228 out << "\nTest shallow implicit conversion from std::vector<T> to ArrayView<T> ...\n";
229 std::vector<T> v2 = Teuchos::createVector(cav);
230 ArrayView<T> cav2(v2);
231 TEST_COMPARE_ARRAYS( cav2, av );
232 }
233
234 {
235 out << "\nTest shallow implicit conversion from const std::vector<T> to ArrayView<const T> ...\n";
236 const std::vector<T> v2 = Teuchos::createVector(cav);
237 ArrayView<const T> cav2(v2);
238 TEST_COMPARE_ARRAYS( cav2, av );
239 }
240
241 {
242 // Try to copy construct from ArrayView<const T> to ArrayView<T> ..
243#ifdef SHOW_INVALID_COPY_CONSTRUCTION
244 ArrayView<T> cav2(cav); // should not compile!
245#endif
246 }
247
248 {
249 out << "\ntest assign(...) ...\n";
250 std::vector<T> v2(n);
251 ArrayView<T> av2(v2);
252 av2.assign(av);
253 TEST_COMPARE_ARRAYS( v2, v );
254 }
255
256 //
257 out << "\nB) Test element access ...\n";
258 //
259
260
261 TEST_EQUALITY_CONST( av.front(), as<T>(0) );
262 TEST_EQUALITY( av.back(), as<T>(n-1) );
263 TEST_EQUALITY_CONST( cav.front(), as<T>(0) );
264 TEST_EQUALITY( cav.back(), as<T>(n-1) );
265#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
270#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
271
272 //
273 out << "\nC) Test iterator access ...\n";
274 //
275
276
277 {
278 out << "\nTest non-const forward iterator access ...\n";
279 std::vector<T> v2(n);
280 ArrayView<T> av2(v2);
281 typedef typename ArrayView<T>::iterator iter_t;
282 iter_t iter = av2.begin();
283 for ( int i = 0; iter != av2.end(); ++i )
284 *iter++ = i;
285 TEST_COMPARE_ARRAYS( v2, v );
286 }
287
288 {
289 out << "\nTest const forward iterator access ... ";
290 bool local_success = true;
291 typedef typename ArrayView<const T>::iterator iter_t;
292 const ArrayView<const T> cav2 = av.getConst();
293 iter_t iter = cav2.begin();
294 for ( int i = 0; i < n; ++i, ++iter ) {
295 TEST_ARRAY_ELE_EQUALITY( av, i, *iter );
296
297#ifdef SHOW_INVALID_CONST_ITER_MODIFICATION
298 *iter = as<T>(i); // Should not compile!
299#endif
300 }
301 iter = NullIteratorTraits<iter_t>::getNull();
302 if (local_success) out << "passed\n";
303 else success = false;
304 }
305
306 //
307 out << "\nD) Test sub-views ...\n";
308 //
309
310 {
311 out << "\nTest full non-const subview ...\n";
312 const ArrayView<T> av2 = av(0,n);
313 TEST_COMPARE_ARRAYS( av2, av );
314 }
315
316 {
317 out << "\nTest full shorthand non-const subview ...\n";
318 const ArrayView<T> av2 = av();
319 TEST_COMPARE_ARRAYS( av2, av );
320 }
321
322 {
323 out << "\nTest full const subview ...\n";
324 const ArrayView<const T> cav2 = cav(0,n);
325 TEST_COMPARE_ARRAYS( cav2, cav );
326 }
327
328 {
329 out << "\nTest full non-const to const subview ...\n";
330 const ArrayView<const T> cav2 = av(0,n);
331 TEST_COMPARE_ARRAYS( cav2, cav );
332 }
333
334 {
335 out << "\nTest full short-hand const subview ...\n";
336 const ArrayView<const T> cav2 = cav();
337 TEST_COMPARE_ARRAYS( cav2, cav );
338 }
339
340 {
341 out << "\nTest non-const initial range view ...\n";
342 std::vector<T> v2(n,as<T>(-1));
343 const ArrayView<T> av2(v2);
344 const ArrayView<T> av2_init = av2(0,n-1);
345 TEST_EQUALITY( av2_init.size(), n-1 );
346 av2_init.assign( av(0,n-1) );
347 av2.back() = as<T>(n-1);
348 TEST_COMPARE_ARRAYS( v2, v );
349 }
350
351 {
352 out << "\nTest non-const final range view ...\n";
353 std::vector<T> v2(n,as<T>(-1));
354 const ArrayView<T> av2(v2);
355 const ArrayView<T> av2_init = av2(1,n-1);
356 TEST_EQUALITY( av2_init.size(), n-1 );
357 av2_init.assign( av(1,n-1) );
358 av2.front() = as<T>(0);
359 TEST_COMPARE_ARRAYS( v2, v );
360 }
361
362 {
363 out << "\nTest non-const middle range view ...\n";
364 std::vector<T> v2(n,as<T>(-1));
365 const ArrayView<T> av2(v2);
366 const ArrayView<T> av2_init = av2(1,n-2);
367 TEST_EQUALITY( av2_init.size(), n-2 );
368 av2_init.assign( av(1,n-2) );
369 av2.front() = as<T>(0);
370 av2.back() = as<T>(n-1);
371 TEST_COMPARE_ARRAYS( v2, v );
372 }
373
374 // ToDo: Test requesting views outside of valid range!
375
376 return success;
377
378}
379
380
381//
382// Main testing program
383//
384
385int main( int argc, char* argv[] )
386{
387
388 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
389
391
392 bool success = true;
393 bool result;
394
397
398 try {
399
400 //
401 // Read options from the commandline
402 //
403
404 CommandLineProcessor clp(false); // Don't throw exceptions
405
406 int n = 4;
407 clp.setOption( "n", &n, "Number of elements in the array" );
408
409 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
410
411 if ( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
412 *out << "\nEnd Result: TEST FAILED" << std::endl;
413 return parse_return;
414 }
415
416 *out << std::endl << Teuchos::Teuchos_Version() << std::endl;
417
418 result = testArrayView<int>(n,*out);
419 if (!result) success = false;
420
421 result = testArrayView<float>(n,*out);
422 if (!result) success = false;
423
424 result = testArrayView<double>(n,*out);
425 if (!result) success = false;
426
427 result = testArrayView<std::complex<double> >(n,*out);
428 if (!result) success = false;
429
430 }
431 TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
432
433 if (success)
434 *out << "\nEnd Result: TEST PASSED" << std::endl;
435 else
436 *out << "\nEnd Result: TEST FAILED" << std::endl;
437
438 return ( success ? 0 : 1 );
439
440}
#define TEST_EQUALITY_CONST(v1, v2)
#define TEST_EQUALITY(v1, v2)
bool testArrayView(const int n, Teuchos::FancyOStream &out)
#define TEST_NOTHROW(code)
#define TEST_ARRAY_ELE_EQUALITY(a, i, val)
#define TEST_THROW(code, ExceptType)
#define TEST_COMPARE_ARRAYS(a1, a2)
#define TEST_ITER_EQUALITY(iter1, iter2)
Basic command line parser for input from (argc,argv[])
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
Utilities to make writing tests easier.
Definition of Teuchos::as, for conversions between types.
Nonowning array view.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
Initialize, finalize, and query the global MPI session.
Base traits class for getting a properly initialized null pointer.
Null reference error exception class.
Range error exception class.
Concrete serial communicator subclass.
Default traits class that just returns typeid(T).name().
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
int main()
Definition evilMain.cpp:75
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
std::string Teuchos_Version()