Teuchos_ArrayView.hpp

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:29 2011 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.3