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