Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
100 template<class T>
101 bool 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
163  TEST_THROW(*cav2.begin(), Teuchos::NullReferenceError);
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
266  TEST_THROW( av[-1], Teuchos::RangeError );
268  TEST_THROW( cav[-1], Teuchos::RangeError );
269  TEST_THROW( cav[n], Teuchos::RangeError );
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 
385 int 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_NOTHROW(code)
Null reference error exception class.
#define TEST_EQUALITY_CONST(v1, v2)
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
ArrayView< T > arrayViewFromVector(std::vector< T > &vec)
Construct a non-const view of an std::vector.
#define TEST_ITER_EQUALITY(iter1, iter2)
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object...
Initialize, finalize, and query the global MPI session.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
#define TEST_COMPARE_ARRAYS(a1, a2)
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
std::string Teuchos_Version()
Base traits class for getting a properly initialized null pointer.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
int main(int argc, char *argv[])
bool testArrayView(const int n, Teuchos::FancyOStream &out)
Utilities to make writing tests easier.
Nonowning array view.
Default traits class that just returns typeid(T).name().
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Basic command line parser for input from (argc,argv[])
#define TEST_THROW(code, ExceptType)
Smart reference counting pointer class for automatic garbage collection.
#define TEST_ARRAY_ELE_EQUALITY(a, i, val)
#define TEST_EQUALITY(v1, v2)
Range error exception class.
RCP< basic_FancyOStream< CharT, Traits > > tab(const RCP< basic_FancyOStream< CharT, Traits > > &out, const int tabs=1, const std::basic_string< CharT, Traits > linePrefix="")
Create a tab for an RCP-wrapped basic_FancyOStream object to cause the indentation of all output auto...
Definition of Teuchos::as, for conversions between types.
Class that helps parse command line input arguments from (argc,argv[]) and set options.