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.
Smart reference counting pointer class for automatic garbage collection.
Range error exception class.
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 ...
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object.
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()