Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Array_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_Array.hpp"
00043 #include "Teuchos_GlobalMPISession.hpp"
00044 #include "Teuchos_CommandLineProcessor.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_LocalTestingHelpers.hpp"
00051 
00052 #include "TestClasses.hpp"
00053 
00054 
00055 //
00056 // Main templated array test function
00057 //
00058 
00059 
00060 template<class T>
00061 bool testArray( const int n, Teuchos::FancyOStream &out )
00062 {
00063 
00064   using Teuchos::Array;
00065   using Teuchos::ArrayView;
00066   using Teuchos::outArg;
00067   using Teuchos::getConst;
00068   using Teuchos::NullIteratorTraits;
00069   using Teuchos::TypeNameTraits;
00070   using Teuchos::as;
00071   using Teuchos::tuple;
00072   typedef typename Array<T>::size_type size_type;
00073 
00074   bool success = true;
00075 
00076   out
00077     << "\n***"
00078     << "\n*** Testing "<<TypeNameTraits<Array<T> >::name()<<" of size = "<<n
00079     << "\n***\n";
00080 
00081   Teuchos::OSTab tab(out);
00082 
00083   //
00084   out << "\nA) Initial setup ...\n\n";
00085   //
00086 
00087   // Tests construction using size
00088 
00089   Array<T> a(n);
00090 
00091   TEST_EQUALITY_CONST( a.empty(), false );
00092   TEST_EQUALITY( a.length(), n );
00093   TEST_EQUALITY( as<int>(a.size()), n );
00094   TEST_EQUALITY( a.getRawPtr(), &a[0] );
00095   TEST_EQUALITY( getConst(a).getRawPtr(), &getConst(a)[0] );
00096   TEST_COMPARE( a.max_size(), >=, as<size_type>(n) );
00097   TEST_COMPARE( as<int>(a.capacity()), >=, n );
00098 
00099   {
00100     out << "\nInitializing data ...\n";
00101     for( int i = 0; i < n; ++i )
00102       a[i] = as<T>(i); // tests non-const operator[](i)
00103   }
00104 
00105   {
00106     out << "\nTest that a[i] == i ... ";
00107     bool local_success = true;
00108     for( int i = 0; i < n; ++i ) {
00109       TEST_ARRAY_ELE_EQUALITY( a, i, as<T>(i) );
00110     }
00111     if (local_success) out << "passed\n";
00112     else success = false;
00113   }
00114 
00115   {
00116     out << "\nTest that a.at(i) == i ...\n";
00117     bool local_success = true;
00118     for( int i = 0; i < n; ++i ) {
00119       TEUCHOS_TEST_EQUALITY( a.at(i), as<T>(i), out, local_success );
00120     }
00121     if (local_success) out << "passed\n";
00122     else success = false;
00123   }
00124 
00125   //
00126   out << "\nB) Test constructors, assignment operators etc ...\n";
00127   //
00128 
00129   {
00130     out << "\nTest default constructor ...\n";
00131     Array<T> a2;
00132     TEST_EQUALITY_CONST( as<int>(a2.size()), 0 );
00133     TEST_EQUALITY_CONST( as<bool>(a2.empty()), true );
00134     TEST_EQUALITY_CONST( a2.getRawPtr(), 0 );
00135     TEST_EQUALITY_CONST( getConst(a2).getRawPtr(), 0 );
00136   }
00137 
00138   {
00139     out << "\nTest copy conversion to and from Teuchos::Array and std::vector ...\n";
00140     std::vector<T> v2 = createVector(a);
00141     Array<T> a2(v2);
00142     TEST_COMPARE_ARRAYS( a2, a );
00143   }
00144 
00145   {
00146     out << "\nTest assignment operator taking an std::vector ...\n";
00147     std::vector<T> v2 = createVector(a);
00148     Array<T> a2;
00149     a2 = v2;
00150     TEST_COMPARE_ARRAYS( a2, a );
00151   }
00152 
00153   {
00154     out << "\nTest construction using iterators ...\n";
00155     std::vector<T> v2 = createVector(a);
00156     Array<T> a2(a.begin(),a.end());
00157     TEST_COMPARE_ARRAYS( a2, a );
00158   }
00159 
00160   {
00161     out << "\nTest copy construction ...\n";
00162     Array<T> a2(a);
00163     TEST_COMPARE_ARRAYS( a2, a );
00164   }
00165 
00166   {
00167     out << "\nTest array assignment operator ...\n";
00168     Array<T> a2;
00169     a2 = a;
00170     TEST_COMPARE_ARRAYS( a2, a );
00171   }
00172 
00173   {
00174     out << "\nTest array assign(...) ...\n";
00175     Array<T> a2;
00176     a2.assign(a.begin(),a.end());
00177     TEST_COMPARE_ARRAYS( a2, a );
00178   }
00179 
00180   {
00181     out << "\nTest iterator access and then resize ...\n";
00182     Array<T> a2(a);
00183     const Array<T> &ca2 = a2;
00184     Array<T> a3(ca2.begin(),ca2.end());
00185     TEST_COMPARE_ARRAYS( a3, a );
00186     TEST_NOTHROW(a2.resize(0)); // This used to throw exception!
00187   }
00188 
00189   //
00190   out << "\nC) Test element access ...\n";
00191   //
00192 
00193   TEST_EQUALITY_CONST( a.front(), as<T>(0) );
00194   TEST_EQUALITY( a.back(), as<T>(n-1) );
00195 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00196   TEST_THROW( a[-1], Teuchos::RangeError );
00197   TEST_THROW( a[n], Teuchos::RangeError );
00198   TEST_THROW( a.at(-1), Teuchos::RangeError );
00199   TEST_THROW( a.at(n), Teuchos::RangeError );
00200 #else //HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00201   TEST_THROW( a.at(-1), std::out_of_range );
00202   TEST_THROW( a.at(n), std::out_of_range );
00203 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00204 
00205   //
00206   out << "\nD) Test iterator access ...\n";
00207   //
00208 
00209 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00210 
00211   {
00212     out << "\nTesting functions that should throw for empty container ...\n";
00213     Array<T> a2;
00214     TEST_THROW( *a2.begin(), Teuchos::NullReferenceError );
00215     TEST_THROW( a2.front(), Teuchos::NullReferenceError );
00216     TEST_THROW( a2.back(), Teuchos::NullReferenceError );
00217     TEST_THROW( getConst(a2).front(), Teuchos::NullReferenceError );
00218     TEST_THROW( getConst(a2).back(), Teuchos::NullReferenceError );
00219     TEST_THROW( a2.erase(a2.begin()), Teuchos::NullReferenceError );
00220   }
00221 
00222 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00223 
00224   {
00225     out << "\nTest that a2.begin() == a2.end() for empty a2 ...\n";
00226     Array<T> a2;
00227     TEST_ITER_EQUALITY( a2.begin(), a2.end() );
00228   }
00229 
00230   {
00231     out << "\nTest nonconst forward iterator access ... ";
00232     bool local_success = true;
00233     typedef typename Array<T>::iterator iter_t;
00234     iter_t iter = a.begin();
00235     for ( int i = 0; i < n; ++i, ++iter )
00236       TEST_ARRAY_ELE_EQUALITY( a, i, *iter );
00237     iter = NullIteratorTraits<iter_t>::getNull();
00238     if (local_success) out << "passed\n";
00239     else success = false;
00240   }
00241 
00242   {
00243     out << "\nTest const forward iterator access ... ";
00244     bool local_success = true;
00245     typedef typename Array<T>::const_iterator iter_t;
00246     iter_t iter = getConst(a).begin();
00247     for ( int i = 0; i < n; ++i, ++iter )
00248       TEST_ARRAY_ELE_EQUALITY( a, i, *iter );
00249     iter = NullIteratorTraits<iter_t>::getNull();
00250     if (local_success) out << "passed\n";
00251     else success = false;
00252   }
00253 
00254 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00255 
00256   {
00257     out << "\nTest forward iterators dereferenced out of bounds ...\n";
00258     TEST_THROW( *(a.begin()-1), Teuchos::RangeError );
00259     TEST_THROW( *a.end(), Teuchos::RangeError );
00260     TEST_THROW( *(getConst(a).begin()-1), Teuchos::RangeError );
00261     TEST_THROW( *getConst(a).end(), Teuchos::RangeError );
00262   }
00263 
00264 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00265 
00266   {
00267     out << "\nTest that a2.rbegin() == a2.rend() for empty a2 ...\n";
00268     Array<T> a2;
00269     TEST_ITER_EQUALITY( a2.rbegin(), a2.rend() );
00270   }
00271 
00272   {
00273     out << "\nTest nonconst reverse iterator access ... ";
00274     bool local_success = true;
00275     typedef typename Array<T>::reverse_iterator iter_t;
00276     iter_t iter = a.rbegin();
00277     for ( int i = n-1; i >= 0; --i, ++iter )
00278       TEST_ARRAY_ELE_EQUALITY( a, i, *iter );
00279     iter = NullIteratorTraits<iter_t>::getNull();
00280     if (local_success) out << "passed\n";
00281     else success = false;
00282   }
00283 
00284   {
00285     out << "\nTest const reverse iterator access ... ";
00286     bool local_success = true;
00287     typedef typename Array<T>::const_reverse_iterator iter_t;
00288     iter_t iter = getConst(a).rbegin();
00289     for ( int i = n-1; i >= 0; --i, ++iter )
00290       TEST_ARRAY_ELE_EQUALITY( a, i, *iter );
00291     iter = NullIteratorTraits<iter_t>::getNull();
00292     if (local_success) out << "passed\n";
00293     else success = false;
00294   }
00295 
00296 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00297   {
00298     out << "\nTest reverse iterators dereferenced out of bounds ...\n";
00299     TEST_THROW( *(a.rbegin()-1), Teuchos::RangeError );
00300     TEST_THROW( *a.rend(), Teuchos::RangeError );
00301     TEST_THROW( *(getConst(a).rbegin()-1), Teuchos::RangeError );
00302     TEST_THROW( *getConst(a).rend(), Teuchos::RangeError );
00303   }
00304 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00305 
00306   {
00307     out << "\nTest that an iterator reference set to null does not throw ...\n";
00308     typedef typename Array<T>::iterator iter_t;
00309     iter_t iter = NullIteratorTraits<iter_t>::getNull();
00310     TEST_NOTHROW( Array<T> a2(n); iter = a2.begin();
00311       iter = NullIteratorTraits<iter_t>::getNull() );
00312   }
00313 
00314   {
00315     out << "\nTest that a dangling iterator reference throws exception ...\n";
00316     typedef typename Array<T>::iterator iter_t;
00317     iter_t iter = NullIteratorTraits<iter_t>::getNull();
00318     {
00319       Array<T> a2(n);
00320       iter = a2.begin();
00321     }
00322 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00323     TEST_THROW(*iter=0, Teuchos::DanglingReferenceError );
00324 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00325   }
00326 
00327 
00328   //
00329   out << "\nE) Test insertion and deletion functions ...\n";
00330   //
00331 
00332   {
00333     out << "\nTest push_back(x) ...\n";
00334     Array<T> a2;
00335     for ( int i = 0; i < n; ++i ) {
00336       a2.push_back(as<T>(i));
00337       TEST_EQUALITY_CONST(a2.front(),as<T>(0));
00338       TEST_EQUALITY_CONST(getConst(a2).front(),as<T>(0));
00339       TEST_EQUALITY(a2.back(),as<T>(i));
00340       TEST_EQUALITY(getConst(a2).back(),as<T>(i));
00341     }
00342     TEST_COMPARE_ARRAYS( a2, a );
00343   }
00344 
00345   {
00346     out << "\nTest pop_back() ...\n";
00347     Array<T> a2(a);
00348     for ( int i = n-1; i >= 0; --i ) {
00349       TEST_EQUALITY(a2.back(),as<T>(i));
00350       a2.pop_back();
00351     }
00352   }
00353 
00354   {
00355     out << "\nTest insert(iter,x) ...\n";
00356     Array<T> a2;
00357     for ( int i = 0; i < n; ++i ) {
00358       const typename Array<T>::iterator
00359         iter = a2.insert(a2.end(), as<T>(i));
00360       TEST_EQUALITY(*iter, as<T>(i));
00361     }
00362     TEST_COMPARE_ARRAYS( a2, a );
00363   }
00364 
00365   {
00366     out << "\nTest insert(iter,1,x) ...\n";
00367     Array<T> a2;
00368     for ( int i = 0; i < n; ++i )
00369       a2.insert(a2.end(),1,i);
00370     TEST_COMPARE_ARRAYS( a2, a );
00371   }
00372 
00373   {
00374     out << "\nTest insert(iter,first,last) ...\n";
00375     Array<T> a2;
00376     for ( int i = 0; i < n; ++i )
00377       a2.insert(a2.end(),a.begin()+i,a.begin()+i+1);
00378     TEST_COMPARE_ARRAYS( a2, a );
00379   }
00380 
00381   {
00382     out << "\nTest append(x) ...\n";
00383     Array<T> a2;
00384     for ( int i = 0; i < n; ++i )
00385       a2.append(as<T>(i));
00386     TEST_COMPARE_ARRAYS( a2, a );
00387   }
00388 
00389   {
00390     out << "\nTest erase(iter) ...\n";
00391     Array<T> a2(a);
00392     for ( int i = 0; i < n; ++i ) {
00393       TEST_EQUALITY( as<int>(a2.size()), n-i );
00394       TEST_EQUALITY( a2.front(), as<T>(i) );
00395       a2.erase(a2.begin());
00396     }
00397     TEST_EQUALITY_CONST( a2.empty(), true );
00398   }
00399 
00400 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00401 
00402   {
00403     out << "\nTest trying to erase twice with the same iterator which should throw ...\n";
00404     Array<T> a2(a);
00405     const typename Array<T>::iterator iter = a2.begin();
00406     a2.erase(iter); // After this point, the iterator is no longer valid!
00407     // This is no longer a valid iterator and should throw!
00408     TEST_THROW( a2.erase(iter), Teuchos::IncompatibleIteratorsError );
00409   }
00410 
00411 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00412 
00413   // 2007/11/08: rabartl: ToDo: Above, I have tested one use case where the
00414   // iterator should be invalidated and this tests that it throws an exception
00415   // as it should.  However, currently, I don't have code written that will
00416   // catch the problem where the client would try to dereference the iterator
00417   // or something like that.  This is a big no-no.  I could do this by adding
00418   // an is_valid() property to RCP_node and then setting this to null when the
00419   // structure of the iterator changes.  Then, I would have to put asserts in
00420   // ArrayRCP to constantly check is_valid() (with an assert_is_valid()
00421   // function or something) on any call other than operator=(...) which would
00422   // reset this iterator.  Catching all of these user errors is a lot of work!
00423 
00424   {
00425     out << "\nTest remove(i) ...\n";
00426     Array<T> a2(a);
00427     for ( int i = 0; i < n; ++i ) {
00428       TEST_EQUALITY( as<int>(a2.size()), n-i );
00429       TEST_EQUALITY( a2.front(), as<T>(i) );
00430       a2.remove(0); // Always remove the "first" entry!
00431     }
00432     TEST_EQUALITY_CONST( a2.empty(), true );
00433   }
00434 
00435   {
00436     out << "\nTest erase(begin(),end()) ...\n";
00437     Array<T> a2(a);
00438     a2.erase(a2.begin(),a2.end());
00439     TEST_EQUALITY_CONST( a2.empty(), true );
00440   }
00441 
00442   {
00443     out << "\nTest member swap() ...\n";
00444     Array<T> a2(a);
00445     Array<T> a3(a);
00446     for ( int i = 0; i < n; ++i )
00447       a2[i] += as<T>(1);
00448     a2.swap(a3);
00449     TEST_COMPARE_ARRAYS( a2, a );
00450   }
00451 
00452   {
00453     out << "\nTest non-member swap() ...\n";
00454     Array<T> a2(a);
00455     Array<T> a3(a);
00456     for ( int i = 0; i < n; ++i )
00457       a2[i] += as<T>(1);
00458     swap(a2,a3);
00459     TEST_COMPARE_ARRAYS( a2, a );
00460   }
00461 
00462   {
00463     out << "\nTest clear() ...\n";
00464     Array<T> a2(a);
00465     a2.clear();
00466     TEST_EQUALITY_CONST( a2.empty(), true );
00467     TEST_EQUALITY_CONST( a2.size(), 0 );
00468   }
00469 
00470 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00471   // mfh 28 Aug 2012: This test no longer passes, because we've
00472   // specialized ArrayView<T>::toString() for T = (const) float,
00473   // (const) double.  We've done the specialization to print float and
00474   // double in scientific notation.  That was a hack to fix a bug; it
00475   // would make more sense to provide a standard toString() for float
00476   // and double, and have the test (or even the
00477   // ArrayView<T>::toString() specialization) use that.
00478   //
00479   // {
00480   //   out << "\nTest to string ...\n";
00481   //   std::ostringstream o;
00482   //   o << "{";
00483   //   for ( int i = 0; i < n; ++i ) {
00484   //     o << as<T>(i) << ( i < n-1 ? ", " : "" );
00485   //   }
00486   //   o << "}";
00487   //   TEST_EQUALITY( o.str(), a.toString() );
00488   // }
00489 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00490 
00491   {
00492     out << "\nTest hasArrayBoundsChecking() ... \n";
00493 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00494     TEST_EQUALITY_CONST( a.hasBoundsChecking(), true );
00495 #else
00496     TEST_EQUALITY_CONST( a.hasBoundsChecking(), false );
00497 #endif
00498   }
00499 
00500   //
00501   out << "\nG) Test views ...\n";
00502   //
00503 
00504   {
00505     out << "\nTest full non-const subview ...\n";
00506     const ArrayView<T> av2 = a(0,n);
00507     TEST_COMPARE_ARRAYS( av2, a );
00508   }
00509 
00510   {
00511     out << "\nTest full shorthand non-const subview ...\n";
00512     const ArrayView<T> av2 = a();
00513     TEST_COMPARE_ARRAYS( av2, a );
00514   }
00515 
00516   {
00517     out << "\nTest full const subview ...\n";
00518     const ArrayView<const T> cav2 = getConst(a)(0, n);
00519     TEST_COMPARE_ARRAYS( cav2, a );
00520   }
00521 
00522   {
00523     out << "\nTest full non-const to const subview ...\n";
00524     const ArrayView<const T> cav2 = a(0, n);
00525     TEST_COMPARE_ARRAYS( cav2, a );
00526   }
00527 
00528   {
00529     out << "\nTest full short-hand const subview ...\n";
00530     const ArrayView<const T> cav2 = getConst(a)();
00531     TEST_COMPARE_ARRAYS( cav2, a );
00532   }
00533 
00534   {
00535     out << "\nTest non-const initial range view ...\n";
00536     Array<T> a2(n,as<T>(-1));
00537     const ArrayView<T> av2 = a2; // Tests implicit conversion!
00538     const ArrayView<T> av2_end = av2(0,n-1);
00539     TEST_EQUALITY( av2_end.size(), n-1 );
00540     av2_end.assign( a(0,n-1) );
00541     av2.back() = as<T>(n-1);
00542     TEST_COMPARE_ARRAYS( a2, a );
00543   }
00544 
00545   {
00546     out << "\nTest non-const middle range view ...\n";
00547     Array<T> a2(n,as<T>(-1));
00548     const ArrayView<T> av2 = a2; // Tests implicit conversion!
00549     const ArrayView<T> av2_middle = av2(1,n-2);
00550     TEST_EQUALITY( av2_middle.size(), n-2 );
00551     av2_middle.assign( a(1,n-2) );
00552     av2.front() = as<T>(0);
00553     av2.back() = as<T>(n-1);
00554     TEST_COMPARE_ARRAYS( a2, a );
00555   }
00556 
00557   {
00558     out << "\nTest const view ... ";
00559     const ArrayView<const T> av2 = a; // Tests implicit conversion to const!
00560     const ArrayView<const T> av2_middle = av2(1,n-2);
00561     TEST_EQUALITY( av2_middle.size(), n-2 );
00562     bool local_success = true;
00563     for ( int i = 0; i < n-2; ++i )
00564       TEST_ARRAY_ELE_EQUALITY( av2_middle, i, as<T>(i+1) );
00565     if (local_success) out << "passed\n";
00566     else success = false;
00567   }
00568 
00569   {
00570     out << "\nTest constructing Array<T> from ArrayView<T> ...\n";
00571     const ArrayView<T> av2 = a;
00572     Array<T> a2(av2);
00573     TEST_COMPARE_ARRAYS( a2, a );
00574   }
00575 
00576   {
00577     out << "\nTest constructing Array<T> from ArrayView<const T> ...\n";
00578     const ArrayView<const T> av2 = a;
00579     Array<T> a2(av2);
00580     TEST_COMPARE_ARRAYS( a2, a );
00581   }
00582 
00583   {
00584     out << "\nTest comparison operators ...\n";
00585     Array<T> a2(a);
00586     TEST_EQUALITY_CONST( (a2==a), true );
00587     TEST_EQUALITY_CONST( (a2!=a), false );
00588     TEST_EQUALITY_CONST( (a2<=a), true );
00589     TEST_EQUALITY_CONST( (a2>=a), true );
00590     TEST_EQUALITY_CONST( (a2<a), false );
00591     TEST_EQUALITY_CONST( (a2>a), false );
00592   }
00593 
00594   //
00595   out << "\nH) Test tuple(...) construction ...\n";
00596   //
00597 
00598   {
00599     const size_type m = 1;
00600     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00601     Array<T> am = tuple<T>(0);
00602     TEST_EQUALITY_CONST(am.size(), m);
00603     out << "Test that am[i] == i ... ";
00604     bool local_success = true;
00605     for( size_type i = 0; i < m; ++i ) {
00606       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00607     }
00608     if (local_success) out << "passed\n";
00609     else success = false;
00610   }
00611 
00612   {
00613     const size_type m = 2;
00614     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00615     Array<T> am = tuple<T>(0,1);
00616     TEST_EQUALITY_CONST(am.size(),m);
00617     out << "Test that am[i] == i ... ";
00618     bool local_success = true;
00619     for( size_type i = 0; i < m; ++i ) {
00620       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00621     }
00622     if (local_success) out << "passed\n";
00623     else success = false;
00624   }
00625 
00626   {
00627     const size_type m = 3;
00628     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00629     Array<T> am = tuple<T>(0,1,2);
00630     TEST_EQUALITY_CONST(am.size(),m);
00631     out << "Test that am[i] == i ... ";
00632     bool local_success = true;
00633     for( size_type i = 0; i < m; ++i ) {
00634       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00635     }
00636     if (local_success) out << "passed\n";
00637     else success = false;
00638   }
00639 
00640   {
00641     const size_type m = 4;
00642     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00643     Array<T> am = tuple<T>(0,1,2,3);
00644     TEST_EQUALITY_CONST(am.size(),m);
00645     out << "Test that am[i] == i ... ";
00646     bool local_success = true;
00647     for( size_type i = 0; i < m; ++i ) {
00648       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00649     }
00650     if (local_success) out << "passed\n";
00651     else success = false;
00652   }
00653 
00654   {
00655     const size_type m = 5;
00656     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00657     Array<T> am = tuple<T>(0,1,2,3,4);
00658     TEST_EQUALITY_CONST(am.size(),m);
00659     out << "Test that am[i] == i ... ";
00660     bool local_success = true;
00661     for( size_type i = 0; i < m; ++i ) {
00662       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00663     }
00664     if (local_success) out << "passed\n";
00665     else success = false;
00666   }
00667 
00668   {
00669     const size_type m = 6;
00670     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00671     Array<T> am = tuple<T>(0,1,2,3,4,5);
00672     TEST_EQUALITY_CONST(am.size(),m);
00673     out << "Test that am[i] == i ... ";
00674     bool local_success = true;
00675     for( size_type i = 0; i < m; ++i ) {
00676       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00677     }
00678     if (local_success) out << "passed\n";
00679     else success = false;
00680   }
00681 
00682   {
00683     const size_type m = 7;
00684     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00685     Array<T> am = tuple<T>(0,1,2,3,4,5,6);
00686     TEST_EQUALITY_CONST(am.size(),m);
00687     out << "Test that am[i] == i ... ";
00688     bool local_success = true;
00689     for( size_type i = 0; i < m; ++i ) {
00690       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00691     }
00692     if (local_success) out << "passed\n";
00693     else success = false;
00694   }
00695 
00696   {
00697     const size_type m = 8;
00698     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00699     Array<T> am = tuple<T>(0,1,2,3,4,5,6,7);
00700     TEST_EQUALITY_CONST(am.size(),m);
00701     out << "Test that am[i] == i ... ";
00702     bool local_success = true;
00703     for( size_type i = 0; i < m; ++i ) {
00704       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00705     }
00706     if (local_success) out << "passed\n";
00707     else success = false;
00708   }
00709 
00710   {
00711     const size_type m = 9;
00712     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00713     Array<T> am = tuple<T>(0,1,2,3,4,5,6,7,8);
00714     TEST_EQUALITY_CONST(am.size(),m);
00715     out << "Test that am[i] == i ... ";
00716     bool local_success = true;
00717     for( size_type i = 0; i < m; ++i ) {
00718       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00719     }
00720     if (local_success) out << "passed\n";
00721     else success = false;
00722   }
00723 
00724   {
00725     const size_type m = 10;
00726     out << "\nTest Array<T> = tuple(0,...,"<<m-1<<")\n";
00727     Array<T> am = tuple<T>(0,1,2,3,4,5,6,7,8,9);
00728     TEST_EQUALITY_CONST(am.size(),m);
00729     out << "Test that am[i] == i ... ";
00730     bool local_success = true;
00731     for( size_type i = 0; i < m; ++i ) {
00732       TEST_ARRAY_ELE_EQUALITY( am, i, as<T>(i) );
00733     }
00734     if (local_success) out << "passed\n";
00735     else success = false;
00736   }
00737 
00738   {
00739     out << "\nTest taking an empty view ...\n";
00740     const ArrayView<T> av = a(0,0);
00741     TEST_EQUALITY_CONST( av.size(), 0 );
00742   }
00743 
00744 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00745   {
00746     out << "\nTest taking views outside of valid range ...\n";
00747     TEST_THROW( const ArrayView<T> av = a(-1,n), Teuchos::RangeError );
00748     TEST_THROW( const ArrayView<T> av = a(0,n+1), Teuchos::RangeError );
00749     TEST_THROW( const ArrayView<T> av = a(0,-1), Teuchos::RangeError );
00750   }
00751 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00752 
00753   return success;
00754 
00755 }
00756 
00757 
00758 template<class T>
00759 bool testArrayOpaqueWithoutTNT( const std::string &T_name, const int n,
00760   const T &someValue, Teuchos::FancyOStream &out )
00761 {
00762 
00763   using Teuchos::Array;
00764   using Teuchos::ArrayView;
00765   using Teuchos::TypeNameTraits;
00766   using Teuchos::as;
00767   typedef typename Array<T>::size_type size_type;
00768 
00769   bool success = true;
00770 
00771   out
00772     << "\n***"
00773     << "\n*** Testing Array<"<<T_name<<"> for opaque type without TNT of size = "<<n
00774     << "\n***\n";
00775 
00776   Teuchos::OSTab tab(out);
00777 
00778   //
00779   out << "\nA) Initial setup ...\n\n";
00780   //
00781 
00782   // Tests construction using size
00783 
00784   Array<T> a(n);
00785 
00786   TEST_EQUALITY_CONST( a.empty(), false );
00787   TEST_EQUALITY( a.length(), n );
00788   TEST_EQUALITY( as<int>(a.size()), n );
00789   TEST_EQUALITY( a.getRawPtr(), &a[0] );
00790   TEST_EQUALITY( getConst(a).getRawPtr(), &getConst(a)[0] );
00791   TEST_COMPARE( a.max_size(), >=, as<size_type>(n) );
00792   TEST_COMPARE( as<int>(a.capacity()), >=, n );
00793 
00794   {
00795     out << "\nInitializing data ...\n";
00796     for( int i = 0; i < n; ++i )
00797       a[i] = someValue; // tests non-const operator[](i)
00798   }
00799 
00800   {
00801     out << "\nTest that a[i] == "<<someValue<<" ... ";
00802     bool local_success = true;
00803     for( int i = 0; i < n; ++i ) {
00804       TEST_ARRAY_ELE_EQUALITY( a, i, someValue );
00805     }
00806     if (local_success) out << "passed\n";
00807     else success = false;
00808   }
00809 
00810 #ifndef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00811   {
00812     out << "\nTest taking a view of the array ...\n";
00813     const ArrayView<T> av = a();
00814     TEST_COMPARE_ARRAYS( av, a );
00815   }
00816   // 2008/08/01: rabartl: Above: We can not create an array view of an
00817   // undefined type in debug mode without a specialization of TypeNameTraits.
00818 #endif // not HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00819 
00820   // ToDo: Do we need to be testing other things for opaque objects?
00821 
00822   return success;
00823 
00824 }
00825 
00826 
00827 template<class T>
00828 bool testArrayOpaqueWithTNT( const int n, const T &someValue, Teuchos::FancyOStream &out )
00829 {
00830 
00831   using Teuchos::Array;
00832   using Teuchos::ArrayView;
00833   using Teuchos::TypeNameTraits;
00834   using Teuchos::as;
00835   typedef typename Array<T>::size_type size_type;
00836 
00837   bool success = true;
00838 
00839   out
00840     << "\n***"
00841     << "\n*** Testing "<<TypeNameTraits<Array<T> >::name()<<" for opaque type with TNT of size = "<<n
00842     << "\n***\n";
00843 
00844   Teuchos::OSTab tab(out);
00845 
00846   //
00847   out << "\nA) Initial setup ...\n\n";
00848   //
00849 
00850   // Tests construction using size
00851 
00852   Array<T> a(n);
00853 
00854   TEST_EQUALITY_CONST( a.empty(), false );
00855   TEST_EQUALITY( a.length(), n );
00856   TEST_EQUALITY( as<int>(a.size()), n );
00857   TEST_EQUALITY( a.getRawPtr(), &a[0] );
00858   TEST_EQUALITY( getConst(a).getRawPtr(), &getConst(a)[0] );
00859   TEST_COMPARE( a.max_size(), >=, as<size_type>(n) );
00860   TEST_COMPARE( as<int>(a.capacity()), >=, n );
00861 
00862   {
00863     out << "\nInitializing data ...\n";
00864     for( int i = 0; i < n; ++i )
00865       a[i] = someValue; // tests non-const operator[](i)
00866   }
00867 
00868   {
00869     out << "\nTest that a[i] == "<<someValue<<" ... ";
00870     bool local_success = true;
00871     for( int i = 0; i < n; ++i ) {
00872       TEST_ARRAY_ELE_EQUALITY( a, i, someValue );
00873     }
00874     if (local_success) out << "passed\n";
00875     else success = false;
00876   }
00877 
00878   {
00879     out << "\nTest taking a view of the array ...\n";
00880     const ArrayView<T> av = a();
00881     TEST_COMPARE_ARRAYS( av, a );
00882   }
00883 
00884 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00885   {
00886     out << "\nTest taking views outside of valid range ...\n";
00887     TEST_THROW( const ArrayView<T> av = a(-1,n), Teuchos::RangeError );
00888     TEST_THROW( const ArrayView<T> av = a(0,n+1), Teuchos::RangeError );
00889     TEST_THROW( const ArrayView<T> av = a(0,-1), Teuchos::RangeError );
00890   }
00891 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00892 
00893   // 2008/08/01: rabartl: Above: We can create ArrayViews and any other thing
00894   // that we would like since we have defined a TypeNameTraits class for the
00895   // undefined type.
00896 
00897   // ToDo: Do we need to be testing other things for opaque objects?
00898 
00899   return success;
00900 
00901 }
00902 
00903 
00904 //
00905 // Main testing program
00906 //
00907 
00908 int main( int argc, char* argv[] ) {
00909 
00910   using Teuchos::CommandLineProcessor;
00911   using Teuchos::Array;
00912 
00913         bool success = true;
00914   bool result;
00915 
00916   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
00917   //const int procRank = Teuchos::GlobalMPISession::getRank();
00918 
00919   Teuchos::RCP<Teuchos::FancyOStream>
00920     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00921 
00922         try {
00923 
00924     //
00925                 // Read options from the commandline
00926     //
00927 
00928     CommandLineProcessor clp(false); // Don't throw exceptions
00929 
00930     int n = 4;
00931     clp.setOption( "n", &n, "Number of elements in the array" );
00932 
00933                 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00934 
00935                 if ( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00936                         *out << "\nEnd Result: TEST FAILED" << std::endl;
00937                         return parse_return;
00938                 }
00939 
00940     *out << std::endl << Teuchos::Teuchos_Version() << std::endl;
00941 
00942     result = testArray<int>(n,*out);
00943     if (!result) success = false;
00944 
00945     result = testArray<float>(n,*out);
00946     if (!result) success = false;
00947 
00948     result = testArray<double>(n,*out);
00949     if (!result) success = false;
00950 
00951     //result = testArray<std::complex<double> >(n,*out);
00952     //if (!result) success = false;
00953     // 2007/12/03: rabartl: Commented this out so I can test comparison operators
00954 
00955     result = testArrayOpaqueWithoutTNT<Opaque_handle>("Opaque_handle", n,
00956       OPAQUE_HANDLE_NULL, *out);
00957     if (!result) success = false;
00958 
00959     result = testArrayOpaqueWithTNT<Opaque2_handle>(n, OPAQUE2_HANDLE_NULL, *out);
00960     if (!result) success = false;
00961 
00962     result = testArrayOpaqueWithTNT<Opaque3_handle>(n, OPAQUE3_HANDLE_NULL, *out);
00963     if (!result) success = false;
00964 
00965     // ToDo: Fill in the rest of the types!
00966 
00967         }
00968   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00969 
00970   if (success)
00971     *out << "\nEnd Result: TEST PASSED" << std::endl;
00972   else
00973     *out << "\nEnd Result: TEST FAILED" << std::endl;
00974 
00975   return ( success ? 0 : 1 );
00976 
00977 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines