Teuchos Package Browser (Single Doxygen Collection) Version of the Day
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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_ArrayView.hpp"
00043 #include "Teuchos_CommandLineProcessor.hpp"
00044 #include "Teuchos_GlobalMPISession.hpp"
00045 #include "Teuchos_VerboseObject.hpp"
00046 #include "Teuchos_StandardCatchMacros.hpp"
00047 #include "Teuchos_Version.hpp"
00048 #include "Teuchos_getConst.hpp"
00049 #include "Teuchos_as.hpp"
00050 #include "Teuchos_TestingHelpers.hpp"
00051 
00052 
00053 // Uncomment to show compile errors from invalid usage
00054 //#define SHOW_INVALID_COPY_CONSTRUCTION
00055 //#define SHOW_INVALID_CONST_ASSIGN
00056 //#define SHOW_INVALID_CONST_ITER_MODIFICATION
00057 
00058 //
00059 // Define local macros to make defining tests easier for this particular test
00060 // code.
00061 //
00062 // Note, macros with these types of names should only exist in a *.cpp file
00063 // after all #includes are done!
00064 //
00065 
00066 
00067 #define TEST_EQUALITY_CONST( v1, v2 ) \
00068   TEUCHOS_TEST_EQUALITY_CONST( v1, v2, out, success )
00069 
00070 #define TEST_EQUALITY( v1, v2 ) \
00071   TEUCHOS_TEST_EQUALITY( v1, v2, out, success )
00072 
00073 #define TEST_ITER_EQUALITY( iter1, iter2 ) \
00074   TEUCHOS_TEST_ITER_EQUALITY( iter1, iter2, out, success )
00075 
00076 #define TEST_ARRAY_ELE_EQUALITY( a, i, val ) \
00077    TEUCHOS_TEST_ARRAY_ELE_EQUALITY( a, i, val, false, out, local_success )
00078 
00079 #define TEST_COMPARE( v1, comp, v2 ) \
00080   TEUCHOS_TEST_COMPARE( v1, comp, v2, out, success )
00081 
00082 #define TEST_COMPARE_ARRAYS( a1, a2 ) \
00083   { \
00084     const bool result = compareArrays(a1,#a1,a2,#a2,out); \
00085     if (!result) success = false; \
00086   }
00087 
00088 #define TEST_THROW( code, ExceptType  ) \
00089   TEUCHOS_TEST_THROW( code, ExceptType, out, success  )
00090 
00091 #define TEST_NOTHROW( code  ) \
00092   TEUCHOS_TEST_NOTHROW( code, out, success  )
00093 
00094 
00095 //
00096 // Main templated array test function
00097 //
00098 
00099 
00100 template<class T>
00101 bool testArrayView( const int n, Teuchos::FancyOStream &out )
00102 {
00103 
00104   using Teuchos::ArrayView;
00105   using Teuchos::arrayView;
00106   using Teuchos::arrayViewFromVector;
00107   using Teuchos::outArg;
00108   using Teuchos::NullIteratorTraits;
00109   using Teuchos::TypeNameTraits;
00110   using Teuchos::getConst;
00111   using Teuchos::as;
00112   typedef typename ArrayView<T>::size_type size_type;
00113   // mfh 03 Apr 2014: The point of the above line of code is to ensure
00114   // that ArrayView<T> has a public size_type typedef.  However, the
00115   // above line of code in isolation causes some compilers to warn
00116   // about a declared but unused typedef.  We deal with this by
00117   // declaring a variable (actually, the oxymoron "const variable") of
00118   // type size_type, then using the "cast to void" trick to forestall
00119   // compiler warnings for the declared but unused variable.  (Fun
00120   // fact: "oxymoron" means "sharp dull" and is itself an oxymoron.)
00121   // The "cast to void" trick doesn't always work, but if it doesn't,
00122   // it's easy to make it go away by printing it to the output stream
00123   // 'out'.
00124   const size_type arbitrarySizeTypeValue = 0;
00125   (void) arbitrarySizeTypeValue;
00126 
00127   bool success = true;
00128 
00129   out
00130     << "\n***"
00131     << "\n*** Testing "<<TypeNameTraits<ArrayView<T> >::name()<<" of size = "<<n
00132     << "\n***\n";
00133 
00134   Teuchos::OSTab tab(out);
00135 
00136   //
00137   out << "\nA) Initial setup testing ...\n\n";
00138   //
00139 
00140   {
00141     out << "\nTesting basic null construction!\n\n";
00142     ArrayView<T> av2 = Teuchos::null;
00143     TEST_EQUALITY_CONST(is_null(av2),true);
00144     TEST_EQUALITY_CONST(av2.size(),0);
00145     TEST_EQUALITY_CONST(av2.getRawPtr(),0);
00146     TEST_ITER_EQUALITY(av2.begin(),av2.end());
00147 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00148     TEST_THROW(av2[0],Teuchos::NullReferenceError);
00149     TEST_THROW(*av2.begin(), Teuchos::NullReferenceError);
00150     TEST_THROW(*av2.end(), Teuchos::NullReferenceError);
00151     TEST_THROW(av2.assign(av2), Teuchos::NullReferenceError);
00152     TEST_THROW(av2.front(), Teuchos::NullReferenceError);
00153     TEST_THROW(av2.back(), Teuchos::NullReferenceError);
00154 #endif
00155     ArrayView<const T> cav2(av2); // Tests copy constructor and implicit conversion operator!
00156     TEST_EQUALITY_CONST(cav2.size(),0);
00157     TEST_EQUALITY_CONST(cav2.getRawPtr(),0);
00158     TEST_ITER_EQUALITY(cav2.begin(),av2.end());
00159 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00160     TEST_THROW(cav2[0],Teuchos::NullReferenceError);
00161     TEST_THROW(*cav2.begin(), Teuchos::NullReferenceError);
00162     TEST_THROW(*cav2.end(), Teuchos::NullReferenceError);
00163     TEST_THROW(cav2.back(), Teuchos::NullReferenceError);
00164 #endif
00165 #ifdef SHOW_INVALID_CONST_ASSIGN
00166     TEST_NOTHROW(cav2.assign(av2)); // Should not compile!
00167 #endif
00168   }
00169 
00170   std::vector<T> v(n);
00171 
00172   const ArrayView<T> av = arrayViewFromVector(v);
00173   TEST_EQUALITY_CONST(is_null(av), false);
00174   TEST_EQUALITY( as<int>(av.size()), n );
00175 
00176   const ArrayView<const T> cav = av;
00177 
00178   {
00179     out << "\nInitializing data for std::vector v through view av ...\n";
00180     for( int i = 0; i < n; ++i )
00181       av[i] = i; // tests non-const operator[](i)
00182   }
00183 
00184   {
00185     out << "\nTest that v[i] == i through ArrayView<const T> ...\n";
00186     const ArrayView<const T> cav2 = cav;
00187     bool local_success = true;
00188     for( int i = 0; i < n; ++i ) {
00189       TEST_ARRAY_ELE_EQUALITY( cav2, i, as<T>(i) );
00190     }
00191     if (local_success) out << "passed\n";
00192     else success = false;
00193   }
00194 
00195   {
00196     out << "\nTest explicit copy to std::vector from non-const array view ...\n";
00197     std::vector<T> v2 = Teuchos::createVector(av);
00198     TEST_COMPARE_ARRAYS( v2, v );
00199   }
00200 
00201   {
00202     out << "\nTest explicit copy to std::vector from const array view ...\n";
00203     std::vector<T> v2 = Teuchos::createVector(cav);
00204     TEST_COMPARE_ARRAYS( v2, v );
00205   }
00206 
00207   {
00208     out << "\nTest shallow implicit conversion from ArrayView<T> to ArrayView<T> ...\n";
00209     ArrayView<T> av2(av);
00210     TEST_COMPARE_ARRAYS( av2, av );
00211   }
00212 
00213   {
00214     out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<const T> ...\n";
00215     ArrayView<const T> cav2(cav);
00216     TEST_COMPARE_ARRAYS( cav2, cav );
00217   }
00218 
00219   {
00220     out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<T> ...\n";
00221     ArrayView<const T> cav2(av);
00222     TEST_COMPARE_ARRAYS( cav2, av );
00223   }
00224 
00225   {
00226     out << "\nTest shallow implicit conversion from std::vector<T> to ArrayView<T> ...\n";
00227     std::vector<T> v2 = Teuchos::createVector(cav);
00228     ArrayView<T> cav2(v2);
00229     TEST_COMPARE_ARRAYS( cav2, av );
00230   }
00231 
00232   {
00233     out << "\nTest shallow implicit conversion from const std::vector<T> to ArrayView<const T> ...\n";
00234     const std::vector<T> v2 = Teuchos::createVector(cav);
00235     ArrayView<const T> cav2(v2);
00236     TEST_COMPARE_ARRAYS( cav2, av );
00237   }
00238 
00239   {
00240     // Try to copy construct from ArrayView<const T> to ArrayView<T> ..
00241 #ifdef SHOW_INVALID_COPY_CONSTRUCTION
00242     ArrayView<T> cav2(cav); // should not compile!
00243 #endif
00244   }
00245 
00246   {
00247     out << "\ntest assign(...) ...\n";
00248     std::vector<T> v2(n);
00249     ArrayView<T> av2(v2);
00250     av2.assign(av);
00251     TEST_COMPARE_ARRAYS( v2, v );
00252   }
00253 
00254   //
00255   out << "\nB) Test element access ...\n";
00256   //
00257 
00258 
00259   TEST_EQUALITY_CONST( av.front(), as<T>(0) );
00260   TEST_EQUALITY( av.back(), as<T>(n-1) );
00261   TEST_EQUALITY_CONST( cav.front(), as<T>(0) );
00262   TEST_EQUALITY( cav.back(), as<T>(n-1) );
00263 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00264   TEST_THROW( av[-1], Teuchos::RangeError );
00265   TEST_THROW( av[n], Teuchos::RangeError );
00266   TEST_THROW( cav[-1], Teuchos::RangeError );
00267   TEST_THROW( cav[n], Teuchos::RangeError );
00268 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00269 
00270   //
00271   out << "\nC) Test iterator access ...\n";
00272   //
00273 
00274 
00275   {
00276     out << "\nTest non-const forward iterator access ...\n";
00277     std::vector<T> v2(n);
00278     ArrayView<T> av2(v2);
00279     typedef typename ArrayView<T>::iterator iter_t;
00280     iter_t iter = av2.begin();
00281     for ( int i = 0; iter != av2.end(); ++i )
00282       *iter++ = i;
00283     TEST_COMPARE_ARRAYS( v2, v );
00284   }
00285 
00286   {
00287     out << "\nTest const forward iterator access ... ";
00288     bool local_success = true;
00289     typedef typename ArrayView<const T>::iterator iter_t;
00290     const ArrayView<const T> cav2 = av.getConst();
00291     iter_t iter = cav2.begin();
00292     for ( int i = 0; i < n; ++i, ++iter ) {
00293       TEST_ARRAY_ELE_EQUALITY( av, i, *iter );
00294 
00295 #ifdef SHOW_INVALID_CONST_ITER_MODIFICATION
00296       *iter = as<T>(i); // Should not compile!
00297 #endif
00298     }
00299     iter = NullIteratorTraits<iter_t>::getNull();
00300     if (local_success) out << "passed\n";
00301     else success = false;
00302   }
00303 
00304   //
00305   out << "\nD) Test sub-views ...\n";
00306   //
00307 
00308   {
00309     out << "\nTest full non-const subview ...\n";
00310     const ArrayView<T> av2 = av(0,n);
00311     TEST_COMPARE_ARRAYS( av2, av );
00312   }
00313 
00314   {
00315     out << "\nTest full shorthand non-const subview ...\n";
00316     const ArrayView<T> av2 = av();
00317     TEST_COMPARE_ARRAYS( av2, av );
00318   }
00319 
00320   {
00321     out << "\nTest full const subview ...\n";
00322     const ArrayView<const T> cav2 = cav(0,n);
00323     TEST_COMPARE_ARRAYS( cav2, cav );
00324   }
00325 
00326   {
00327     out << "\nTest full non-const to const subview ...\n";
00328     const ArrayView<const T> cav2 = av(0,n);
00329     TEST_COMPARE_ARRAYS( cav2, cav );
00330   }
00331 
00332   {
00333     out << "\nTest full short-hand const subview ...\n";
00334     const ArrayView<const T> cav2 = cav();
00335     TEST_COMPARE_ARRAYS( cav2, cav );
00336   }
00337 
00338   {
00339     out << "\nTest non-const initial range view ...\n";
00340     std::vector<T> v2(n,as<T>(-1));
00341     const ArrayView<T> av2(v2);
00342     const ArrayView<T> av2_init = av2(0,n-1);
00343     TEST_EQUALITY( av2_init.size(), n-1 );
00344     av2_init.assign( av(0,n-1) );
00345     av2.back() = as<T>(n-1);
00346     TEST_COMPARE_ARRAYS( v2, v );
00347   }
00348 
00349   {
00350     out << "\nTest non-const final range view ...\n";
00351     std::vector<T> v2(n,as<T>(-1));
00352     const ArrayView<T> av2(v2);
00353     const ArrayView<T> av2_init = av2(1,n-1);
00354     TEST_EQUALITY( av2_init.size(), n-1 );
00355     av2_init.assign( av(1,n-1) );
00356     av2.front() = as<T>(0);
00357     TEST_COMPARE_ARRAYS( v2, v );
00358   }
00359 
00360   {
00361     out << "\nTest non-const middle range view ...\n";
00362     std::vector<T> v2(n,as<T>(-1));
00363     const ArrayView<T> av2(v2);
00364     const ArrayView<T> av2_init = av2(1,n-2);
00365     TEST_EQUALITY( av2_init.size(), n-2 );
00366     av2_init.assign( av(1,n-2) );
00367     av2.front() = as<T>(0);
00368     av2.back() = as<T>(n-1);
00369     TEST_COMPARE_ARRAYS( v2, v );
00370   }
00371 
00372   // ToDo: Test requesting views outside of valid range!
00373 
00374   return success;
00375 
00376 }
00377 
00378 
00379 //
00380 // Main testing program
00381 //
00382 
00383 int main( int argc, char* argv[] )
00384 {
00385 
00386   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
00387 
00388   using Teuchos::CommandLineProcessor;
00389 
00390         bool success = true;
00391   bool result;
00392 
00393   Teuchos::RCP<Teuchos::FancyOStream>
00394     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00395 
00396         try {
00397 
00398     //
00399                 // Read options from the commandline
00400     //
00401 
00402     CommandLineProcessor clp(false); // Don't throw exceptions
00403 
00404     int n = 4;
00405     clp.setOption( "n", &n, "Number of elements in the array" );
00406 
00407                 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00408 
00409                 if ( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00410                         *out << "\nEnd Result: TEST FAILED" << std::endl;
00411                         return parse_return;
00412                 }
00413 
00414     *out << std::endl << Teuchos::Teuchos_Version() << std::endl;
00415 
00416     result = testArrayView<int>(n,*out);
00417     if (!result) success = false;
00418 
00419     result = testArrayView<float>(n,*out);
00420     if (!result) success = false;
00421 
00422     result = testArrayView<double>(n,*out);
00423     if (!result) success = false;
00424 
00425     result = testArrayView<std::complex<double> >(n,*out);
00426     if (!result) success = false;
00427 
00428         }
00429   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00430 
00431   if (success)
00432     *out << "\nEnd Result: TEST PASSED" << std::endl;
00433   else
00434     *out << "\nEnd Result: TEST FAILED" << std::endl;
00435 
00436   return ( success ? 0 : 1 );
00437 
00438 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines