Teuchos Package Browser (Single Doxygen Collection) Version of the Day
ArrayView_UnitTests.cpp
Go to the documentation of this file.
00001 /*
00002 // @HEADER
00003 // ***********************************************************************
00004 //
00005 //                    Teuchos: Common Tools Package
00006 //                 Copyright (2004) Sandia Corporation
00007 //
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 // @HEADER
00042 */
00043 
00044 #include "Array_UnitTest_helpers.hpp"
00045 
00046 #include "Teuchos_implicit_cast.hpp"
00047 
00048 
00049 namespace {
00050 
00051 
00052 using ArrayUnitTestHelpers::n;
00053 using ArrayUnitTestHelpers::generateArray;
00054 using Teuchos::RCP;
00055 using Teuchos::rcp;
00056 using Teuchos::Array;
00057 using Teuchos::ArrayRCP;
00058 using Teuchos::arcp;
00059 using Teuchos::ArrayView;
00060 using Teuchos::arrayView;
00061 using Teuchos::av_const_cast;
00062 using Teuchos::av_reinterpret_cast;
00063 using Teuchos::DanglingReferenceError;
00064 using Teuchos::as;
00065 using Teuchos::null;
00066 using Teuchos::implicit_ptr_cast;
00067 
00068 
00069 TEUCHOS_UNIT_TEST( ArrayView, assignSelf )
00070 {
00071   ArrayView<int> av;
00072   av = av;
00073   TEST_ASSERT(is_null(av));
00074   TEST_ASSERT(!nonnull(av));
00075 }
00076 
00077 
00078 TEUCHOS_UNIT_TEST( ArrayView, assignFuncSelf )
00079 {
00080   Array<int> a = generateArray<int>(n);
00081   ArrayView<int> av = a;
00082   av.assign(av);
00083 }
00084 
00085 
00086 TEUCHOS_UNIT_TEST( ArrayView, av_const_cast_null )
00087 {
00088   ArrayView<const int> av_int1 = null;
00089   ArrayView<int> av_int2 = av_const_cast<int>(av_int1);
00090   TEST_ASSERT(is_null(av_int2));
00091 }
00092 
00093 
00094 TEUCHOS_UNIT_TEST( ArrayView, av_const_cast )
00095 {
00096   ArrayRCP<const int> arcp_int = arcp<int>(n);
00097   ArrayView<const int> av_int1 = arcp_int();
00098   ArrayView<int> av_int2 = av_const_cast<int>(av_int1);
00099   TEST_ASSERT(nonnull(av_int2));
00100   TEST_EQUALITY(av_int2.getRawPtr(), av_int1.getRawPtr());
00101   TEST_EQUALITY(av_int2.getRawPtr(), arcp_int.getRawPtr());
00102 }
00103 
00104 
00105 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_null )
00106 {
00107   ArrayView<char> av_char = null;
00108   ArrayView<int> av_int = av_reinterpret_cast<int>(av_char);
00109   TEST_ASSERT(is_null(av_int));
00110 }
00111 
00112 
00113 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_char_to_int )
00114 {
00115 
00116   const int sizeOfInt = sizeof(int);
00117   const int sizeOfChar = sizeof(char);
00118   const int num_ints = n;
00119   const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
00120   out << "num_ints = " << num_ints << "\n";
00121   out << "num_chars = " << num_chars << "\n";
00122 
00123   ArrayRCP<char> arcp_char = arcp<char>(num_chars);
00124   ArrayView<int> av_int = av_reinterpret_cast<int>(arcp_char());
00125   TEST_EQUALITY(av_int.size(), num_ints);
00126   TEST_EQUALITY(implicit_ptr_cast<void>(&av_int[0]),
00127     implicit_ptr_cast<void>(&arcp_char[0]));
00128   TEST_EQUALITY(implicit_ptr_cast<void>((&av_int[num_ints-1])+1),
00129     implicit_ptr_cast<void>((&arcp_char[num_chars-1])+1));
00130 
00131 }
00132 
00133 
00134 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_int_to_char )
00135 {
00136 
00137   const int sizeOfInt = sizeof(int);
00138   const int sizeOfChar = sizeof(char);
00139   const int num_ints = n;
00140   const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
00141   out << "num_ints = " << num_ints << "\n";
00142   out << "num_chars = " << num_chars << "\n";
00143 
00144   ArrayRCP<int> arcp_int = arcp<int>(num_ints);
00145   ArrayView<char> av_char = av_reinterpret_cast<char>(arcp_int());
00146   TEST_EQUALITY(av_char.size(), num_chars);
00147   TEST_EQUALITY(implicit_ptr_cast<void>(&arcp_int[0]),
00148     implicit_ptr_cast<void>(&av_char[0]));
00149   TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
00150     implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
00151   TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
00152     implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
00153 
00154 }
00155 
00156 
00157 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView_construct_zero_size, T )
00158 {
00159   Array<T> a;
00160   const ArrayView<T> av = arrayView(a.getRawPtr(), a.size());
00161   TEST_EQUALITY_CONST(av.size(), 0);
00162   TEST_ASSERT(is_null(av));
00163   TEST_ASSERT(!nonnull(av));
00164 }
00165 
00166 
00167 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView, T )
00168 {
00169   Array<T> a = generateArray<T>(n);
00170   const ArrayView<T> av = arrayView(&a[0], a.size());
00171   TEST_COMPARE_ARRAYS( a, av );
00172 }
00173 
00174 
00175 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, null_zero_ArrayView_operator, T )
00176 {
00177   const ArrayView<T> av_0;
00178   const ArrayView<T> av = av_0(0, 0);
00179   TEST_ASSERT(is_null(av));
00180 }
00181 
00182 
00183 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, null_zero_ArrayView_func, T )
00184 {
00185   const ArrayView<T> av_0;
00186   const ArrayView<T> av = av_0.view(0, 0);
00187   TEST_ASSERT(is_null(av));
00188 }
00189 
00190 
00191 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, assignmentOperator, T )
00192 {
00193   Array<T> a = generateArray<T>(n);
00194   ArrayView<T> av1;
00195   av1 = a;
00196   ArrayView<T> av2;
00197   av2 = av1;
00198   TEST_EQUALITY( av1.getRawPtr(), a.getRawPtr() );
00199   TEST_EQUALITY( av1.size(), as<int>(a.size()) );
00200   TEST_EQUALITY( av1.getRawPtr(), av2.getRawPtr() );
00201   TEST_EQUALITY( av1.size(), av2.size() );
00202   TEST_COMPARE_ARRAYS( av1, a );
00203   TEST_COMPARE_ARRAYS( av1, av2 );
00204   av1 = null;
00205   TEST_EQUALITY_CONST( av1.getRawPtr(), 0 );
00206   TEST_EQUALITY_CONST( av1.size(), 0 );
00207   av2 = null;
00208   TEST_EQUALITY_CONST( av2.getRawPtr(), 0 );
00209   TEST_EQUALITY_CONST( av2.size(), 0 );
00210 }
00211 
00212 
00213 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, iterators, T )
00214 {
00215   typedef typename ArrayView<T>::iterator iter_t;
00216   typedef Teuchos::ScalarTraits<T> ST;
00217   ECHO(Array<T> a = generateArray<T>(n));
00218   ECHO(ArrayView<T> av = a);
00219   ECHO(const iter_t av_begin = av.begin());
00220   ECHO(const iter_t av_end = av.end());
00221 #ifdef TEUCHOS_DEBUG
00222   TEST_ASSERT(av_begin.shares_resource(av_end));
00223 #endif
00224   ECHO(std::fill(av_begin, av_end, ST::random()));
00225   ECHO(Array<T> a2 = generateArray<T>(n));
00226   ECHO(ArrayView<T> av2 = a2);
00227   ECHO(std::copy(av.begin(), av.end(), av2.begin()));
00228   TEST_COMPARE_ARRAYS(a, a2);
00229 }
00230 
00231 
00232 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_std_vector, T )
00233 {
00234   ArrayView<T> av;
00235   T* badPtr = 0;
00236   {
00237     std::vector<T> v(n);
00238     av = v;
00239     badPtr = &v[0];
00240   }
00241   // Access the raw pointer but it now points to invalid memory!
00242   TEST_EQUALITY(av.getRawPtr(), badPtr);
00243   // Above, we have no way to detect that the underlying std::vector object
00244   // has gone away.  This is the whole point of needing Teuchos::Array and
00245   // having an integrated set of utility classes that all work together!
00246 }
00247 
00248 
00249 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_rcp_std_vector, T )
00250 {
00251   ArrayView<T> av;
00252   {
00253     ArrayRCP<T> ap = arcp(rcp(new std::vector<T>(n)));
00254     av = ap();
00255   }
00256 #ifdef TEUCHOS_DEBUG
00257   TEST_THROW(av.getRawPtr(), DanglingReferenceError);
00258 #endif
00259   // Above, because we wrapped the initial std::vector in an RCP object, we
00260   // can sucessfully detect when the object goes away in debug mode!
00261 }
00262 
00263 
00264 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00265 
00266 
00267 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00268 
00269 
00270 //
00271 // Instantiations
00272 //
00273 
00274 
00275 
00276 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00277 
00278 #  define DEBUG_UNIT_TEST_GROUP( T )
00279 
00280 #else // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00281 
00282 #  define DEBUG_UNIT_TEST_GROUP( T )
00283 
00284 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00285 
00286 
00287 #define UNIT_TEST_GROUP( T ) \
00288   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_construct_zero_size, T ) \
00289   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView, T ) \
00290   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_operator, T ) \
00291   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_func, T ) \
00292   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, assignmentOperator, T ) \
00293   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, iterators, T ) \
00294   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_std_vector, T ) \
00295   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_rcp_std_vector, T ) \
00296   DEBUG_UNIT_TEST_GROUP( T )
00297 
00298 
00299 UNIT_TEST_GROUP(int)
00300 UNIT_TEST_GROUP(float)
00301 UNIT_TEST_GROUP(double)
00302 
00303 
00304 } // namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines