|
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 // 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 00153 for (int i=0; i < as<int>(size()); ++i) 00154 { 00155 ss << operator[](i); 00156 if (i < size()-1) ss << ", "; 00157 } 00158 ss << "}"; 00159 00160 return ss.str(); 00161 00162 } 00163 00164 00165 // Element Access Functions 00166 00167 00168 template<class T> inline 00169 T* ArrayView<T>::getRawPtr() const 00170 { 00171 debug_assert_valid_ptr(); 00172 return ptr_; 00173 } 00174 00175 00176 template<class T> inline 00177 T& ArrayView<T>::operator[](size_type i) const 00178 { 00179 debug_assert_valid_ptr(); 00180 debug_assert_in_range(i,1); 00181 return ptr_[i]; 00182 } 00183 00184 00185 template<class T> inline 00186 T& ArrayView<T>::front() const 00187 { 00188 debug_assert_not_null(); 00189 debug_assert_valid_ptr(); 00190 return *ptr_; 00191 } 00192 00193 00194 template<class T> inline 00195 T& ArrayView<T>::back() const 00196 { 00197 debug_assert_not_null(); 00198 debug_assert_valid_ptr(); 00199 return *(ptr_+size_-1); 00200 } 00201 00202 00203 // Views 00204 00205 00206 template<class T> inline 00207 ArrayView<T> ArrayView<T>::view(size_type offset, size_type size_in) const 00208 { 00209 if (size_in == 0) { 00210 return null; 00211 } 00212 debug_assert_valid_ptr(); 00213 debug_assert_in_range(offset, size_in); 00214 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00215 return arcp_(offset, size_in); 00216 #endif 00217 return ArrayView<T>(ptr_+offset, size_in); 00218 // WARNING: The above code had better be correct since we are using raw 00219 // pointer arithmetic! 00220 } 00221 00222 00223 template<class T> inline 00224 ArrayView<T> ArrayView<T>::operator()(size_type offset, size_type size_in) const 00225 { 00226 return view(offset, size_in); 00227 } 00228 00229 00230 template<class T> inline 00231 const ArrayView<T>& ArrayView<T>::operator()() const 00232 { 00233 debug_assert_valid_ptr(); 00234 return *this; 00235 } 00236 00237 00238 template<class T> inline 00239 ArrayView<const T> ArrayView<T>::getConst() const 00240 { 00241 debug_assert_valid_ptr(); 00242 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00243 return arcp_.getConst()(); 00244 #endif 00245 return ArrayView<const T>(ptr_, size_); 00246 } 00247 00248 00249 template<class T> inline 00250 ArrayView<T>::operator ArrayView<const T>() const 00251 { 00252 return getConst(); 00253 } 00254 00255 00256 // Assignment 00257 00258 00259 template<class T> 00260 void ArrayView<T>::assign(const ArrayView<const T>& array) const 00261 { 00262 debug_assert_valid_ptr(); 00263 debug_assert_not_null(); 00264 if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size()) 00265 return; // Assignment to self 00266 debug_assert_in_range(0,array.size()); 00267 std::copy( array.begin(), array.end(), this->begin() ); 00268 // Note: Above, in debug mode, the iterators are range checked! In 00269 // optimized mode, these are raw pointers which should run very fast! 00270 } 00271 00272 00273 // Standard Container-Like Functions 00274 00275 00276 template<class T> 00277 typename ArrayView<T>::iterator ArrayView<T>::begin() const 00278 { 00279 debug_assert_valid_ptr(); 00280 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00281 return arcp_.create_weak(); 00282 #else 00283 return ptr_; 00284 #endif 00285 } 00286 00287 00288 template<class T> 00289 typename ArrayView<T>::iterator ArrayView<T>::end() const 00290 { 00291 debug_assert_valid_ptr(); 00292 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00293 return arcp_.create_weak() + size_; 00294 #else 00295 return ptr_ + size_; 00296 #endif 00297 } 00298 00299 00300 // Assertion Functions. 00301 00302 00303 template<class T> 00304 const ArrayView<T>& ArrayView<T>::assert_not_null() const 00305 { 00306 if(!ptr_) 00307 throw_null_ptr_error(typeName(*this)); 00308 return *this; 00309 } 00310 00311 00312 template<class T> 00313 const ArrayView<T>& 00314 ArrayView<T>::assert_in_range(size_type offset, size_type size_in) const 00315 { 00316 assert_not_null(); 00317 TEUCHOS_TEST_FOR_EXCEPTION( size_in == as<size_type>(0), RangeError, 00318 "Error, size=0 is not allowed!" ); 00319 TEUCHOS_TEST_FOR_EXCEPTION( 00320 !( 00321 ( 0 <= offset && offset+size_in <= this->size() ) 00322 && 00323 size_in >= 0 00324 ), 00325 RangeError, 00326 typeName(*this)<<"::assert_in_range():" 00327 " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")" 00328 " does not lie in the range [0,"<<this->size()<<")!" 00329 ); 00330 return*this; 00331 } 00332 00333 00334 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00335 00336 template<class T> 00337 ArrayView<T>::ArrayView( const ArrayRCP<T> &arcp ) 00338 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp) 00339 {} 00340 00341 00342 template<class T> 00343 ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp) 00344 : ptr_(p), size_(size_in), arcp_(arcp) 00345 {} 00346 00347 00348 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00349 00350 00351 // private 00352 00353 00354 template<class T> 00355 void ArrayView<T>::setUpIterators(const ERCPNodeLookup rcpNodeLookup) 00356 { 00357 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00358 if (ptr_ && arcp_.is_null()) { 00359 arcp_ = ArrayRCP<T>(ptr_, 0, size_, false, rcpNodeLookup); 00360 } 00361 #endif 00362 } 00363 00364 00365 } // namespace Teuchos 00366 00367 00368 // 00369 // Nonmember helper functions 00370 // 00371 00372 00373 template<class T> inline 00374 Teuchos::ArrayView<T> 00375 Teuchos::arrayView( T* p, typename ArrayView<T>::size_type size ) 00376 { 00377 if (size == 0) 00378 return null; 00379 return ArrayView<T>(p, size); 00380 } 00381 00382 00383 template<class T> inline 00384 Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec ) 00385 { 00386 if (vec.size() == 0) 00387 return null; 00388 return ArrayView<T>(vec); 00389 } 00390 00391 00392 template<class T> inline 00393 Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec ) 00394 { 00395 if (vec.size() == 0) 00396 return null; 00397 return ArrayView<const T>(vec); 00398 } 00399 00400 00401 #ifndef __sun 00402 00403 template<class T> inline 00404 std::vector<T> Teuchos::createVector( const ArrayView<T> &av ) 00405 { 00406 std::vector<T> v(av.begin(), av.end()); 00407 return v; 00408 } 00409 00410 #endif // __sun 00411 00412 00413 template<class T> inline 00414 std::vector<T> Teuchos::createVector( const ArrayView<const T> &av ) 00415 { 00416 std::vector<T> v(av.begin(), av.end()); 00417 return v; 00418 } 00419 00420 00421 template<class T> inline 00422 bool Teuchos::is_null( const ArrayView<T> &av ) 00423 { 00424 return av.is_null(); 00425 } 00426 00427 00428 template<class T> inline 00429 bool Teuchos::nonnull( const ArrayView<T> &av ) 00430 { 00431 return !av.is_null(); 00432 } 00433 00434 00435 template<class T> 00436 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p ) 00437 { 00438 return out << p.toString(); 00439 } 00440 00441 00442 template<class T2, class T1> 00443 REFCOUNTPTR_INLINE 00444 Teuchos::ArrayView<T2> 00445 Teuchos::av_const_cast(const ArrayView<T1>& p1) 00446 { 00447 T2 *ptr2 = const_cast<T2*>(p1.getRawPtr()); 00448 return ArrayView<T2>(ptr2, p1.size()); 00449 // Note: Above is just fine even if p1.get()==NULL! 00450 } 00451 00452 00453 template<class T2, class T1> 00454 REFCOUNTPTR_INLINE 00455 Teuchos::ArrayView<T2> 00456 Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1) 00457 { 00458 typedef typename ArrayView<T1>::size_type size_type; 00459 const int sizeOfT1 = sizeof(T1); 00460 const int sizeOfT2 = sizeof(T2); 00461 size_type size2 = (p1.size()*sizeOfT1) / sizeOfT2; 00462 T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr()); 00463 return ArrayView<T2>( 00464 ptr2, size2 00465 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00466 ,arcp_reinterpret_cast<T2>(p1.access_private_arcp()) 00467 #endif 00468 ); 00469 // Note: Above is just fine even if p1.get()==NULL! 00470 } 00471 00472 00473 #endif // TEUCHOS_ARRAY_VIEW_HPP
1.7.4