Teuchos_Array.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_H
00030 #define TEUCHOS_ARRAY_H
00031 
00036 #include "Teuchos_ConfigDefs.hpp"
00037 #include "Teuchos_TestForException.hpp"
00038 #include "Teuchos_TypeNameTraits.hpp"
00039 #include "Teuchos_ArrayRCP.hpp"
00040 #include "Teuchos_Tuple.hpp"
00041 #include "Teuchos_Utils.hpp"
00042 #include "Teuchos_Assert.hpp"
00043 
00044 
00045 namespace Teuchos {
00046 
00047 
00052 class InvalidArrayStringRepresentation : public std::logic_error
00053 {public:InvalidArrayStringRepresentation(const std::string& what_arg) : std::logic_error(what_arg) {}};
00054 
00055 
00056 template<typename T> class Array;
00057 
00058 
00059 // 2007/11/30: rabartl: Below, I had to move the initial declaration of these
00060 // non-member template functions outside of the Array class since the Sun
00061 // compiler on sass9000 would not accept this.  However, this did work on a
00062 // number of other compilers such a g++, Intel C++ etc.  The old in-class
00063 // non-member friend definition is clearly ISO 98 C++ as shown in Item 46 of
00064 // "Effective C++: Third Edition".  This is not the end of the world but this
00065 // is something to remember for this platform.
00066 
00067 
00072 template<typename T> inline
00073 bool operator==( const Array<T> &a1, const Array<T> &a2 );
00074 
00075 
00080 template<typename T> inline
00081 bool operator!=( const Array<T> &a1, const Array<T> &a2 );
00082 
00083 
00088 template<typename T> inline
00089 void swap( Array<T> &a1, Array<T> &a2 );
00090 
00091 
00096 template<typename T> inline
00097 bool operator<( const Array<T> &a1, const Array<T> &a2 );
00098 
00099 
00104 template<typename T> inline
00105 bool operator<=( const Array<T> &a1, const Array<T> &a2 );
00106 
00107 
00112 template<typename T> inline
00113 bool operator>( const Array<T> &a1, const Array<T> &a2 );
00114 
00115 
00120 template<typename T> inline
00121 bool operator>=( const Array<T> &a1, const Array<T> &a2 );
00122 
00123 
00161 template<typename T>
00162 class Array
00163 {
00164 public:
00165 
00166   // 2007/11/30: rabartl: Below, note that the only reason that these
00167   // functions are declared as friends is so that the compiler will do
00168   // automatic type conversions as described in "Effective C++: Third Edition"
00169   // Item 46.
00170 
00172   template<typename T2>
00173   friend bool Teuchos::operator==( const Array<T2> &a1, const Array<T2> &a2 );
00174 
00176   template<typename T2>
00177   friend bool Teuchos::operator!=( const Array<T2> &a1, const Array<T2> &a2 );
00178 
00180   template<typename T2>
00181   friend void swap( Array<T2> &a1, Array<T2> &a2 );
00182 
00184   template<typename T2>
00185   friend bool Teuchos::operator<( const Array<T2> &a1, const Array<T2> &a2 );
00186 
00188   template<typename T2>
00189   friend bool Teuchos::operator<=( const Array<T2> &a1, const Array<T2> &a2 );
00190 
00192   template<typename T2>
00193   friend bool Teuchos::operator>( const Array<T2> &a1, const Array<T2> &a2 );
00194 
00196   template<typename T2>
00197   friend bool Teuchos::operator>=( const Array<T2> &a1, const Array<T2> &a2 );
00198 
00201 
00203   typedef typename std::vector<T>::value_type value_type;
00205   typedef typename std::vector<T>::pointer pointer;
00207   typedef typename std::vector<T>::const_pointer const_pointer;
00209   typedef typename std::vector<T>::reference reference;
00211   typedef typename std::vector<T>::const_reference const_reference;
00212 
00213 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00214 
00215   typedef ArrayRCP<T> iterator;
00217   typedef ArrayRCP<const T> const_iterator;
00219   typedef std::reverse_iterator<iterator> reverse_iterator;
00221   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00222 #else
00223 
00224   typedef typename std::vector<T>::iterator iterator;
00226   typedef typename std::vector<T>::const_iterator const_iterator;
00228   typedef typename std::vector<T>::reverse_iterator reverse_iterator;
00230   typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
00231 #endif
00232 
00234   typedef typename std::vector<T>::size_type size_type;
00236   typedef typename std::vector<T>::difference_type difference_type;
00238   typedef typename std::vector<T>::allocator_type allocator_type;
00239 
00241 
00244 
00245 
00247   Array();
00249   explicit Array(size_type n, const value_type& value = value_type());
00251   Array(const Array<T>& x);
00253   template<typename InputIterator>
00254   Array(InputIterator first, InputIterator last);
00256   Array(const ArrayView<const T>& a);
00258   template<int N>
00259   Array(const Tuple<T,N>& t);
00261   ~Array();
00263   Array& operator=(const Array<T>& a);
00264 
00266 
00269 
00271   void assign(size_type n, const value_type& val);
00273   template<typename InputIterator>
00274   void assign(InputIterator first, InputIterator last);
00276   iterator begin();
00278   iterator end();
00280   const_iterator begin() const;
00282   const_iterator end() const;
00284   reverse_iterator rbegin();
00286   reverse_iterator rend();
00288   const_reverse_iterator rbegin() const;
00290   const_reverse_iterator rend() const;
00292   size_type size() const;
00294   size_type max_size() const;
00296   void resize(size_type new_size, const value_type& x = value_type());
00298   size_type capacity() const;
00300   bool empty() const;
00302   void reserve(size_type n);
00304   reference operator[](size_type i);
00306   const_reference operator[](size_type i) const;
00308   reference at(size_type i);
00310   const_reference at(size_type i) const;
00312   reference front();
00314   const_reference front() const;
00316   reference back();
00318   const_reference back() const;
00320   void push_back(const value_type& x);
00322   void pop_back();
00324   iterator insert(iterator position, const value_type& x);
00326   void insert(iterator position, size_type n, const value_type& x);
00328   template<typename InputIterator>
00329   void insert(iterator position, InputIterator first, InputIterator last);
00331   iterator erase(iterator position);
00333   iterator erase(iterator first, iterator last);
00335   void swap(Array& x);
00337   void clear();
00338 
00340 
00343 
00348   Array<T>& append(const T& x);
00349 
00353   void remove(int i);
00354 
00359   inline int length() const;
00360 
00362   inline std::string toString() const;
00363 
00365   inline static bool hasBoundsChecking();
00366 
00368   inline T* getRawPtr();
00369 
00371   inline const T* getRawPtr() const;
00372 
00374 
00377 
00379   Array( const std::vector<T> &v );
00380 
00382   std::vector<T> toVector() const;
00383 
00385   Array& operator=( const std::vector<T> &v );
00386 
00388 
00390 
00391 
00403   ArrayView<T> view( size_type offset, size_type size );
00404 
00416   ArrayView<const T> view( size_type offset, size_type size ) const;
00417 
00421   ArrayView<T> operator()( size_type offset, size_type size );
00422 
00426   ArrayView<const T> operator()( size_type offset, size_type size ) const;
00427 
00432   ArrayView<T> operator()();
00433 
00438   ArrayView<const T> operator()() const;
00439 
00443   operator ArrayView<T>();
00444 
00448   operator ArrayView<const T>() const;
00449 
00451 
00452 private:
00453 
00454 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00455   RCP<std::vector<T> > vec_;
00456   mutable ArrayRCP<T> arcp_;
00457   mutable ArrayRCP<const T> carcp_;
00458 #else
00459   std::vector<T> vec_;
00460 #endif
00461 
00462   inline std::vector<T>& vec(
00463     bool isStructureBeingModified = false,
00464     bool activeIter = false
00465     );
00466 
00467   inline const std::vector<T>& vec() const;
00468 
00469   inline typename std::vector<T>::iterator
00470   raw_position( iterator position );
00471   
00472   inline void assertIndex(int i) const;
00473 
00474   inline void assertNotNull() const;
00475 
00476 };
00477 
00478 
00484 template<class T>
00485 ArrayRCP<T> arcp( const RCP<Array<T> > &v )
00486 {
00487   if ( is_null(v) || !v->size() )
00488     return null;
00489   return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
00490     &(*v)[0], 0, v->size(),
00491     v, false
00492     );
00493 }
00494 
00495 
00501 template<class T>
00502 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
00503 {
00504   if ( is_null(v) || !v->size() )
00505     return null;
00506   return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
00507     &(*v)[0], 0, v->size(),
00508     v, false
00509     );
00510 }
00511 
00512 
00525 template<typename T>
00526 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
00527 
00528 
00533 template<typename T> inline
00534 int hashCode(const Array<T>& array);
00535 
00536 
00543 template<typename T> inline
00544 std::vector<T> createVector( const Array<T> &a );
00545 
00546 
00551 template<typename T>
00552 std::string toString(const Array<T>& array);
00553 
00554 
00606 template<typename T>
00607 Array<T> fromStringToArray(const std::string& arrayStr);
00608 
00609 
00610 } // namespace Teuchos
00611 
00612 
00613 //
00614 // Implementation
00615 //
00616 
00617 
00618 namespace Teuchos {
00619 
00620 
00621 // All constructors
00622 
00623 
00624 template<typename T> inline
00625 Array<T>::Array()
00626 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00627   : vec_(rcp(new std::vector<T>()))
00628 #endif
00629 {}
00630 
00631 
00632 template<typename T> inline
00633 Array<T>::Array(size_type n, const value_type& value) :
00634 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00635   vec_(rcp(new std::vector<T>(n,value)))
00636 #else
00637   vec_(n,value)
00638 #endif
00639 {}
00640 
00641 
00642 template<typename T> inline
00643 Array<T>::Array(const Array<T>& x) :
00644 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00645   vec_(rcp(new std::vector<T>(*x.vec_)))
00646 #else
00647   vec_(x.vec_)
00648 #endif
00649 {}
00650 
00651 
00652 template<typename T> template<typename InputIterator> inline
00653 Array<T>::Array(InputIterator first, InputIterator last) :
00654 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00655   vec_(rcp(new std::vector<T>(first,last)))
00656 #else
00657   vec_(first,last)
00658 #endif
00659 {}
00660 
00661 
00662 template<typename T> inline
00663 Array<T>::~Array()
00664 {
00665 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00666   const std::string errorMsg = 
00667     "Error, there must be some client with a dangling reference to this array "
00668     "object!  This could be a dangling iterator or a dangling view of something "
00669     "else.";
00670   TEST_FOR_EXCEPTION( arcp_.count() > 1, DanglingReferenceError, errorMsg );
00671   arcp_ = null;
00672   TEST_FOR_EXCEPTION( carcp_.count() > 1, DanglingReferenceError, errorMsg );
00673   carcp_ = null;
00674   TEST_FOR_EXCEPTION( vec_.count() > 1, DanglingReferenceError, errorMsg );
00675 #endif
00676 }
00677 
00678 
00679 template<typename T> inline
00680 Array<T>::Array(const ArrayView<const T>& a)
00681 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00682   : vec_(rcp(new std::vector<T>()))
00683 #endif
00684 {
00685   insert(begin(),a.begin(),a.end());
00686 }
00687 
00688 
00689 template<typename T>
00690 template<int N>
00691 inline
00692 Array<T>::Array(const Tuple<T,N>& t)
00693 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00694   : vec_(rcp(new std::vector<T>()))
00695 #endif
00696 {
00697   insert(begin(),t.begin(),t.end());
00698 }
00699 
00700 
00701 template<typename T> inline
00702 Array<T>& Array<T>::operator=(const Array& a)
00703 {
00704   vec(true) = a.vec();
00705   return *this;
00706 }
00707 
00708 
00709 // Other std::vector functions
00710 
00711 
00712 template<typename T> inline
00713 void Array<T>::assign(size_type n, const value_type& val)
00714 {
00715   vec(true).assign(n,val);
00716 }
00717 
00718 
00719 template<typename T> template<typename InputIterator> inline
00720 void Array<T>::assign(InputIterator first, InputIterator last)
00721 {
00722   vec(true).assign(first,last);
00723 }
00724 
00725 
00726 template<typename T> inline
00727 typename Array<T>::iterator
00728 Array<T>::begin()
00729 {
00730 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00731   if (is_null(arcp_))
00732     arcp_ = arcp(vec_);
00733   return arcp_;
00734 #else
00735   return vec().begin();
00736 #endif
00737 }
00738 
00739 
00740 template<typename T> inline
00741 typename Array<T>::iterator
00742 Array<T>::end()
00743 {
00744 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00745   return begin() + size();
00746 #else
00747   return vec().end();
00748 #endif
00749 }
00750 
00751 
00752 template<typename T> inline
00753 typename Array<T>::const_iterator
00754 Array<T>::begin() const
00755 {
00756 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00757   if (is_null(carcp_))
00758     carcp_ = arcp(rcp_const_cast<const std::vector<T> >(vec_));
00759   return carcp_;
00760 #else
00761   return vec().begin();
00762 #endif
00763 }
00764 
00765 
00766 template<typename T> inline
00767 typename Array<T>::const_iterator
00768 Array<T>::end() const
00769 {
00770 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00771   return begin() + size();
00772 #else
00773   return vec().end();
00774 #endif
00775 }
00776 
00777 
00778 template<typename T> inline
00779 typename Array<T>::reverse_iterator
00780 Array<T>::rbegin()
00781 {
00782 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00783   return reverse_iterator(end());
00784 #else
00785   return vec().rbegin();
00786 #endif
00787 }
00788 
00789 
00790 template<typename T> inline
00791 typename Array<T>::reverse_iterator
00792 Array<T>::rend()
00793 {
00794 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00795   return reverse_iterator(begin());
00796 #else
00797   return vec().rend();
00798 #endif
00799 }
00800 
00801 
00802 template<typename T> inline
00803 typename Array<T>::const_reverse_iterator
00804 Array<T>::rbegin() const
00805 {
00806 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00807   return const_reverse_iterator(end());
00808 #else
00809   return vec().rbegin();
00810 #endif
00811 }
00812 
00813 
00814 template<typename T> inline
00815 typename Array<T>::const_reverse_iterator
00816 Array<T>::rend() const
00817 {
00818 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00819   return const_reverse_iterator(begin());
00820 #else
00821   return vec().rend();
00822 #endif
00823 }
00824 
00825 
00826 template<typename T> inline
00827 typename Array<T>::size_type
00828 Array<T>::size() const
00829 {
00830   return vec().size();
00831 }
00832 
00833 
00834 template<typename T> inline
00835 typename Array<T>::size_type
00836 Array<T>::max_size() const
00837 {
00838   return vec().max_size();
00839 }
00840 
00841 
00842 template<typename T> inline
00843 void
00844 Array<T>::resize(size_type new_size, const value_type& x)
00845 {
00846   vec(true).resize(new_size,x);
00847 }
00848 
00849 
00850 template<typename T> inline
00851 typename Array<T>::size_type
00852 Array<T>::capacity() const
00853 {
00854   return vec().capacity();
00855 }
00856 
00857 
00858 template<typename T> inline
00859 bool Array<T>::empty() const
00860 {
00861   return vec().empty();
00862 }
00863 
00864 
00865 template<typename T> inline
00866 void Array<T>::reserve(size_type n)
00867 {
00868   vec(true).reserve(n);
00869 }
00870 
00871 
00872 template<typename T> inline
00873 typename Array<T>::reference
00874 Array<T>::operator[](size_type i)
00875 {
00876 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00877   assertIndex(i);
00878 #endif
00879   return vec()[i];
00880 }
00881 
00882 
00883 template<typename T> inline
00884 typename Array<T>::const_reference
00885 Array<T>::operator[](size_type i) const
00886 {
00887 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00888   assertIndex(i);
00889 #endif
00890   return vec()[i];
00891 }
00892 
00893 
00894 template<typename T> inline
00895 typename Array<T>::reference
00896 Array<T>::at(size_type i)
00897 {
00898 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00899   assertIndex(i);
00900 #endif
00901   return vec().at(i);
00902 }
00903 
00904 
00905 template<typename T> inline
00906 typename Array<T>::const_reference
00907 Array<T>::at(size_type i) const
00908 {
00909 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00910   assertIndex(i);
00911 #endif
00912   return vec().at(i);
00913 }
00914 
00915 
00916 template<typename T> inline
00917 typename Array<T>::reference
00918 Array<T>::front()
00919 {
00920 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00921   assertNotNull();
00922 #endif
00923   return vec().front();
00924 }
00925 
00926 
00927 template<typename T> inline
00928 typename Array<T>::const_reference
00929 Array<T>::front() const
00930 {
00931 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00932   assertNotNull();
00933 #endif
00934   return vec().front();
00935 }
00936 
00937 
00938 template<typename T> inline
00939 typename Array<T>::reference
00940 Array<T>::back()
00941 {
00942 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00943   assertNotNull();
00944 #endif
00945   return vec().back();
00946 }
00947 
00948 
00949 template<typename T> inline
00950 typename Array<T>::const_reference
00951 Array<T>::back() const
00952 {
00953 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00954   assertNotNull();
00955 #endif
00956   return vec().back();
00957 }
00958 
00959 
00960 template<typename T> inline
00961 void Array<T>::push_back(const value_type& x)
00962 {
00963   vec(true).push_back(x);
00964 }
00965 
00966 
00967 template<typename T> inline
00968 void Array<T>::pop_back()
00969 {
00970 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00971   assertNotNull();
00972 #endif
00973   vec(true).pop_back();
00974 }
00975 
00976 
00977 // 2007/11/20: rabartl: Note: In the below insertion and deletion functions,
00978 // you have to grab the raw iterator first before you call vec(true,true)
00979 // which will invalidate the iterator.  I had it that raw_position(...) was
00980 // called in the same statement at vec(true,true) and some compilers migh call
00981 // vec(true,true) before they call raw_position(...) which results in an
00982 // exception being thrown.
00983 
00984 
00985 template<typename T> inline
00986 typename Array<T>::iterator
00987 Array<T>::insert(iterator position, const value_type& x)
00988 {
00989 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00990   // Assert a valid iterator and get vector iterator
00991   const typename std::vector<T>::iterator raw_poss = raw_position(position);
00992   const difference_type i = position - begin();
00993   vec(true,true).insert(raw_poss,x);
00994   return begin() + i;
00995 #else
00996   return vec_.insert(position,x);
00997 #endif
00998 }
00999 
01000 
01001 template<typename T> inline
01002 void Array<T>::insert(iterator position, size_type n, const value_type& x)
01003 {
01004 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01005   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01006   vec(true,true).insert(raw_poss,n,x);
01007 #else
01008   return vec_.insert(position,n,x);
01009 #endif
01010 }
01011 
01012 
01013 template<typename T> template<typename InputIterator> inline
01014 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
01015 {
01016 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01017   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01018   vec(true,true).insert(raw_poss,first,last);
01019 #else
01020   return vec_.insert(position,first,last);
01021 #endif
01022 }
01023 
01024 
01025 template<typename T> inline
01026 typename Array<T>::iterator
01027 Array<T>::erase(iterator position)
01028 {
01029 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01030   assertNotNull();
01031   // Assert a valid iterator and get vector iterator
01032   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01033   const difference_type i = position - begin();
01034   vec(true,true).erase(raw_poss);
01035   return begin() + i;
01036 #else
01037   return vec_.erase(position);
01038 #endif
01039 }
01040 
01041 
01042 template<typename T> inline
01043 typename Array<T>::iterator
01044 Array<T>::erase(iterator first, iterator last)
01045 {
01046 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01047   assertNotNull();
01048   // Assert a valid iterator and get vector iterator
01049   const typename std::vector<T>::iterator raw_first = raw_position(first);
01050   const typename std::vector<T>::iterator raw_last = raw_position(last);
01051   const difference_type i = first - begin();
01052   vec(true,true).erase(raw_first,raw_last);
01053   return begin() + i;
01054 #else
01055   return vec_.erase(first,last);
01056 #endif
01057 }
01058 
01059 
01060 template<typename T> inline
01061 void Array<T>::swap(Array& x)
01062 {
01063   vec(true).swap(x.vec());
01064 }
01065 
01066 
01067 template<typename T> inline
01068 void Array<T>::clear()
01069 {
01070   vec(true).clear();
01071 }
01072 
01073 
01074 // Non-standard functions
01075 
01076 
01077 template<typename T> inline
01078 Array<T>& Array<T>::append(const T& x)
01079 {
01080   this->push_back(x);
01081   return *this;
01082 }
01083 
01084 
01085 template<typename T> inline
01086 void Array<T>::remove(int i)
01087 {
01088 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01089   assertIndex(i);
01090 #endif
01091   // Erase the i-th element of this array.
01092   this->erase( this->begin() + i );
01093 }
01094 
01095 
01096 template<typename T> inline
01097 int Array<T>::length() const
01098 {
01099   return this->size();
01100 }
01101 
01102 
01103 template<typename T> inline
01104 std::string Array<T>::toString() const
01105 {
01106   return (*this)().toString();
01107 }
01108 
01109 
01110 template<typename T> inline
01111 bool Array<T>::hasBoundsChecking()
01112 {
01113 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK  
01114   return true;
01115 #else
01116   return false;
01117 #endif
01118 }
01119 
01120 
01121 template<typename T> inline
01122 T* Array<T>::getRawPtr()
01123 {
01124   return ( size() ? &(*this)[0] : 0 );
01125 }
01126 
01127 
01128 template<typename T> inline
01129 const T* Array<T>::getRawPtr() const
01130 {
01131   return ( size() ? &(*this)[0] : 0 );
01132 }
01133 
01134 
01135 // Conversions to and from std::vector
01136 
01137 
01138 template<typename T> inline
01139 Array<T>::Array( const std::vector<T> &v ) :
01140 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01141   vec_(new std::vector<T>(v))
01142 #else
01143   vec_(v)
01144 #endif
01145 {}
01146 
01147 
01148 template<typename T> inline
01149 std::vector<T> Array<T>::toVector() const
01150 {
01151   if (!size())
01152     return std::vector<T>();
01153   std::vector<T> v(begin(),end());
01154   return v;
01155 }
01156 
01157 
01158 template<typename T> inline
01159 Array<T>& Array<T>::operator=( const std::vector<T> &v )
01160 {
01161   vec(true) = v;
01162   return *this;
01163 }
01164 
01165 
01166 // Views
01167 
01168 
01169 template<typename T> inline
01170 ArrayView<T> Array<T>::view( size_type offset, size_type size_in )
01171 {
01172 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01173   assertIndex(offset);
01174   // TEUCHOS_ASSERT_INEQUALITY(size_in, >=, 0); // according to C99, size_type should be unsigned
01175                                                 // this comparison will generate warnings on compliant compilers
01176   if (size_in)
01177     assertIndex(offset+size_in-1);
01178 #endif
01179   if (size_in)
01180     return arrayView( &vec()[offset], size_in );
01181   return Teuchos::null;
01182   // ToDo: Add support for detecting dangling references!
01183 }
01184 
01185 
01186 template<typename T> inline
01187 ArrayView<const T> Array<T>::view( size_type offset, size_type size_in ) const
01188 {
01189 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01190   assertIndex(offset);
01191   assertIndex(offset+size_in-1);
01192 #endif
01193   return arrayView( &vec()[offset], size_in );
01194   //return arrayView( &const_cast<std::vector<T>&>(vec())[offset], size );
01195 }
01196 
01197 
01198 template<typename T> inline
01199 ArrayView<T> Array<T>::operator()( size_type offset, size_type size_in )
01200 {
01201   return view(offset,size_in);
01202 }
01203 
01204 
01205 template<typename T> inline
01206 ArrayView<const T> Array<T>::operator()( size_type offset, size_type size_in ) const
01207 {
01208   return view(offset,size_in);
01209 }
01210 
01211 
01212 template<typename T> inline
01213 ArrayView<T> Array<T>::operator()()
01214 {
01215   if (!size())
01216     return null;
01217   return arrayView( &vec()[0], size() );
01218   // ToDo: Add support for detecting dangling references!
01219 }
01220 
01221 
01222 template<typename T> inline
01223 ArrayView<const T> Array<T>::operator()() const
01224 {
01225   if (!size())
01226     return null;
01227   return arrayView( &vec()[0], size() );
01228 }
01229 
01230 
01231 template<typename T> inline
01232 Array<T>::operator ArrayView<T>()
01233 {
01234   return this->operator()();
01235 }
01236 
01237 
01238 template<typename T> inline
01239 Array<T>::operator ArrayView<const T>() const
01240 {
01241   return this->operator()();
01242 }
01243 
01244 
01245 // private
01246 
01247 
01248 template<typename T>
01249 std::vector<T>&
01250 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
01251 {
01252 (void)isStructureBeingModified; // get rid of "unused parameter" warnings
01253 (void)activeIter;
01254 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01255   if (isStructureBeingModified) {
01256     // Give up my ArrayRCPs used for iterator access since the array we be
01257     // getting modifed!
01258     arcp_ = null;
01259     carcp_ = null;
01260     if (activeIter) {
01261       // If there is an active iterator in this call, then we need to allow
01262       // for the existance of one or more other iterators!  We can't know for
01263       // sure how many other iterators there will be since some copy
01264       // constructors etc., might be called!  This leaves a dangerous
01265       // situration in place where the client might access the iterator after
01266       // this call!
01267       
01268       // 2007/11/08: rabartl: ToDo: I need to add a bool field to RCP_node
01269       // that stores if the underlying object is valid or not.  I can then put
01270       // in a debug-enabled check that any use of that object will be invalid
01271       // and throw!  The WEAK RCP pointer approach might be able to handle
01272       // this!
01273     }
01274     else {
01275       // If there is no active iterator, then we don't allow any other
01276       // dangling references or we will thrown an exception!
01277       TEST_FOR_EXCEPTION( vec_.count() > 1, DanglingReferenceError,
01278         "Error, Array is being modified while a dangling reference exists!");
01279     }
01280   }
01281   return *vec_;
01282 #else
01283   return vec_;
01284 #endif
01285 }
01286 
01287 
01288 template<typename T> inline
01289 const std::vector<T>&
01290 Array<T>::vec() const
01291 {
01292 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01293   return *vec_;
01294 #else
01295   return vec_;
01296 #endif
01297 }
01298 
01299 
01300 template<typename T> inline
01301 typename std::vector<T>::iterator
01302 Array<T>::raw_position( iterator position )
01303 {
01304 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01305   const iterator first = this->begin();
01306   const iterator last = this->end();
01307   TEST_FOR_EXCEPTION(
01308     !(first <= position && position <= last), DanglingReferenceError,
01309     "Error, this iterator is no longer valid for this Aray!"
01310     );
01311   // Note, above operator<=(...) functions will throw
01312   // IncompatibleIteratorsError if the iterators do not share the same
01313   // RCP_node object!
01314   return vec_->begin() + (position - this->begin());
01315 #else
01316   return position;
01317 #endif
01318 }
01319 
01320 
01321 template<typename T> inline
01322 void Array<T>::assertIndex(int i) const
01323 {
01324   TEST_FOR_EXCEPTION(
01325     !( 0 <= i && i < length() ), RangeError,
01326     typeName(*this)<<"::assertIndex(i): "
01327     "index " << i << " out of range [0, "<< length() << ")"
01328     );
01329 }
01330 
01331 
01332 template<typename T> inline
01333 void Array<T>::assertNotNull() const
01334 {
01335   TEST_FOR_EXCEPTION(
01336     !size(), NullReferenceError,
01337     typeName(*this)<<"::assertNotNull(): "
01338     "Error, the array has size zero!"
01339     );
01340 }
01341 
01342 
01343 } // namespace Teuchos
01344 
01345 
01346 // Nonmember functions
01347 
01348 
01349 template<typename T> inline
01350 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
01351 { return (a1.vec() == a2.vec()); }
01352 
01353 
01354 template<typename T> inline
01355 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
01356 { return (a1.vec() != a2.vec()); }
01357 
01358 
01359 template<typename T> inline
01360 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
01361 { a1.swap(a2); }
01362 
01363 
01364 template<typename T> inline
01365 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
01366 { return (a1.vec() < a2.vec()); }
01367 
01368 
01369 template<typename T> inline
01370 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
01371 { return (a1.vec() <= a2.vec()); }
01372 
01373 
01374 template<typename T> inline
01375 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
01376 { return (a1.vec() > a2.vec()); }
01377 
01378 
01379 template<typename T> inline
01380 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
01381 { return (a1.vec() >= a2.vec()); }
01382 
01383 
01384 template<typename T> inline
01385 std::ostream& Teuchos::operator<<(
01386   std::ostream& os, const Array<T>& array
01387   )
01388 {
01389   return os << Teuchos::toString(array);
01390 }
01391 
01392 
01393 template<typename T> inline
01394 int Teuchos::hashCode(const Array<T>& array)
01395 {
01396   int rtn = hashCode(array.length());
01397   for (int i=0; i<array.length(); i++)
01398   {
01399     rtn += hashCode(array[i]);
01400   }
01401   return rtn;
01402 }
01403 
01404 
01405 template<typename T> inline
01406 std::vector<T> Teuchos::createVector( const Array<T> &a )
01407 {
01408   return a.toVector();
01409 }
01410 
01411 
01412 template<typename T> inline
01413 std::string Teuchos::toString(const Array<T>& array)
01414 {
01415   return array.toString();
01416 }
01417 
01418 
01419 template<typename T>
01420 Teuchos::Array<T>
01421 Teuchos::fromStringToArray(const std::string& arrayStr)
01422 {
01423   const std::string str = Utils::trimWhiteSpace(arrayStr);
01424   std::istringstream iss(str);
01425   TEST_FOR_EXCEPTION(
01426     ( str[0]!='{' || str[str.length()-1] != '}' )
01427     ,InvalidArrayStringRepresentation
01428     ,"Error, the std::string:\n"
01429     "----------\n"
01430     <<str<<
01431     "\n----------\n"
01432     "is not a valid array represntation!"
01433     );
01434   char c;
01435   c = iss.get(); // Read initial '{'
01436   TEST_FOR_EXCEPT(c!='{'); // Should not throw!
01437   // Now we are ready to begin reading the entries of the array!
01438   Array<T> a;
01439   while( !iss.eof() ) {
01440     // Get the basic entry std::string
01441     std::string entryStr;
01442     std::getline(iss,entryStr,','); // Get next entry up to ,!
01443     // ToDo: Above, we might have to be careful to look for the opening and
01444     // closing of parentheses in order not to pick up an internal ',' in the
01445     // middle of an entry (for a std::complex number for instance).  The above
01446     // implementation assumes that there will be no commas in the middle of
01447     // the std::string representation of an entry.  This is certainly true for
01448     // the types bool, int, float, and double.
01449     //
01450     // Trim whitespace from beginning and end
01451     entryStr = Utils::trimWhiteSpace(entryStr);
01452     // Remove the final '}' if this is the last entry and we did not
01453     // actually terminate the above getline(...) on ','
01454     bool found_end = false;
01455     if(entryStr[entryStr.length()-1]=='}') {
01456       entryStr = entryStr.substr(0,entryStr.length()-1);
01457       found_end = true;
01458       if( entryStr.length()==0 && a.size()==0 )
01459         return a; // This is the empty array "{}" (with any spaces in it!)
01460     }
01461     TEST_FOR_EXCEPTION(
01462       0 == entryStr.length()
01463       ,InvalidArrayStringRepresentation
01464       ,"Error, the std::string:\n"
01465       "----------\n"
01466       <<str<<
01467       "\n----------\n"
01468       "is not a valid array represntation!"
01469       );
01470     // Finally we can convert the entry and add it to the array!
01471     std::istringstream entryiss(entryStr);
01472     T entry;
01473     entryiss >> entry; // Assumes type has operator>>(...) defined!
01474     // ToDo: We may need to define a traits class to allow us to specialized
01475     // how conversion from a std::string to a object is done!
01476     a.push_back(entry);
01477     // At the end of the loop body here, if we have reached the last '}'
01478     // then the input stream iss should be empty and iss.eof() should be
01479     // true, so the loop should terminate.  We put an std::exception test here
01480     // just in case something has gone wrong.
01481     TEST_FOR_EXCEPTION(
01482       found_end && !iss.eof()
01483       ,InvalidArrayStringRepresentation
01484       ,"Error, the std::string:\n"
01485       "----------\n"
01486       <<str<<
01487       "\n----------\n"
01488       "is not a valid array represntation!"
01489       );
01490   }
01491   return a;
01492 }
01493 
01494 
01495 #endif // TEUCHOS_ARRAY_H

Generated on Wed May 12 21:40:31 2010 for Teuchos - Trilinos Tools Package by  doxygen 1.4.7