|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
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 }
1.7.4