|
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 #ifndef TEUCHOS_ARRAY_VIEW_HPP 00043 #define TEUCHOS_ARRAY_VIEW_HPP 00044 00045 00046 #include "Teuchos_ArrayViewDecl.hpp" 00047 #include "Teuchos_ArrayRCP.hpp" 00048 #include "Teuchos_as.hpp" 00049 00050 00051 namespace Teuchos { 00052 00053 00054 // Constructors/Destructors 00055 00056 00057 template<class T> inline 00058 ArrayView<T>::ArrayView( ENull ) 00059 :ptr_(0), size_(0) 00060 { 00061 setUpIterators(); 00062 } 00063 00064 00065 template<class T> inline 00066 ArrayView<T>::ArrayView( T* p, size_type size_in, const ERCPNodeLookup rcpNodeLookup ) 00067 :ptr_(p), size_(size_in) 00068 { 00069 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00070 TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 ); 00071 TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 ); 00072 setUpIterators(rcpNodeLookup); 00073 #endif 00074 } 00075 00076 00077 template<class T> inline 00078 ArrayView<T>::ArrayView(const ArrayView<T>& array) 00079 :ptr_(array.ptr_), size_(array.size_) 00080 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00081 ,arcp_(array.arcp_) 00082 #endif 00083 {} 00084 00085 00086 template<class T> inline 00087 ArrayView<T>::ArrayView( 00088 std::vector<typename ConstTypeTraits<T>::NonConstType>& vec 00089 ) 00090 : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size()) 00091 { 00092 setUpIterators(); 00093 } 00094 00095 00096 template<class T> inline 00097 ArrayView<T>::ArrayView( 00098 const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec 00099 ) 00100 : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size()) 00101 { 00102 setUpIterators(); 00103 } 00104 00105 00106 template<class T> inline 00107 ArrayView<T>& ArrayView<T>::operator=(const ArrayView<T>& array) 00108 { 00109 ptr_ = array.ptr_; 00110 size_ = array.size_; 00111 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00112 arcp_ = array.arcp_; 00113 #endif 00114 return *this; 00115 } 00116 00117 00118 template<class T> inline 00119 ArrayView<T>::~ArrayView() 00120 {} 00121 00122 00123 // General query functions 00124 00125 00126 template<class T> 00127 inline 00128 bool ArrayView<T>::is_null() const 00129 { 00130 return ptr_ == 0; 00131 } 00132 00133 00134 template<class T> inline 00135 typename ArrayView<T>::size_type ArrayView<T>::size() const 00136 { 00137 debug_assert_valid_ptr(); 00138 return size_; 00139 } 00140 00141 00142 template<typename T> 00143 std::string ArrayView<T>::toString() const 00144 { 00145 00146 using Teuchos::as; 00147 std::ostringstream ss; 00148 00149 debug_assert_valid_ptr(); 00150 00151 ss << "{"; 00152 for (size_type i = 0; i < size (); ++i) { 00153 // NOTE: This depends on std::ostream::operator<<(const T&). 00154 ss << operator[] (i); 00155 if (i + 1 < size ()) { 00156 ss << ", "; 00157 } 00158 } 00159 ss << "}"; 00160 return ss.str (); 00161 } 00162 00163 00164 // Specialization for float. We use sufficient precision that no 00165 // digits are lost after writing to string and reading back in again. 00166 template<> 00167 TEUCHOS_LIB_DLL_EXPORT std::string 00168 ArrayView<float>::toString() const; 00169 00170 // Specialization for (const) float. We use sufficient precision that no 00171 // digits are lost after writing to string and reading back in again. 00172 template<> 00173 TEUCHOS_LIB_DLL_EXPORT std::string 00174 ArrayView<const float>::toString() const; 00175 00176 // Specialization for double. We use sufficient precision that no 00177 // digits are lost after writing to string and reading back in again. 00178 template<> 00179 TEUCHOS_LIB_DLL_EXPORT std::string 00180 ArrayView<double>::toString() const; 00181 00182 // Specialization for (const) double. We use sufficient precision that no 00183 // digits are lost after writing to string and reading back in again. 00184 template<> 00185 TEUCHOS_LIB_DLL_EXPORT std::string 00186 ArrayView<const double>::toString() const; 00187 00188 00189 // Element Access Functions 00190 00191 00192 template<class T> inline 00193 T* ArrayView<T>::getRawPtr() const 00194 { 00195 debug_assert_valid_ptr(); 00196 return ptr_; 00197 } 00198 00199 00200 template<class T> inline 00201 T& ArrayView<T>::operator[](size_type i) const 00202 { 00203 debug_assert_valid_ptr(); 00204 debug_assert_in_range(i,1); 00205 return ptr_[i]; 00206 } 00207 00208 00209 template<class T> inline 00210 T& ArrayView<T>::front() const 00211 { 00212 debug_assert_not_null(); 00213 debug_assert_valid_ptr(); 00214 return *ptr_; 00215 } 00216 00217 00218 template<class T> inline 00219 T& ArrayView<T>::back() const 00220 { 00221 debug_assert_not_null(); 00222 debug_assert_valid_ptr(); 00223 return *(ptr_+size_-1); 00224 } 00225 00226 00227 // Views 00228 00229 00230 template<class T> inline 00231 ArrayView<T> ArrayView<T>::view(size_type offset, size_type size_in) const 00232 { 00233 if (size_in == 0) { 00234 return null; 00235 } 00236 debug_assert_valid_ptr(); 00237 debug_assert_in_range(offset, size_in); 00238 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00239 return arcp_(offset, size_in); 00240 #endif 00241 return ArrayView<T>(ptr_+offset, size_in); 00242 // WARNING: The above code had better be correct since we are using raw 00243 // pointer arithmetic! 00244 } 00245 00246 00247 template<class T> inline 00248 ArrayView<T> ArrayView<T>::operator()(size_type offset, size_type size_in) const 00249 { 00250 return view(offset, size_in); 00251 } 00252 00253 00254 template<class T> inline 00255 const ArrayView<T>& ArrayView<T>::operator()() const 00256 { 00257 debug_assert_valid_ptr(); 00258 return *this; 00259 } 00260 00261 00262 template<class T> inline 00263 ArrayView<const T> ArrayView<T>::getConst() const 00264 { 00265 debug_assert_valid_ptr(); 00266 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00267 return arcp_.getConst()(); 00268 #endif 00269 return ArrayView<const T>(ptr_, size_); 00270 } 00271 00272 00273 template<class T> inline 00274 ArrayView<T>::operator ArrayView<const T>() const 00275 { 00276 return getConst(); 00277 } 00278 00279 00280 // Assignment 00281 00282 00283 template<class T> 00284 void ArrayView<T>::assign(const ArrayView<const T>& array) const 00285 { 00286 debug_assert_valid_ptr(); 00287 debug_assert_not_null(); 00288 if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size()) 00289 return; // Assignment to self 00290 debug_assert_in_range(0,array.size()); 00291 std::copy( array.begin(), array.end(), this->begin() ); 00292 // Note: Above, in debug mode, the iterators are range checked! In 00293 // optimized mode, these are raw pointers which should run very fast! 00294 } 00295 00296 00297 // Standard Container-Like Functions 00298 00299 00300 template<class T> 00301 typename ArrayView<T>::iterator ArrayView<T>::begin() const 00302 { 00303 debug_assert_valid_ptr(); 00304 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00305 return arcp_.create_weak(); 00306 #else 00307 return ptr_; 00308 #endif 00309 } 00310 00311 00312 template<class T> 00313 typename ArrayView<T>::iterator ArrayView<T>::end() const 00314 { 00315 debug_assert_valid_ptr(); 00316 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00317 return arcp_.create_weak() + size_; 00318 #else 00319 return ptr_ + size_; 00320 #endif 00321 } 00322 00323 00324 // Assertion Functions. 00325 00326 00327 template<class T> 00328 const ArrayView<T>& ArrayView<T>::assert_not_null() const 00329 { 00330 if(!ptr_) 00331 throw_null_ptr_error(typeName(*this)); 00332 return *this; 00333 } 00334 00335 00336 template<class T> 00337 const ArrayView<T>& 00338 ArrayView<T>::assert_in_range(size_type offset, size_type size_in) const 00339 { 00340 assert_not_null(); 00341 TEUCHOS_TEST_FOR_EXCEPTION( size_in == as<size_type>(0), RangeError, 00342 "Error, size=0 is not allowed!" ); 00343 TEUCHOS_TEST_FOR_EXCEPTION( 00344 !( 00345 ( 0 <= offset && offset+size_in <= this->size() ) 00346 && 00347 size_in >= 0 00348 ), 00349 RangeError, 00350 typeName(*this)<<"::assert_in_range():" 00351 " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")" 00352 " does not lie in the range [0,"<<this->size()<<")!" 00353 ); 00354 return*this; 00355 } 00356 00357 00358 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00359 00360 template<class T> 00361 ArrayView<T>::ArrayView( const ArrayRCP<T> &arcp ) 00362 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp) 00363 {} 00364 00365 00366 template<class T> 00367 ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp) 00368 : ptr_(p), size_(size_in), arcp_(arcp) 00369 {} 00370 00371 00372 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00373 00374 00375 // private 00376 00377 00378 template<class T> 00379 void ArrayView<T>::setUpIterators(const ERCPNodeLookup rcpNodeLookup) 00380 { 00381 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00382 if (ptr_ && arcp_.is_null()) { 00383 arcp_ = ArrayRCP<T>(ptr_, 0, size_, false, rcpNodeLookup); 00384 } 00385 #endif 00386 } 00387 00388 00389 } // namespace Teuchos 00390 00391 00392 // 00393 // Nonmember helper functions 00394 // 00395 00396 00397 template<class T> inline 00398 Teuchos::ArrayView<T> 00399 Teuchos::arrayView( T* p, typename ArrayView<T>::size_type size ) 00400 { 00401 if (size == 0) 00402 return null; 00403 return ArrayView<T>(p, size); 00404 } 00405 00406 00407 template<class T> inline 00408 Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec ) 00409 { 00410 if (vec.size() == 0) 00411 return null; 00412 return ArrayView<T>(vec); 00413 } 00414 00415 00416 template<class T> inline 00417 Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec ) 00418 { 00419 if (vec.size() == 0) 00420 return null; 00421 return ArrayView<const T>(vec); 00422 } 00423 00424 00425 #ifndef __sun 00426 00427 template<class T> inline 00428 std::vector<T> Teuchos::createVector( const ArrayView<T> &av ) 00429 { 00430 std::vector<T> v(av.begin(), av.end()); 00431 return v; 00432 } 00433 00434 #endif // __sun 00435 00436 00437 template<class T> inline 00438 std::vector<T> Teuchos::createVector( const ArrayView<const T> &av ) 00439 { 00440 std::vector<T> v(av.begin(), av.end()); 00441 return v; 00442 } 00443 00444 00445 template<class T> inline 00446 bool Teuchos::is_null( const ArrayView<T> &av ) 00447 { 00448 return av.is_null(); 00449 } 00450 00451 00452 template<class T> inline 00453 bool Teuchos::nonnull( const ArrayView<T> &av ) 00454 { 00455 return !av.is_null(); 00456 } 00457 00458 00459 template<class T> 00460 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p ) 00461 { 00462 return out << p.toString(); 00463 } 00464 00465 00466 template<class T2, class T1> 00467 REFCOUNTPTR_INLINE 00468 Teuchos::ArrayView<T2> 00469 Teuchos::av_const_cast(const ArrayView<T1>& p1) 00470 { 00471 T2 *ptr2 = const_cast<T2*>(p1.getRawPtr()); 00472 return ArrayView<T2>(ptr2, p1.size()); 00473 // Note: Above is just fine even if p1.get()==NULL! 00474 } 00475 00476 00477 template<class T2, class T1> 00478 REFCOUNTPTR_INLINE 00479 Teuchos::ArrayView<T2> 00480 Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1) 00481 { 00482 typedef typename ArrayView<T1>::size_type size_type; 00483 const int sizeOfT1 = sizeof(T1); 00484 const int sizeOfT2 = sizeof(T2); 00485 size_type size2 = (p1.size()*sizeOfT1) / sizeOfT2; 00486 T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr()); 00487 return ArrayView<T2>( 00488 ptr2, size2 00489 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00490 ,arcp_reinterpret_cast<T2>(p1.access_private_arcp()) 00491 #endif 00492 ); 00493 // Note: Above is just fine even if p1.get()==NULL! 00494 } 00495 00496 00497 #endif // TEUCHOS_ARRAY_VIEW_HPP
1.7.6.1