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 
00114   bool success = true;
00115  
00116   out
00117     << "\n***"
00118     << "\n*** Testing "<<TypeNameTraits<ArrayView<T> >::name()<<" of size = "<<n
00119     << "\n***\n";
00120   
00121   Teuchos::OSTab tab(out);
00122 
00123   //
00124   out << "\nA) Initial setup testing ...\n\n";
00125   //
00126   
00127   {
00128     out << "\nTesting basic null construction!\n\n";
00129     ArrayView<T> av2 = Teuchos::null;
00130     TEST_EQUALITY_CONST(is_null(av2),true);
00131     TEST_EQUALITY_CONST(av2.size(),0);
00132     TEST_EQUALITY_CONST(av2.getRawPtr(),0);
00133     TEST_ITER_EQUALITY(av2.begin(),av2.end());
00134 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00135     TEST_THROW(av2[0],Teuchos::NullReferenceError);
00136     TEST_THROW(*av2.begin(), Teuchos::NullReferenceError);
00137     TEST_THROW(*av2.end(), Teuchos::NullReferenceError);
00138     TEST_THROW(av2.assign(av2), Teuchos::NullReferenceError);
00139     TEST_THROW(av2.front(), Teuchos::NullReferenceError);
00140     TEST_THROW(av2.back(), Teuchos::NullReferenceError);
00141 #endif
00142     ArrayView<const T> cav2(av2); // Tests copy constructor and implicit conversion operator! 
00143     TEST_EQUALITY_CONST(cav2.size(),0);
00144     TEST_EQUALITY_CONST(cav2.getRawPtr(),0);
00145     TEST_ITER_EQUALITY(cav2.begin(),av2.end());
00146 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00147     TEST_THROW(cav2[0],Teuchos::NullReferenceError);
00148     TEST_THROW(*cav2.begin(), Teuchos::NullReferenceError);
00149     TEST_THROW(*cav2.end(), Teuchos::NullReferenceError);
00150     TEST_THROW(cav2.back(), Teuchos::NullReferenceError);
00151 #endif
00152 #ifdef SHOW_INVALID_CONST_ASSIGN
00153     TEST_NOTHROW(cav2.assign(av2)); // Should not compile!
00154 #endif
00155   }
00156 
00157   std::vector<T> v(n);
00158 
00159   const ArrayView<T> av = arrayViewFromVector(v);
00160   TEST_EQUALITY_CONST(is_null(av), false);
00161   TEST_EQUALITY( as<int>(av.size()), n );
00162 
00163   const ArrayView<const T> cav = av;
00164  
00165   {
00166     out << "\nInitializing data for std::vector v through view av ...\n";
00167     for( int i = 0; i < n; ++i )
00168       av[i] = i; // tests non-const operator[](i)
00169   }
00170 
00171   {
00172     out << "\nTest that v[i] == i through ArrayView<const T> ...\n";
00173     const ArrayView<const T> cav2 = cav;
00174     bool local_success = true;
00175     for( int i = 0; i < n; ++i ) {
00176       TEST_ARRAY_ELE_EQUALITY( cav2, i, as<T>(i) );
00177     }
00178     if (local_success) out << "passed\n";
00179     else success = false;
00180   }
00181 
00182   {
00183     out << "\nTest explicit copy to std::vector from non-const array view ...\n";
00184     std::vector<T> v2 = Teuchos::createVector(av);
00185     TEST_COMPARE_ARRAYS( v2, v );
00186   }
00187 
00188   {
00189     out << "\nTest explicit copy to std::vector from const array view ...\n";
00190     std::vector<T> v2 = Teuchos::createVector(cav);
00191     TEST_COMPARE_ARRAYS( v2, v );
00192   }
00193 
00194   {
00195     out << "\nTest shallow implicit conversion from ArrayView<T> to ArrayView<T> ...\n";
00196     ArrayView<T> av2(av);
00197     TEST_COMPARE_ARRAYS( av2, av );
00198   }
00199 
00200   {
00201     out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<const T> ...\n";
00202     ArrayView<const T> cav2(cav);
00203     TEST_COMPARE_ARRAYS( cav2, cav );
00204   }
00205 
00206   {
00207     out << "\nTest shallow implicit conversion from ArrayView<const T> to ArrayView<T> ...\n";
00208     ArrayView<const T> cav2(av);
00209     TEST_COMPARE_ARRAYS( cav2, av );
00210   }
00211 
00212   {
00213     out << "\nTest shallow implicit conversion from std::vector<T> to ArrayView<T> ...\n";
00214     std::vector<T> v2 = Teuchos::createVector(cav);
00215     ArrayView<T> cav2(v2);
00216     TEST_COMPARE_ARRAYS( cav2, av );
00217   }
00218 
00219   {
00220     out << "\nTest shallow implicit conversion from const std::vector<T> to ArrayView<const T> ...\n";
00221     const std::vector<T> v2 = Teuchos::createVector(cav);
00222     ArrayView<const T> cav2(v2);
00223     TEST_COMPARE_ARRAYS( cav2, av );
00224   }
00225 
00226   {
00227     // Try to copy construct from ArrayView<const T> to ArrayView<T> ..
00228 #ifdef SHOW_INVALID_COPY_CONSTRUCTION
00229     ArrayView<T> cav2(cav); // should not compile!
00230 #endif
00231   }
00232 
00233   {
00234     out << "\ntest assign(...) ...\n";
00235     std::vector<T> v2(n);
00236     ArrayView<T> av2(v2);
00237     av2.assign(av);
00238     TEST_COMPARE_ARRAYS( v2, v );
00239   }
00240 
00241   //
00242   out << "\nB) Test element access ...\n";
00243   //
00244 
00245 
00246   TEST_EQUALITY_CONST( av.front(), as<T>(0) );
00247   TEST_EQUALITY( av.back(), as<T>(n-1) );
00248   TEST_EQUALITY_CONST( cav.front(), as<T>(0) );
00249   TEST_EQUALITY( cav.back(), as<T>(n-1) );
00250 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00251   TEST_THROW( av[-1], Teuchos::RangeError );
00252   TEST_THROW( av[n], Teuchos::RangeError );
00253   TEST_THROW( cav[-1], Teuchos::RangeError );
00254   TEST_THROW( cav[n], Teuchos::RangeError );
00255 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00256 
00257   //
00258   out << "\nC) Test iterator access ...\n";
00259   //
00260 
00261 
00262   {
00263     out << "\nTest non-const forward iterator access ...\n";
00264     std::vector<T> v2(n);
00265     ArrayView<T> av2(v2);
00266     typedef typename ArrayView<T>::iterator iter_t;
00267     iter_t iter = av2.begin();
00268     for ( int i = 0; iter != av2.end(); ++i )
00269       *iter++ = i;
00270     TEST_COMPARE_ARRAYS( v2, v );
00271   }
00272 
00273   {
00274     out << "\nTest const forward iterator access ... ";
00275     bool local_success = true;
00276     typedef typename ArrayView<const T>::iterator iter_t;
00277     const ArrayView<const T> cav2 = av.getConst();
00278     iter_t iter = cav2.begin();
00279     for ( int i = 0; i < n; ++i, ++iter ) {
00280       TEST_ARRAY_ELE_EQUALITY( av, i, *iter );
00281 
00282 #ifdef SHOW_INVALID_CONST_ITER_MODIFICATION
00283       *iter = as<T>(i); // Should not compile!
00284 #endif
00285     }
00286     iter = NullIteratorTraits<iter_t>::getNull();
00287     if (local_success) out << "passed\n";
00288     else success = false;
00289   }
00290 
00291   //
00292   out << "\nD) Test sub-views ...\n";
00293   //
00294 
00295   {
00296     out << "\nTest full non-const subview ...\n";
00297     const ArrayView<T> av2 = av(0,n);
00298     TEST_COMPARE_ARRAYS( av2, av );
00299   }
00300 
00301   {
00302     out << "\nTest full shorthand non-const subview ...\n";
00303     const ArrayView<T> av2 = av();
00304     TEST_COMPARE_ARRAYS( av2, av );
00305   }
00306 
00307   {
00308     out << "\nTest full const subview ...\n";
00309     const ArrayView<const T> cav2 = cav(0,n);
00310     TEST_COMPARE_ARRAYS( cav2, cav );
00311   }
00312 
00313   {
00314     out << "\nTest full non-const to const subview ...\n";
00315     const ArrayView<const T> cav2 = av(0,n);
00316     TEST_COMPARE_ARRAYS( cav2, cav );
00317   }
00318 
00319   {
00320     out << "\nTest full short-hand const subview ...\n";
00321     const ArrayView<const T> cav2 = cav();
00322     TEST_COMPARE_ARRAYS( cav2, cav );
00323   }
00324 
00325   {
00326     out << "\nTest non-const initial range view ...\n";
00327     std::vector<T> v2(n,as<T>(-1));
00328     const ArrayView<T> av2(v2);
00329     const ArrayView<T> av2_init = av2(0,n-1);
00330     TEST_EQUALITY( av2_init.size(), n-1 );
00331     av2_init.assign( av(0,n-1) );
00332     av2.back() = as<T>(n-1);
00333     TEST_COMPARE_ARRAYS( v2, v );
00334   }
00335 
00336   {
00337     out << "\nTest non-const final range view ...\n";
00338     std::vector<T> v2(n,as<T>(-1));
00339     const ArrayView<T> av2(v2);
00340     const ArrayView<T> av2_init = av2(1,n-1);
00341     TEST_EQUALITY( av2_init.size(), n-1 );
00342     av2_init.assign( av(1,n-1) );
00343     av2.front() = as<T>(0);
00344     TEST_COMPARE_ARRAYS( v2, v );
00345   }
00346 
00347   {
00348     out << "\nTest non-const middle range view ...\n";
00349     std::vector<T> v2(n,as<T>(-1));
00350     const ArrayView<T> av2(v2);
00351     const ArrayView<T> av2_init = av2(1,n-2);
00352     TEST_EQUALITY( av2_init.size(), n-2 );
00353     av2_init.assign( av(1,n-2) );
00354     av2.front() = as<T>(0);
00355     av2.back() = as<T>(n-1);
00356     TEST_COMPARE_ARRAYS( v2, v );
00357   }
00358 
00359   // ToDo: Test requesting views outside of valid range!
00360 
00361   return success;
00362 
00363 }
00364 
00365 
00366 //
00367 // Main testing program
00368 //
00369 
00370 int main( int argc, char* argv[] )
00371 {
00372 
00373   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
00374 
00375   using Teuchos::CommandLineProcessor;
00376   
00377   bool success = true;
00378   bool result;
00379  
00380   Teuchos::RCP<Teuchos::FancyOStream>
00381     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00382  
00383   try {
00384     
00385     //
00386     // Read options from the commandline
00387     //
00388 
00389     CommandLineProcessor clp(false); // Don't throw exceptions
00390 
00391     int n = 4;
00392     clp.setOption( "n", &n, "Number of elements in the array" );
00393 
00394     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00395 
00396     if ( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00397       *out << "\nEnd Result: TEST FAILED" << std::endl;
00398       return parse_return;
00399     }
00400 
00401     *out << std::endl << Teuchos::Teuchos_Version() << std::endl;
00402  
00403     result = testArrayView<int>(n,*out);
00404     if (!result) success = false;
00405 
00406     result = testArrayView<float>(n,*out);
00407     if (!result) success = false;
00408 
00409     result = testArrayView<double>(n,*out);
00410     if (!result) success = false;
00411 
00412     result = testArrayView<std::complex<double> >(n,*out);
00413     if (!result) success = false;
00414  
00415   }
00416   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00417  
00418   if (success)
00419     *out << "\nEnd Result: TEST PASSED" << std::endl;
00420   else
00421     *out << "\nEnd Result: TEST FAILED" << std::endl;
00422  
00423   return ( success ? 0 : 1 );
00424  
00425 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines