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 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00026 //
00027 // ***********************************************************************
00028 // @HEADER
00029 */
00030 
00031 #include "Array_UnitTest_helpers.hpp"
00032 
00033 #include "Teuchos_implicit_cast.hpp"
00034 
00035 
00036 namespace {
00037 
00038 
00039 using ArrayUnitTestHelpers::n;
00040 using ArrayUnitTestHelpers::generateArray;
00041 using Teuchos::RCP;
00042 using Teuchos::rcp;
00043 using Teuchos::Array;
00044 using Teuchos::ArrayRCP;
00045 using Teuchos::arcp;
00046 using Teuchos::ArrayView;
00047 using Teuchos::arrayView;
00048 using Teuchos::av_const_cast;
00049 using Teuchos::av_reinterpret_cast;
00050 using Teuchos::DanglingReferenceError;
00051 using Teuchos::as;
00052 using Teuchos::null;
00053 using Teuchos::implicit_ptr_cast;
00054 
00055 
00056 TEUCHOS_UNIT_TEST( ArrayView, assignSelf )
00057 {
00058   ArrayView<int> av;
00059   av = av;
00060   TEST_ASSERT(is_null(av));
00061   TEST_ASSERT(!nonnull(av));
00062 }
00063 
00064 
00065 TEUCHOS_UNIT_TEST( ArrayView, assignFuncSelf )
00066 {
00067   Array<int> a = generateArray<int>(n);
00068   ArrayView<int> av = a;
00069   av.assign(av);
00070 }
00071 
00072 
00073 TEUCHOS_UNIT_TEST( ArrayView, av_const_cast_null )
00074 {
00075   ArrayView<const int> av_int1 = null;
00076   ArrayView<int> av_int2 = av_const_cast<int>(av_int1);
00077   TEST_ASSERT(is_null(av_int2));
00078 }
00079 
00080 
00081 TEUCHOS_UNIT_TEST( ArrayView, av_const_cast )
00082 {
00083   ArrayRCP<const int> arcp_int = arcp<int>(n);
00084   ArrayView<const int> av_int1 = arcp_int();
00085   ArrayView<int> av_int2 = av_const_cast<int>(av_int1);
00086   TEST_ASSERT(nonnull(av_int2));
00087   TEST_EQUALITY(av_int2.getRawPtr(), av_int1.getRawPtr());
00088   TEST_EQUALITY(av_int2.getRawPtr(), arcp_int.getRawPtr());
00089 }
00090 
00091 
00092 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_null )
00093 {
00094   ArrayView<char> av_char = null;
00095   ArrayView<int> av_int = av_reinterpret_cast<int>(av_char);
00096   TEST_ASSERT(is_null(av_int));
00097 }
00098 
00099 
00100 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_char_to_int )
00101 {
00102 
00103   const int sizeOfInt = sizeof(int);
00104   const int sizeOfChar = sizeof(char);
00105   const int num_ints = n;
00106   const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
00107   out << "num_ints = " << num_ints << "\n";
00108   out << "num_chars = " << num_chars << "\n";
00109 
00110   ArrayRCP<char> arcp_char = arcp<char>(num_chars);
00111   ArrayView<int> av_int = av_reinterpret_cast<int>(arcp_char());
00112   TEST_EQUALITY(av_int.size(), num_ints);
00113   TEST_EQUALITY(implicit_ptr_cast<void>(&av_int[0]),
00114     implicit_ptr_cast<void>(&arcp_char[0]));
00115   TEST_EQUALITY(implicit_ptr_cast<void>((&av_int[num_ints-1])+1),
00116     implicit_ptr_cast<void>((&arcp_char[num_chars-1])+1));
00117 
00118 }
00119 
00120 
00121 TEUCHOS_UNIT_TEST( ArrayView, av_reinterpret_cast_int_to_char )
00122 {
00123 
00124   const int sizeOfInt = sizeof(int);
00125   const int sizeOfChar = sizeof(char);
00126   const int num_ints = n;
00127   const int num_chars = (num_ints*sizeOfInt)/sizeOfChar;
00128   out << "num_ints = " << num_ints << "\n";
00129   out << "num_chars = " << num_chars << "\n";
00130 
00131   ArrayRCP<int> arcp_int = arcp<int>(num_ints);
00132   ArrayView<char> av_char = av_reinterpret_cast<char>(arcp_int());
00133   TEST_EQUALITY(av_char.size(), num_chars);
00134   TEST_EQUALITY(implicit_ptr_cast<void>(&arcp_int[0]),
00135     implicit_ptr_cast<void>(&av_char[0]));
00136   TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
00137     implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
00138   TEST_EQUALITY(implicit_ptr_cast<void>((&arcp_int[num_ints-1])+1),
00139     implicit_ptr_cast<void>((&av_char[num_chars-1])+1));
00140 
00141 }
00142 
00143 
00144 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView_zero_size, T )
00145 {
00146   Array<T> a;
00147   const ArrayView<T> av = arrayView(a.getRawPtr(), a.size());
00148   TEST_EQUALITY_CONST(av.size(), 0);
00149   TEST_ASSERT(is_null(av));
00150   TEST_ASSERT(!nonnull(av));
00151 }
00152 
00153 
00154 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, arrayView, T )
00155 {
00156   Array<T> a = generateArray<T>(n);
00157   const ArrayView<T> av = arrayView(&a[0], a.size());
00158   TEST_COMPARE_ARRAYS( a, av );
00159 }
00160 
00161 
00162 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, assignmentOperator, T )
00163 {
00164   Array<T> a = generateArray<T>(n);
00165   ArrayView<T> av1;
00166   av1 = a;
00167   ArrayView<T> av2;
00168   av2 = av1;
00169   TEST_EQUALITY( av1.getRawPtr(), a.getRawPtr() );
00170   TEST_EQUALITY( av1.size(), as<int>(a.size()) );
00171   TEST_EQUALITY( av1.getRawPtr(), av2.getRawPtr() );
00172   TEST_EQUALITY( av1.size(), av2.size() );
00173   TEST_COMPARE_ARRAYS( av1, a );
00174   TEST_COMPARE_ARRAYS( av1, av2 );
00175   av1 = null;
00176   TEST_EQUALITY_CONST( av1.getRawPtr(), 0 );
00177   TEST_EQUALITY_CONST( av1.size(), 0 );
00178   av2 = null;
00179   TEST_EQUALITY_CONST( av2.getRawPtr(), 0 );
00180   TEST_EQUALITY_CONST( av2.size(), 0 );
00181 }
00182 
00183 
00184 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, iterators, T )
00185 {
00186   typedef typename ArrayView<T>::iterator iter_t;
00187   typedef Teuchos::ScalarTraits<T> ST;
00188   ECHO(Array<T> a = generateArray<T>(n));
00189   ECHO(ArrayView<T> av = a);
00190   ECHO(const iter_t av_begin = av.begin());
00191   ECHO(const iter_t av_end = av.end());
00192 #ifdef TEUCHOS_DEBUG
00193   TEST_ASSERT(av_begin.shares_resource(av_end));
00194 #endif
00195   ECHO(std::fill(av_begin, av_end, ST::random()));
00196   ECHO(Array<T> a2 = generateArray<T>(n));
00197   ECHO(ArrayView<T> av2 = a2);
00198   ECHO(std::copy(av.begin(), av.end(), av2.begin()));
00199   TEST_COMPARE_ARRAYS(a, a2);
00200 }
00201 
00202 
00203 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_std_vector, T )
00204 {
00205   ArrayView<T> av;
00206   T* badPtr = 0;
00207   {
00208     std::vector<T> v(n);
00209     av = v;
00210     badPtr = &v[0];
00211   }
00212   // Access the raw pointer but it now points to invalid memory!
00213   TEST_EQUALITY(av.getRawPtr(), badPtr);
00214   // Above, we have no way to detect that the underlying std::vector object
00215   // has gone away.  This is the whole point of needing Teuchos::Array and
00216   // having an integrated set of utility classes that all work together!
00217 }
00218 
00219 
00220 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_rcp_std_vector, T )
00221 {
00222   ArrayView<T> av;
00223   {
00224     ArrayRCP<T> ap = arcp(rcp(new std::vector<T>(n)));
00225     av = ap();
00226   }
00227 #ifdef TEUCHOS_DEBUG
00228   TEST_THROW(av.getRawPtr(), DanglingReferenceError);
00229 #endif
00230   // Above, because we wrapped the initial std::vector in an RCP object, we
00231   // can sucessfully detect when the object goes away in debug mode!
00232 }
00233 
00234 
00235 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00236 
00237 
00238 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00239 
00240 
00241 //
00242 // Instantiations
00243 //
00244 
00245 
00246 
00247 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00248 
00249 #  define DEBUG_UNIT_TEST_GROUP( T )
00250 
00251 #else // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00252 
00253 #  define DEBUG_UNIT_TEST_GROUP( T )
00254 
00255 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00256 
00257 
00258 #define UNIT_TEST_GROUP( T ) \
00259   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_zero_size, T ) \
00260   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView, T ) \
00261   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, assignmentOperator, T ) \
00262   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, iterators, T ) \
00263   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_std_vector, T ) \
00264   TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_rcp_std_vector, T ) \
00265   DEBUG_UNIT_TEST_GROUP( T )
00266 
00267 
00268 UNIT_TEST_GROUP(int)
00269 UNIT_TEST_GROUP(float)
00270 UNIT_TEST_GROUP(double)
00271 
00272 
00273 } // namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines