|
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 // 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 }
1.7.6.1