|
Teuchos - Trilinos Tools Package 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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef TEUCHOS_ARRAY_VIEW_HPP 00030 #define TEUCHOS_ARRAY_VIEW_HPP 00031 00032 00033 #include "Teuchos_ArrayViewDecl.hpp" 00034 #include "Teuchos_ArrayRCP.hpp" 00035 #include "Teuchos_as.hpp" 00036 00037 00038 namespace Teuchos { 00039 00040 00041 // Constructors/Destructors 00042 00043 00044 template<class T> inline 00045 ArrayView<T>::ArrayView( ENull ) 00046 :ptr_(0), size_(0) 00047 { 00048 setUpIterators(); 00049 } 00050 00051 00052 template<class T> inline 00053 ArrayView<T>::ArrayView( T* p, size_type size_in, const ERCPNodeLookup rcpNodeLookup ) 00054 :ptr_(p), size_(size_in) 00055 { 00056 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00057 TEST_FOR_EXCEPT( p != 0 && size_in <= 0 ); 00058 TEST_FOR_EXCEPT( p == 0 && size_in != 0 ); 00059 setUpIterators(rcpNodeLookup); 00060 #endif 00061 } 00062 00063 00064 template<class T> inline 00065 ArrayView<T>::ArrayView(const ArrayView<T>& array) 00066 :ptr_(array.ptr_), size_(array.size_) 00067 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00068 ,arcp_(array.arcp_) 00069 #endif 00070 {} 00071 00072 00073 template<class T> inline 00074 ArrayView<T>::ArrayView( 00075 std::vector<typename ConstTypeTraits<T>::NonConstType>& vec 00076 ) 00077 : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size()) 00078 { 00079 setUpIterators(); 00080 } 00081 00082 00083 template<class T> inline 00084 ArrayView<T>::ArrayView( 00085 const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec 00086 ) 00087 : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size()) 00088 { 00089 setUpIterators(); 00090 } 00091 00092 00093 template<class T> inline 00094 ArrayView<T>& ArrayView<T>::operator=(const ArrayView<T>& array) 00095 { 00096 ptr_ = array.ptr_; 00097 size_ = array.size_; 00098 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00099 arcp_ = array.arcp_; 00100 #endif 00101 return *this; 00102 } 00103 00104 00105 template<class T> inline 00106 ArrayView<T>::~ArrayView() 00107 {} 00108 00109 00110 // General query functions 00111 00112 00113 template<class T> 00114 inline 00115 bool ArrayView<T>::is_null() const 00116 { 00117 return ptr_ == 0; 00118 } 00119 00120 00121 template<class T> inline 00122 typename ArrayView<T>::size_type ArrayView<T>::size() const 00123 { 00124 debug_assert_valid_ptr(); 00125 return size_; 00126 } 00127 00128 00129 template<typename T> 00130 std::string ArrayView<T>::toString() const 00131 { 00132 00133 using Teuchos::as; 00134 std::ostringstream ss; 00135 00136 debug_assert_valid_ptr(); 00137 00138 ss << "{"; 00139 00140 for (int i=0; i < as<int>(size()); ++i) 00141 { 00142 ss << operator[](i); 00143 if (i < size()-1) ss << ", "; 00144 } 00145 ss << "}"; 00146 00147 return ss.str(); 00148 00149 } 00150 00151 00152 // Element Access Functions 00153 00154 00155 template<class T> inline 00156 T* ArrayView<T>::getRawPtr() const 00157 { 00158 debug_assert_valid_ptr(); 00159 return ptr_; 00160 } 00161 00162 00163 template<class T> inline 00164 T& ArrayView<T>::operator[](size_type i) const 00165 { 00166 debug_assert_valid_ptr(); 00167 debug_assert_in_range(i,1); 00168 return ptr_[i]; 00169 } 00170 00171 00172 template<class T> inline 00173 T& ArrayView<T>::front() const 00174 { 00175 debug_assert_not_null(); 00176 debug_assert_valid_ptr(); 00177 return *ptr_; 00178 } 00179 00180 00181 template<class T> inline 00182 T& ArrayView<T>::back() const 00183 { 00184 debug_assert_not_null(); 00185 debug_assert_valid_ptr(); 00186 return *(ptr_+size_-1); 00187 } 00188 00189 00190 // Views 00191 00192 00193 template<class T> inline 00194 ArrayView<T> ArrayView<T>::view(size_type offset, size_type size_in) const 00195 { 00196 debug_assert_valid_ptr(); 00197 debug_assert_in_range(offset, size_in); 00198 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00199 return arcp_(offset, size_in); 00200 #endif 00201 return ArrayView<T>(ptr_+offset, size_in); 00202 // WARNING: The above code had better be correct since we are using raw 00203 // pointer arithmetic! 00204 } 00205 00206 00207 template<class T> inline 00208 ArrayView<T> ArrayView<T>::operator()(size_type offset, size_type size_in) const 00209 { 00210 return view(offset, size_in); 00211 } 00212 00213 00214 template<class T> inline 00215 const ArrayView<T>& ArrayView<T>::operator()() const 00216 { 00217 debug_assert_valid_ptr(); 00218 return *this; 00219 } 00220 00221 00222 template<class T> inline 00223 ArrayView<const T> ArrayView<T>::getConst() const 00224 { 00225 debug_assert_valid_ptr(); 00226 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00227 return arcp_.getConst()(); 00228 #endif 00229 return ArrayView<const T>(ptr_, size_); 00230 } 00231 00232 00233 template<class T> inline 00234 ArrayView<T>::operator ArrayView<const T>() const 00235 { 00236 return getConst(); 00237 } 00238 00239 00240 // Assignment 00241 00242 00243 template<class T> 00244 void ArrayView<T>::assign(const ArrayView<const T>& array) const 00245 { 00246 debug_assert_valid_ptr(); 00247 debug_assert_not_null(); 00248 if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size()) 00249 return; // Assignment to self 00250 debug_assert_in_range(0,array.size()); 00251 std::copy( array.begin(), array.end(), this->begin() ); 00252 // Note: Above, in debug mode, the iterators are range checked! In 00253 // optimized mode, these are raw pointers which should run very fast! 00254 } 00255 00256 00257 // Standard Container-Like Functions 00258 00259 00260 template<class T> 00261 typename ArrayView<T>::iterator ArrayView<T>::begin() const 00262 { 00263 debug_assert_valid_ptr(); 00264 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00265 return arcp_.create_weak(); 00266 #else 00267 return ptr_; 00268 #endif 00269 } 00270 00271 00272 template<class T> 00273 typename ArrayView<T>::iterator ArrayView<T>::end() const 00274 { 00275 debug_assert_valid_ptr(); 00276 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00277 return arcp_.create_weak() + size_; 00278 #else 00279 return ptr_ + size_; 00280 #endif 00281 } 00282 00283 00284 // Assertion Functions. 00285 00286 00287 template<class T> 00288 const ArrayView<T>& ArrayView<T>::assert_not_null() const 00289 { 00290 if(!ptr_) 00291 throw_null_ptr_error(typeName(*this)); 00292 return *this; 00293 } 00294 00295 00296 template<class T> 00297 const ArrayView<T>& 00298 ArrayView<T>::assert_in_range(size_type offset, size_type size_in) const 00299 { 00300 00301 assert_not_null(); 00302 TEST_FOR_EXCEPTION( 00303 !( 00304 ( 0 <= offset && offset+size_in <= this->size() ) 00305 && 00306 size_in >= 0 00307 ), 00308 Teuchos::RangeError, 00309 typeName(*this)<<"::assert_in_range():" 00310 " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")" 00311 " does not lie in the range [0,"<<this->size()<<")!" 00312 ); 00313 return*this; 00314 } 00315 00316 00317 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00318 00319 template<class T> 00320 ArrayView<T>::ArrayView( const ArrayRCP<T> &arcp ) 00321 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp) 00322 {} 00323 00324 00325 template<class T> 00326 ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp) 00327 : ptr_(p), size_(size_in), arcp_(arcp) 00328 {} 00329 00330 00331 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00332 00333 00334 // private 00335 00336 00337 template<class T> 00338 void ArrayView<T>::setUpIterators(const ERCPNodeLookup rcpNodeLookup) 00339 { 00340 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00341 if (ptr_ && arcp_.is_null()) { 00342 arcp_ = ArrayRCP<T>(ptr_, 0, size_, false, rcpNodeLookup); 00343 } 00344 #endif 00345 } 00346 00347 00348 } // namespace Teuchos 00349 00350 00351 // 00352 // Nonmember helper functions 00353 // 00354 00355 00356 template<class T> inline 00357 Teuchos::ArrayView<T> 00358 Teuchos::arrayView( T* p, typename ArrayView<T>::size_type size ) 00359 { 00360 if (size == 0) 00361 return null; 00362 return ArrayView<T>(p, size); 00363 } 00364 00365 00366 template<class T> inline 00367 Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec ) 00368 { 00369 if (vec.size() == 0) 00370 return null; 00371 return ArrayView<T>(vec); 00372 } 00373 00374 00375 template<class T> inline 00376 Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec ) 00377 { 00378 if (vec.size() == 0) 00379 return null; 00380 return ArrayView<const T>(vec); 00381 } 00382 00383 00384 #ifndef __sun 00385 00386 template<class T> inline 00387 std::vector<T> Teuchos::createVector( const ArrayView<T> &av ) 00388 { 00389 std::vector<T> v(av.begin(), av.end()); 00390 return v; 00391 } 00392 00393 #endif // __sun 00394 00395 00396 template<class T> inline 00397 std::vector<T> Teuchos::createVector( const ArrayView<const T> &av ) 00398 { 00399 std::vector<T> v(av.begin(), av.end()); 00400 return v; 00401 } 00402 00403 00404 template<class T> inline 00405 bool Teuchos::is_null( const ArrayView<T> &av ) 00406 { 00407 return av.is_null(); 00408 } 00409 00410 00411 template<class T> inline 00412 bool Teuchos::nonnull( const ArrayView<T> &av ) 00413 { 00414 return !av.is_null(); 00415 } 00416 00417 00418 template<class T> 00419 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p ) 00420 { 00421 return out << p.toString(); 00422 } 00423 00424 00425 template<class T2, class T1> 00426 REFCOUNTPTR_INLINE 00427 Teuchos::ArrayView<T2> 00428 Teuchos::av_const_cast(const ArrayView<T1>& p1) 00429 { 00430 T2 *ptr2 = const_cast<T2*>(p1.getRawPtr()); 00431 return ArrayView<T2>(ptr2, p1.size()); 00432 // Note: Above is just fine even if p1.get()==NULL! 00433 } 00434 00435 00436 template<class T2, class T1> 00437 REFCOUNTPTR_INLINE 00438 Teuchos::ArrayView<T2> 00439 Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1) 00440 { 00441 typedef typename ArrayView<T1>::size_type size_type; 00442 const int sizeOfT1 = sizeof(T1); 00443 const int sizeOfT2 = sizeof(T2); 00444 size_type size2 = (p1.size()*sizeOfT1) / sizeOfT2; 00445 T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr()); 00446 return ArrayView<T2>( 00447 ptr2, size2 00448 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00449 ,arcp_reinterpret_cast<T2>(p1.access_private_arcp()) 00450 #endif 00451 ); 00452 // Note: Above is just fine even if p1.get()==NULL! 00453 } 00454 00455 00456 #endif // TEUCHOS_ARRAY_VIEW_HPP
1.7.4