|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
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, raw_ptr_self_view, T ) 00192 { 00193 T *data = new T[10]; 00194 ArrayView<T> view(data, 10); 00195 view = view(0, 5); 00196 TEST_EQUALITY(view.getRawPtr(), data); 00197 TEST_EQUALITY_CONST(view.size(), 5); 00198 ArrayView<const T> cview = view.getConst(); 00199 TEST_EQUALITY(cview.getRawPtr(), const_cast<const T*>(data)); 00200 TEST_EQUALITY_CONST(cview.size(), 5); 00201 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00202 ArrayRCP<const T> cview_arcp = cview.access_private_arcp(); 00203 TEST_EQUALITY(cview_arcp.getRawPtr(), const_cast<const T*>(data)); 00204 TEST_EQUALITY_CONST(cview_arcp.size(), 5); 00205 #endif 00206 delete [] data; 00207 } 00208 00209 00210 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, raw_ptr_self_view_const, T ) 00211 { 00212 T const * data = new T[10]; 00213 ArrayView<const T> view(data, 10); 00214 view = view(0, 5); 00215 TEST_EQUALITY(view.getRawPtr(), data); 00216 TEST_EQUALITY_CONST(view.size(), 5); 00217 ArrayView<const T> cview = view.getConst(); 00218 TEST_EQUALITY(cview.getRawPtr(), data); 00219 TEST_EQUALITY_CONST(cview.size(), 5); 00220 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00221 ArrayRCP<const T> cview_arcp = cview.access_private_arcp(); 00222 TEST_EQUALITY(cview_arcp.getRawPtr(), data); 00223 TEST_EQUALITY_CONST(cview_arcp.size(), 5); 00224 #endif 00225 delete [] data; 00226 } 00227 00228 00229 template<typename T> 00230 void resizeRawView( 00231 Teuchos::ArrayView<T> &view_inout, Teuchos::Ordinal offset, Teuchos::Ordinal size 00232 ) 00233 { 00234 if (view_inout.size() == 0 && size == 0) { return; } 00235 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00236 const T &next_to_last = view_inout[offset+size-1]; 00237 (void)next_to_last; 00238 #endif 00239 view_inout = arrayView<T>(&view_inout[offset], size); 00240 } 00241 00242 00243 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, resize_raw_ptr_self_view, T ) 00244 { 00245 T *data = new T[10]; 00246 ArrayView<T> view(data, 10); 00247 resizeRawView(view, 0, 5); 00248 TEST_EQUALITY(view.getRawPtr(), data); 00249 TEST_EQUALITY_CONST(view.size(), 5); 00250 delete [] data; 00251 // NOTE: The above works because we are creating a completely new ArrayView 00252 // object and are not viewing the original array object which is going away. 00253 } 00254 00255 00256 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, assignmentOperator, T ) 00257 { 00258 Array<T> a = generateArray<T>(n); 00259 ArrayView<T> av1; 00260 av1 = a; 00261 ArrayView<T> av2; 00262 av2 = av1; 00263 TEST_EQUALITY( av1.getRawPtr(), a.getRawPtr() ); 00264 TEST_EQUALITY( av1.size(), as<int>(a.size()) ); 00265 TEST_EQUALITY( av1.getRawPtr(), av2.getRawPtr() ); 00266 TEST_EQUALITY( av1.size(), av2.size() ); 00267 TEST_COMPARE_ARRAYS( av1, a ); 00268 TEST_COMPARE_ARRAYS( av1, av2 ); 00269 av1 = null; 00270 TEST_EQUALITY_CONST( av1.getRawPtr(), 0 ); 00271 TEST_EQUALITY_CONST( av1.size(), 0 ); 00272 av2 = null; 00273 TEST_EQUALITY_CONST( av2.getRawPtr(), 0 ); 00274 TEST_EQUALITY_CONST( av2.size(), 0 ); 00275 } 00276 00277 00278 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, iterators, T ) 00279 { 00280 typedef typename ArrayView<T>::iterator iter_t; 00281 typedef Teuchos::ScalarTraits<T> ST; 00282 ECHO(Array<T> a = generateArray<T>(n)); 00283 ECHO(ArrayView<T> av = a); 00284 ECHO(const iter_t av_begin = av.begin()); 00285 ECHO(const iter_t av_end = av.end()); 00286 #ifdef TEUCHOS_DEBUG 00287 TEST_ASSERT(av_begin.shares_resource(av_end)); 00288 #endif 00289 ECHO(std::fill(av_begin, av_end, ST::random())); 00290 ECHO(Array<T> a2 = generateArray<T>(n)); 00291 ECHO(ArrayView<T> av2 = a2); 00292 ECHO(std::copy(av.begin(), av.end(), av2.begin())); 00293 TEST_COMPARE_ARRAYS(a, a2); 00294 } 00295 00296 00297 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_std_vector, T ) 00298 { 00299 ArrayView<T> av; 00300 T* badPtr = 0; 00301 { 00302 std::vector<T> v(n); 00303 av = v; 00304 badPtr = &v[0]; 00305 } 00306 // Access the raw pointer but it now points to invalid memory! 00307 TEST_EQUALITY(av.getRawPtr(), badPtr); 00308 // Above, we have no way to detect that the underlying std::vector object 00309 // has gone away. This is the whole point of needing Teuchos::Array and 00310 // having an integrated set of utility classes that all work together! 00311 } 00312 00313 00314 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArrayView, danglingView_rcp_std_vector, T ) 00315 { 00316 ArrayView<T> av; 00317 { 00318 ArrayRCP<T> ap = arcp(rcp(new std::vector<T>(n))); 00319 av = ap(); 00320 } 00321 #ifdef TEUCHOS_DEBUG 00322 TEST_THROW(av.getRawPtr(), DanglingReferenceError); 00323 #endif 00324 // Above, because we wrapped the initial std::vector in an RCP object, we 00325 // can sucessfully detect when the object goes away in debug mode! 00326 } 00327 00328 00329 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00330 00331 00332 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00333 00334 00335 // 00336 // Instantiations 00337 // 00338 00339 00340 00341 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00342 00343 # define DEBUG_UNIT_TEST_GROUP( T ) 00344 00345 #else // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00346 00347 # define DEBUG_UNIT_TEST_GROUP( T ) 00348 00349 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00350 00351 00352 #define UNIT_TEST_GROUP( T ) \ 00353 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView_construct_zero_size, T ) \ 00354 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, arrayView, T ) \ 00355 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_operator, T ) \ 00356 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, null_zero_ArrayView_func, T ) \ 00357 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, raw_ptr_self_view, T ) \ 00358 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, raw_ptr_self_view_const, T ) \ 00359 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, resize_raw_ptr_self_view, T ) \ 00360 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, assignmentOperator, T ) \ 00361 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, iterators, T ) \ 00362 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_std_vector, T ) \ 00363 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( ArrayView, danglingView_rcp_std_vector, T ) \ 00364 DEBUG_UNIT_TEST_GROUP( T ) 00365 00366 00367 UNIT_TEST_GROUP(int) 00368 UNIT_TEST_GROUP(float) 00369 UNIT_TEST_GROUP(double) 00370 00371 00372 } // namespace
1.7.6.1