ArrayView_test.cpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Teuchos_ArrayView.hpp"
00030 #include "Teuchos_CommandLineProcessor.hpp"
00031 #include "Teuchos_GlobalMPISession.hpp"
00032 #include "Teuchos_VerboseObject.hpp"
00033 #include "Teuchos_StandardCatchMacros.hpp"
00034 #include "Teuchos_Version.hpp"
00035 #include "Teuchos_getConst.hpp"
00036 #include "Teuchos_as.hpp"
00037 #include "Teuchos_TestingHelpers.hpp"
00038 
00039 
00040 // Uncomment to show compile errors from invalid usage
00041 //#define SHOW_INVALID_COPY_CONSTRUCTION
00042 //#define SHOW_INVALID_CONST_ASSIGN
00043 //#define SHOW_INVALID_CONST_ITER_MODIFICATION
00044 
00045 //
00046 // Define local macros to make defining tests easier for this particular test
00047 // code.
00048 //
00049 // Note, macros with these types of names should only exist in a *.cpp file
00050 // after all #includes are done!
00051 //
00052 
00053 
00054 #define TEST_EQUALITY_CONST( v1, v2 ) \
00055   TEUCHOS_TEST_EQUALITY_CONST( v1, v2, out, success )
00056 
00057 #define TEST_EQUALITY( v1, v2 ) \
00058   TEUCHOS_TEST_EQUALITY( v1, v2, out, success )
00059 
00060 #define TEST_ITER_EQUALITY( iter1, iter2 ) \
00061   TEUCHOS_TEST_ITER_EQUALITY( iter1, iter2, out, success )
00062 
00063 #define TEST_ARRAY_ELE_EQUALITY( a, i, val ) \
00064    TEUCHOS_TEST_ARRAY_ELE_EQUALITY( a, i, val, false, out, local_success )
00065 
00066 #define TEST_COMPARE( v1, comp, v2 ) \
00067   TEUCHOS_TEST_COMPARE( v1, comp, v2, out, success )
00068 
00069 #define TEST_COMPARE_ARRAYS( a1, a2 ) \
00070   { \
00071     const bool result = compareArrays(a1,#a1,a2,#a2,out); \
00072     if (!result) success = false; \
00073   }
00074 
00075 #define TEST_THROW( code, ExceptType  ) \
00076   TEUCHOS_TEST_THROW( code, ExceptType, out, success  )
00077 
00078 #define TEST_NOTHROW( code  ) \
00079   TEUCHOS_TEST_NOTHROW( code, out, success  )
00080 
00081 
00082 //
00083 // Main templated array test function
00084 //
00085 
00086 
00087 template<class T>
00088 bool testArrayView( const int n, Teuchos::FancyOStream &out )
00089 {
00090   
00091   using Teuchos::ArrayView;
00092   using Teuchos::arrayView;
00093   using Teuchos::arrayViewFromVector;
00094   using Teuchos::outArg;
00095   using Teuchos::NullIteratorTraits;
00096   using Teuchos::TypeNameTraits;
00097   using Teuchos::getConst;
00098   using Teuchos::as;
00099   typedef typename ArrayView<T>::size_type size_type;
00100 
00101   bool success = true;
00102  
00103   out
00104     << "\n***"
00105     << "\n*** Testing "<<TypeNameTraits<ArrayView<T> >::name()<<" of size = "<<n
00106     << "\n***\n";
00107   
00108   Teuchos::OSTab tab(out);
00109 
00110   //
00111   out << "\nA) Initial setup testing ...\n\n";
00112   //
00113   
00114   {
00115     out << "\nTesting basic null construction!\n\n";
00116     ArrayView<T> av2 = Teuchos::null;
00117     TEST_EQUALITY_CONST(is_null(av2),true);
00118     TEST_EQUALITY_CONST(av2.size(),0);
00119     TEST_EQUALITY_CONST(av2.getRawPtr(),0);
00120     TEST_ITER_EQUALITY(av2.begin(),av2.end());
00121 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00122     TEST_THROW(av2[0],Teuchos::NullReferenceError);
00123     TEST_THROW(*av2.begin(), Teuchos::NullReferenceError);
00124     TEST_THROW(*av2.end(), Teuchos::NullReferenceError);
00125     TEST_THROW(av2.assign(av2), Teuchos::NullReferenceError);
00126     TEST_THROW(av2.front(), Teuchos::NullReferenceError);
00127     TEST_THROW(av2.back(), Teuchos::NullReferenceError);
00128 #endif
00129     ArrayView<const T> cav2(av2); // Tests copy constructor and implicit conversion operator! 
00130     TEST_EQUALITY_CONST(cav2.size(),0);
00131     TEST_EQUALITY_CONST(cav2.getRawPtr(),0);
00132     TEST_ITER_EQUALITY(cav2.begin(),av2.end());
00133 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00134     TEST_THROW(cav2[0],Teuchos::NullReferenceError);
00135     TEST_THROW(*cav2.begin(), Teuchos::NullReferenceError);
00136     TEST_THROW(*cav2.end(), Teuchos::NullReferenceError);
00137     TEST_THROW(cav2.back(), Teuchos::NullReferenceError);
00138 #endif
00139 #ifdef SHOW_INVALID_CONST_ASSIGN
00140     TEST_NOTHROW(cav2.assign(av2)); // Should not compile!
00141 #endif
00142   }
00143 
00144   std::vector<T> v(n);
00145 
00146   const ArrayView<T> av = arrayViewFromVector(v);
00147   TEST_EQUALITY_CONST(is_null(av), false);
00148   TEST_EQUALITY( as<int>(av.size()), n );
00149 
00150   const ArrayView<const T> cav = av;
00151  
00152   {
00153     out << "\nInitializing data for std::vector v through view av ...\n";
00154     for( int i = 0; i < n; ++i )
00155       av[i] = i; // tests non-const operator[](i)
00156   }
00157 
00158   {
00159     out << "\nTest that v[i] == i through ArrayView<const T> ...\n";
00160     const ArrayView<const T> cav2 = cav;
00161     bool local_success = true;
00162     for( int i = 0; i < n; ++i ) {
00163       TEST_ARRAY_ELE_EQUALITY( cav2, i, as<T>(i) );
00164     }
00165     if (local_success) out << "passed\n";
00166     else success = false;
00167   }
00168 
00169   {
00170     out << "\nTest explicit copy to std::vector from non-const array view ...\n";
00171     std::vector<T> v2 = Teuchos::createVector(av);
00172     TEST_COMPARE_ARRAYS( v2, v );
00173   }
00174 
00175   {
00176     out << "\nTest explicit copy to std::vector from const array view ...\n";
00177     std::vector<T> v2 = Teuchos::createVector(cav);
00178     TEST_COMPARE_ARRAYS( v2, v );
00179   }
00180 
00181   {
00182     out << "\nTest shallow implicit conversion from ArrayView<T> to ArrayView<T> ...\n";
00183     ArrayView<T> av2(av);
00184     TEST_COMPARE_ARRAYS( av2, av );
00185   }
00186 
00187   {
00188     out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<const T> ...\n";
00189     ArrayView<const T> cav2(cav);
00190     TEST_COMPARE_ARRAYS( cav2, cav );
00191   }
00192 
00193   {
00194     out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<T> ...\n";
00195     ArrayView<const T> cav2(av);
00196     TEST_COMPARE_ARRAYS( cav2, av );
00197   }
00198 
00199   {
00200     out << "\nTest shallow implicit conversion from std::vector<T> to ArrayView<T> ...\n";
00201     std::vector<T> v2 = Teuchos::createVector(cav);
00202     ArrayView<T> cav2(v2);
00203     TEST_COMPARE_ARRAYS( cav2, av );
00204   }
00205 
00206   {
00207     out << "\nTest shallow implicit conversion from const std::vector<T> to ArrayView<const T> ...\n";
00208     const std::vector<T> v2 = Teuchos::createVector(cav);
00209     ArrayView<const T> cav2(v2);
00210     TEST_COMPARE_ARRAYS( cav2, av );
00211   }
00212 
00213   {
00214     // Try to copy construct from ArrayView<const T> to ArrayView<T> ..
00215 #ifdef SHOW_INVALID_COPY_CONSTRUCTION
00216     ArrayView<T> cav2(cav); // should not compile!
00217 #endif
00218   }
00219 
00220   {
00221     out << "\ntest assign(...) ...\n";
00222     std::vector<T> v2(n);
00223     ArrayView<T> av2(v2);
00224     av2.assign(av);
00225     TEST_COMPARE_ARRAYS( v2, v );
00226   }
00227 
00228   //
00229   out << "\nB) Test element access ...\n";
00230   //
00231 
00232 
00233   TEST_EQUALITY_CONST( av.front(), as<T>(0) );
00234   TEST_EQUALITY( av.back(), as<T>(n-1) );
00235   TEST_EQUALITY_CONST( cav.front(), as<T>(0) );
00236   TEST_EQUALITY( cav.back(), as<T>(n-1) );
00237 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00238   TEST_THROW( av[-1], Teuchos::RangeError );
00239   TEST_THROW( av[n], Teuchos::RangeError );
00240   TEST_THROW( cav[-1], Teuchos::RangeError );
00241   TEST_THROW( cav[n], Teuchos::RangeError );
00242 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00243 
00244   //
00245   out << "\nC) Test iterator access ...\n";
00246   //
00247 
00248 
00249   {
00250     out << "\nTest non-const forward iterator access ...\n";
00251     std::vector<T> v2(n);
00252     ArrayView<T> av2(v2);
00253     typedef typename ArrayView<T>::iterator iter_t;
00254     iter_t iter = av2.begin();
00255     for ( int i = 0; iter != av2.end(); ++i )
00256       *iter++ = i;
00257     TEST_COMPARE_ARRAYS( v2, v );
00258   }
00259 
00260   {
00261     out << "\nTest const forward iterator access ... ";
00262     bool local_success = true;
00263     typedef typename ArrayView<const T>::iterator iter_t;
00264     const ArrayView<const T> cav2 = av.getConst();
00265     iter_t iter = cav2.begin();
00266     for ( int i = 0; i < n; ++i, ++iter ) {
00267       TEST_ARRAY_ELE_EQUALITY( av, i, *iter );
00268 
00269 #ifdef SHOW_INVALID_CONST_ITER_MODIFICATION
00270       *iter = as<T>(i); // Should not compile!
00271 #endif
00272     }
00273     iter = NullIteratorTraits<iter_t>::getNull();
00274     if (local_success) out << "passed\n";
00275     else success = false;
00276   }
00277 
00278   //
00279   out << "\nD) Test sub-views ...\n";
00280   //
00281 
00282   {
00283     out << "\nTest full non-const subview ...\n";
00284     const ArrayView<T> av2 = av(0,n);
00285     TEST_COMPARE_ARRAYS( av2, av );
00286   }
00287 
00288   {
00289     out << "\nTest full shorthand non-const subview ...\n";
00290     const ArrayView<T> av2 = av();
00291     TEST_COMPARE_ARRAYS( av2, av );
00292   }
00293 
00294   {
00295     out << "\nTest full const subview ...\n";
00296     const ArrayView<const T> cav2 = cav(0,n);
00297     TEST_COMPARE_ARRAYS( cav2, cav );
00298   }
00299 
00300   {
00301     out << "\nTest full non-const to const subview ...\n";
00302     const ArrayView<const T> cav2 = av(0,n);
00303     TEST_COMPARE_ARRAYS( cav2, cav );
00304   }
00305 
00306   {
00307     out << "\nTest full short-hand const subview ...\n";
00308     const ArrayView<const T> cav2 = cav();
00309     TEST_COMPARE_ARRAYS( cav2, cav );
00310   }
00311 
00312   {
00313     out << "\nTest non-const initial range view ...\n";
00314     std::vector<T> v2(n,as<T>(-1));
00315     const ArrayView<T> av2(v2);
00316     const ArrayView<T> av2_init = av2(0,n-1);
00317     TEST_EQUALITY( av2_init.size(), n-1 );
00318     av2_init.assign( av(0,n-1) );
00319     av2.back() = as<T>(n-1);
00320     TEST_COMPARE_ARRAYS( v2, v );
00321   }
00322 
00323   {
00324     out << "\nTest non-const final range view ...\n";
00325     std::vector<T> v2(n,as<T>(-1));
00326     const ArrayView<T> av2(v2);
00327     const ArrayView<T> av2_init = av2(1,n-1);
00328     TEST_EQUALITY( av2_init.size(), n-1 );
00329     av2_init.assign( av(1,n-1) );
00330     av2.front() = as<T>(0);
00331     TEST_COMPARE_ARRAYS( v2, v );
00332   }
00333 
00334   {
00335     out << "\nTest non-const middle range view ...\n";
00336     std::vector<T> v2(n,as<T>(-1));
00337     const ArrayView<T> av2(v2);
00338     const ArrayView<T> av2_init = av2(1,n-2);
00339     TEST_EQUALITY( av2_init.size(), n-2 );
00340     av2_init.assign( av(1,n-2) );
00341     av2.front() = as<T>(0);
00342     av2.back() = as<T>(n-1);
00343     TEST_COMPARE_ARRAYS( v2, v );
00344   }
00345 
00346   // ToDo: Test requesting views outside of valid range!
00347 
00348   return success;
00349 
00350 }
00351 
00352 
00353 //
00354 // Main testing program
00355 //
00356 
00357 int main( int argc, char* argv[] )
00358 {
00359 
00360   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
00361 
00362   using Teuchos::CommandLineProcessor;
00363   
00364   bool success = true;
00365   bool result;
00366  
00367   Teuchos::RCP<Teuchos::FancyOStream>
00368     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00369  
00370   try {
00371     
00372     //
00373     // Read options from the commandline
00374     //
00375 
00376     CommandLineProcessor clp(false); // Don't throw exceptions
00377 
00378     int n = 4;
00379     clp.setOption( "n", &n, "Number of elements in the array" );
00380 
00381     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00382 
00383     if ( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00384       *out << "\nEnd Result: TEST FAILED" << std::endl;
00385       return parse_return;
00386     }
00387 
00388     *out << std::endl << Teuchos::Teuchos_Version() << std::endl;
00389  
00390     result = testArrayView<int>(n,*out);
00391     if (!result) success = false;
00392 
00393     result = testArrayView<float>(n,*out);
00394     if (!result) success = false;
00395 
00396     result = testArrayView<double>(n,*out);
00397     if (!result) success = false;
00398 
00399     result = testArrayView<std::complex<double> >(n,*out);
00400     if (!result) success = false;
00401  
00402   }
00403   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00404  
00405   if (success)
00406     *out << "\nEnd Result: TEST PASSED" << std::endl;
00407   else
00408     *out << "\nEnd Result: TEST FAILED" << std::endl;
00409  
00410   return ( success ? 0 : 1 );
00411  
00412 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:28 2011 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.3