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, Ordinal size_in )
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();
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>::Ordinal 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[](Ordinal 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(Ordinal offset, Ordinal size_in) const
00195 {
00196   debug_assert_valid_ptr();
00197   debug_assert_in_range(offset, size_in);
00198   return ArrayView<T>(ptr_+offset,size_in);
00199   // WARNING: The above code had better be correct since we are using raw
00200   // pointer arithmetic!
00201 }
00202 
00203 
00204 template<class T> inline
00205 ArrayView<T> ArrayView<T>::operator()( Ordinal offset, Ordinal size_in ) const
00206 {
00207   return view(offset, size_in);
00208 }
00209 
00210 
00211 template<class T> inline
00212 const ArrayView<T>& ArrayView<T>::operator()() const
00213 {
00214   debug_assert_valid_ptr();
00215   return *this;
00216 }
00217 
00218 
00219 template<class T> inline
00220 ArrayView<const T> ArrayView<T>::getConst() const
00221 {
00222   debug_assert_valid_ptr();
00223   return ArrayView<const T>(ptr_,size_);
00224 }
00225 
00226 
00227 template<class T> inline
00228 ArrayView<T>::operator ArrayView<const T>() const
00229 {
00230   return getConst();
00231 }
00232 
00233 
00234 // Assignment
00235 
00236 
00237 template<class T>
00238 void ArrayView<T>::assign(const ArrayView<const T>& array) const
00239 {
00240   debug_assert_valid_ptr();
00241   debug_assert_not_null();
00242   if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size())
00243     return; // Assignment to self
00244   debug_assert_in_range(0,array.size());
00245   std::copy( array.begin(), array.end(), this->begin() );
00246   // Note: Above, in debug mode, the iterators are range checked!  In
00247   // optimized mode, these are raw pointers which should run very fast!
00248 }
00249 
00250 
00251 // Standard Container-Like Functions 
00252 
00253 
00254 template<class T>
00255 typename ArrayView<T>::iterator ArrayView<T>::begin() const
00256 {
00257   debug_assert_valid_ptr();
00258 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00259   return arcp_.create_weak();
00260 #else
00261   return ptr_;
00262 #endif
00263 }
00264 
00265 
00266 template<class T>
00267 typename ArrayView<T>::iterator ArrayView<T>::end() const
00268 {
00269   debug_assert_valid_ptr();
00270 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00271   return arcp_.create_weak() + size_;
00272 #else
00273   return ptr_ + size_;
00274 #endif
00275 }
00276 
00277 
00278 // Assertion Functions. 
00279 
00280 
00281 template<class T>
00282 const ArrayView<T>& ArrayView<T>::assert_not_null() const
00283 {
00284   if(!ptr_)
00285     throw_null_ptr_error(typeName(*this));
00286   return *this;
00287 }
00288 
00289 
00290 template<class T>
00291 const ArrayView<T>&
00292 ArrayView<T>::assert_in_range( Ordinal offset, Ordinal size_in ) const
00293 {
00294   
00295   assert_not_null();
00296   TEST_FOR_EXCEPTION(
00297     !(
00298       ( 0 <= offset && offset+size_in <= this->size() )
00299       &&
00300       size_in >= 0
00301       ),
00302     Teuchos::RangeError,
00303     typeName(*this)<<"::assert_in_range():"
00304     " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
00305     " does not lie in the range [0,"<<this->size()<<")!"
00306     );
00307   return*this;
00308 }
00309 
00310 
00311 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00312 
00313 template<class T>
00314 ArrayView<T>::ArrayView( const ArrayRCP<T> &arcp )
00315   : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
00316 {}
00317 
00318 
00319 template<class T>
00320 ArrayView<T>::ArrayView( T* p, Ordinal size_in, const ArrayRCP<T> &arcp )
00321   : ptr_(p), size_(size_in), arcp_(arcp)
00322 {}
00323 
00324 
00325 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00326 
00327 
00328 // private
00329 
00330 
00331 template<class T>
00332 void ArrayView<T>::setUpIterators()
00333 {
00334 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00335   if (ptr_)
00336     arcp_ = arcp(ptr_, 0, size_, false);
00337   // 2008/09/16: rabartl: Above, this will catch improper usage of the array
00338   // for out-of-bounds errors but it will not catch dangling references.
00339 #endif
00340 }
00341 
00342 
00343 } // namespace Teuchos
00344 
00345 
00346 //
00347 // Nonmember helper functions
00348 //
00349 
00350 
00351 template<class T> inline
00352 Teuchos::ArrayView<T>
00353 Teuchos::arrayView( T* p, typename ArrayView<T>::Ordinal size )
00354 {
00355   return ArrayView<T>(p,size);
00356 }
00357 
00358 
00359 template<class T> inline
00360 Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec )
00361 {
00362   return ArrayView<T>(vec);
00363 }
00364 
00365 
00366 template<class T> inline
00367 Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec )
00368 {
00369   return ArrayView<const T>(vec);
00370 }
00371 
00372 
00373 #ifndef __sun
00374 
00375 template<class T> inline
00376 std::vector<T> Teuchos::createVector( const ArrayView<T> &av )
00377 {
00378   std::vector<T> v(av.begin(), av.end());
00379   return v;
00380 }
00381 
00382 #endif // __sun
00383 
00384 
00385 template<class T> inline
00386 std::vector<T> Teuchos::createVector( const ArrayView<const T> &av )
00387 {
00388   std::vector<T> v(av.begin(), av.end());
00389   return v;
00390 }
00391 
00392 
00393 template<class T> inline
00394 bool Teuchos::is_null( const ArrayView<T> &av )
00395 {
00396   return av.is_null();
00397 }
00398 
00399 
00400 template<class T>
00401 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p )
00402 {
00403   return out << p.toString();
00404 }
00405 
00406 
00407 template<class T2, class T1>
00408 REFCOUNTPTR_INLINE
00409 Teuchos::ArrayView<T2>
00410 Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1)
00411 {
00412   typedef typename ArrayView<T1>::Ordinal Ordinal;
00413   const int sizeOfT1 = sizeof(T1);
00414   const int sizeOfT2 = sizeof(T2);
00415   Ordinal size2 = (p1.size()*sizeOfT1) / sizeOfT2;
00416   T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr());
00417   return ArrayView<T2>(
00418     ptr2, size2
00419 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00420     ,arcp_reinterpret_cast<T2>(p1.access_private_arcp())
00421 #endif
00422     );
00423   // Note: Above is just fine even if p1.get()==NULL!
00424 }
00425 
00426 
00427 #endif  // TEUCHOS_ARRAY_VIEW_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Tue Oct 20 10:13:59 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1