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