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 Teuchos_Ordinal Ordinal;
00205   typedef Ordinal size_type;
00207   typedef Ordinal difference_type;
00209   typedef typename std::vector<T>::value_type value_type;
00211   typedef typename std::vector<T>::pointer pointer;
00213   typedef typename std::vector<T>::const_pointer const_pointer;
00215   typedef typename std::vector<T>::reference reference;
00217   typedef typename std::vector<T>::const_reference const_reference;
00219   typedef typename std::vector<T>::allocator_type allocator_type;
00220 
00221 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00222 
00223   typedef ArrayRCP<T> iterator;
00225   typedef ArrayRCP<const T> const_iterator;
00227   typedef std::reverse_iterator<iterator> reverse_iterator;
00229   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00230 #else
00231 
00232   typedef typename std::vector<T>::iterator iterator;
00234   typedef typename std::vector<T>::const_iterator const_iterator;
00236   typedef typename std::vector<T>::reverse_iterator reverse_iterator;
00238   typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
00239 #endif
00240 
00241 
00243 
00246 
00248   inline Array();
00250   inline explicit Array(size_type n, const value_type& value = value_type());
00252   inline Array(const Array<T>& x);
00254   template<typename InputIterator>
00255   inline Array(InputIterator first, InputIterator last);
00257   inline Array(const ArrayView<const T>& a);
00259   template<int N>
00260   inline Array(const Tuple<T,N>& t);
00262   inline ~Array();
00264   inline Array& operator=(const Array<T>& a);
00265 
00267 
00270 
00272   inline void assign(size_type n, const value_type& val);
00274   template<typename InputIterator>
00275   inline void assign(InputIterator first, InputIterator last);
00277   inline iterator begin();
00279   inline iterator end();
00281   inline const_iterator begin() const;
00283   inline const_iterator end() const;
00285   inline reverse_iterator rbegin();
00287   inline reverse_iterator rend();
00289   inline const_reverse_iterator rbegin() const;
00291   inline const_reverse_iterator rend() const;
00293   inline size_type size() const;
00295   inline size_type max_size() const;
00297   inline void resize(size_type new_size, const value_type& x = value_type());
00299   inline size_type capacity() const;
00301   inline bool empty() const;
00303   inline void reserve(size_type n);
00305   inline reference operator[](size_type i);
00307   inline const_reference operator[](size_type i) const;
00309   inline reference at(size_type i);
00311   inline const_reference at(size_type i) const;
00313   inline reference front();
00315   inline const_reference front() const;
00317   inline reference back();
00319   inline const_reference back() const;
00321   inline void push_back(const value_type& x);
00323   inline void pop_back();
00325   inline iterator insert(iterator position, const value_type& x);
00327   inline void insert(iterator position, size_type n, const value_type& x);
00329   template<typename InputIterator>
00330   inline void insert(iterator position, InputIterator first, InputIterator last);
00332   inline iterator erase(iterator position);
00334   inline iterator erase(iterator first, iterator last);
00336   inline void swap(Array& x);
00338   inline void clear();
00339 
00341 
00344 
00349   inline Array<T>& append(const T& x);
00350 
00354   inline void remove(int i);
00355 
00360   inline int length() const;
00361 
00363   inline std::string toString() const;
00364 
00366   inline static bool hasBoundsChecking();
00367 
00369   inline T* getRawPtr();
00370 
00372   inline const T* getRawPtr() const;
00373 
00375 
00378 
00380   inline Array( const std::vector<T> &v );
00381 
00383   inline std::vector<T> toVector() const;
00384 
00386   inline Array& operator=( const std::vector<T> &v );
00387 
00389 
00391 
00392 
00404   inline ArrayView<T> view( size_type offset, size_type size );
00405 
00417   inline ArrayView<const T> view( size_type offset, size_type size ) const;
00418 
00422   inline ArrayView<T> operator()( size_type offset, size_type size );
00423 
00427   inline ArrayView<const T> operator()( size_type offset, size_type size ) const;
00428 
00433   inline ArrayView<T> operator()();
00434 
00439   inline ArrayView<const T> operator()() const;
00440 
00444   inline operator ArrayView<T>();
00445 
00449   inline operator ArrayView<const T>() const;
00450 
00452 
00453 private:
00454 
00455 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00456   RCP<std::vector<T> > vec_;
00457   mutable ArrayRCP<T> extern_arcp_;
00458   mutable ArrayRCP<const T> extern_carcp_;
00459 #else
00460   std::vector<T> vec_;
00461 #endif
00462 
00463   inline std::vector<T>& vec(
00464     bool isStructureBeingModified = false,
00465     bool activeIter = false
00466     );
00467 
00468   inline const std::vector<T>& vec() const;
00469 
00470   inline typename std::vector<T>::iterator
00471   raw_position( iterator position );
00472   
00473   inline void assertIndex(int i) const;
00474 
00475   inline void assertNotNull() const;
00476 
00477 };
00478 
00479 
00485 template<class T>
00486 ArrayRCP<T> arcp( const RCP<Array<T> > &v )
00487 {
00488   if ( is_null(v) || !v->size() )
00489     return null;
00490   return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
00491     &(*v)[0], 0, v->size(),
00492     v, false
00493     );
00494 }
00495 
00496 
00502 template<class T>
00503 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
00504 {
00505   if ( is_null(v) || !v->size() )
00506     return null;
00507   return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
00508     &(*v)[0], 0, v->size(),
00509     v, false
00510     );
00511 }
00512 
00513 
00519 template<class T>
00520 ArrayRCP<T> arcpFromArray( Array<T> &a )
00521 {
00522   if (a.size() == 0)
00523     return null;
00524 #ifdef TEUCHOS_DEBUG
00525   return a.begin(); // Catch dangling reference!
00526 #else
00527   return arcp(a.getRawPtr(), 0, a.size(), false);
00528 #endif
00529 }
00530 
00531 
00537 template<class T>
00538 ArrayRCP<const T> arcpFromArray( const Array<T> &a )
00539 {
00540   if (a.size() == 0)
00541     return null;
00542 #ifdef TEUCHOS_DEBUG
00543   return a.begin(); // Catch dangling reference!
00544 #else
00545   return arcp(a.getRawPtr(), 0, a.size(), false);
00546 #endif
00547 }
00548 
00549 
00562 template<typename T>
00563 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
00564 
00565 
00570 template<typename T> inline
00571 int hashCode(const Array<T>& array);
00572 
00573 
00580 template<typename T> inline
00581 std::vector<T> createVector( const Array<T> &a );
00582 
00583 
00588 template<typename T>
00589 std::string toString(const Array<T>& array);
00590 
00591 
00643 template<typename T>
00644 Array<T> fromStringToArray(const std::string& arrayStr);
00645 
00651 template<typename T> inline
00652 void extractDataFromISS( std::istringstream& iss, T& data )
00653 {
00654   iss >> data; // Assumes type has operator>>(...) defined!
00655 }
00656 
00663 inline
00664 void extractDataFromISS( std::istringstream& iss, std::string& data )
00665 {
00666   // grab unformatted string.
00667   data = iss.str();
00668   // remove white space from beginning and end of string.
00669   data = Utils::trimWhiteSpace(data);
00670 }
00671 
00672 } // namespace Teuchos
00673 
00674 
00675 //
00676 // Implementation
00677 //
00678 
00679 
00680 namespace Teuchos {
00681 
00682 
00683 // All constructors
00684 
00685 
00686 template<typename T> inline
00687 Array<T>::Array()
00688 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00689   : vec_(rcp(new std::vector<T>()))
00690 #endif
00691 {}
00692 
00693 
00694 template<typename T> inline
00695 Array<T>::Array(size_type n, const value_type& value) :
00696 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00697   vec_(rcp(new std::vector<T>(n,value)))
00698 #else
00699   vec_(n, value)
00700 #endif
00701 {}
00702 
00703 
00704 template<typename T> inline
00705 Array<T>::Array(const Array<T>& x) :
00706 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00707   vec_(rcp(new std::vector<T>(*x.vec_)))
00708 #else
00709   vec_(x.vec_)
00710 #endif
00711 {}
00712 
00713 
00714 template<typename T> template<typename InputIterator> inline
00715 Array<T>::Array(InputIterator first, InputIterator last) :
00716 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00717   vec_(rcp(new std::vector<T>(first, last)))
00718 #else
00719   vec_(first, last)
00720 #endif
00721 {}
00722 
00723 
00724 template<typename T> inline
00725 Array<T>::~Array()
00726 {}
00727 
00728 
00729 template<typename T> inline
00730 Array<T>::Array(const ArrayView<const T>& a)
00731 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00732   : vec_(rcp(new std::vector<T>()))
00733 #endif
00734 {
00735   insert(begin(), a.begin(), a.end());
00736 }
00737 
00738 
00739 template<typename T>
00740 template<int N>
00741 inline
00742 Array<T>::Array(const Tuple<T,N>& t)
00743 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00744   : vec_(rcp(new std::vector<T>()))
00745 #endif
00746 {
00747   insert(begin(), t.begin(), t.end());
00748 }
00749 
00750 
00751 template<typename T> inline
00752 Array<T>& Array<T>::operator=(const Array& a)
00753 {
00754   vec(true) = a.vec();
00755   return *this;
00756 }
00757 
00758 
00759 // Other std::vector functions
00760 
00761 
00762 template<typename T> inline
00763 void Array<T>::assign(size_type n, const value_type& val)
00764 {
00765   vec(true).assign(n,val);
00766 }
00767 
00768 
00769 template<typename T> template<typename InputIterator> inline
00770 void Array<T>::assign(InputIterator first, InputIterator last)
00771 {
00772   vec(true).assign(first,last);
00773 }
00774 
00775 
00776 template<typename T> inline
00777 typename Array<T>::iterator
00778 Array<T>::begin()
00779 {
00780 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00781   if (is_null(extern_arcp_)) {
00782     // Here we must use the same RCP to avoid creating two unrelated RCPNodes!
00783     extern_arcp_ = arcp(vec_); // Will be null if vec_ is sized!
00784   }
00785   // Returning a weak pointer will help to catch dangling references but still
00786   // keep the same behavior as optimized code.
00787   return extern_arcp_.create_weak();
00788 #else
00789   return vec().begin();
00790 #endif
00791 }
00792 
00793 
00794 template<typename T> inline
00795 typename Array<T>::iterator
00796 Array<T>::end()
00797 {
00798 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00799   return begin() + size();
00800 #else
00801   return vec().end();
00802 #endif
00803 }
00804 
00805 
00806 template<typename T> inline
00807 typename Array<T>::const_iterator
00808 Array<T>::begin() const
00809 {
00810 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00811   if (is_null(extern_carcp_)) {
00812     extern_carcp_ = const_cast<Array<T>*>(this)->begin();
00813   }
00814   // Returning a weak pointer will help to catch dangling references but still
00815   // keep the same behavior as optimized code.
00816   return extern_carcp_.create_weak();
00817 #else
00818   return vec().begin();
00819 #endif
00820 }
00821 
00822 
00823 template<typename T> inline
00824 typename Array<T>::const_iterator
00825 Array<T>::end() const
00826 {
00827 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00828   return begin() + size();
00829 #else
00830   return vec().end();
00831 #endif
00832 }
00833 
00834 
00835 template<typename T> inline
00836 typename Array<T>::reverse_iterator
00837 Array<T>::rbegin()
00838 {
00839 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00840   return reverse_iterator(end());
00841 #else
00842   return vec().rbegin();
00843 #endif
00844 }
00845 
00846 
00847 template<typename T> inline
00848 typename Array<T>::reverse_iterator
00849 Array<T>::rend()
00850 {
00851 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00852   return reverse_iterator(begin());
00853 #else
00854   return vec().rend();
00855 #endif
00856 }
00857 
00858 
00859 template<typename T> inline
00860 typename Array<T>::const_reverse_iterator
00861 Array<T>::rbegin() const
00862 {
00863 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00864   return const_reverse_iterator(end());
00865 #else
00866   return vec().rbegin();
00867 #endif
00868 }
00869 
00870 
00871 template<typename T> inline
00872 typename Array<T>::const_reverse_iterator
00873 Array<T>::rend() const
00874 {
00875 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00876   return const_reverse_iterator(begin());
00877 #else
00878   return vec().rend();
00879 #endif
00880 }
00881 
00882 
00883 template<typename T> inline
00884 typename Array<T>::size_type
00885 Array<T>::size() const
00886 {
00887   return vec().size();
00888 }
00889 
00890 
00891 template<typename T> inline
00892 typename Array<T>::size_type
00893 Array<T>::max_size() const
00894 {
00895   return std::numeric_limits<size_type>::max();
00896 }
00897 
00898 
00899 template<typename T> inline
00900 void
00901 Array<T>::resize(size_type new_size, const value_type& x)
00902 {
00903   vec(true).resize(new_size,x);
00904 }
00905 
00906 
00907 template<typename T> inline
00908 typename Array<T>::size_type
00909 Array<T>::capacity() const
00910 {
00911   return vec().capacity();
00912 }
00913 
00914 
00915 template<typename T> inline
00916 bool Array<T>::empty() const
00917 {
00918   return vec().empty();
00919 }
00920 
00921 
00922 template<typename T> inline
00923 void Array<T>::reserve(size_type n)
00924 {
00925   vec(true).reserve(n);
00926 }
00927 
00928 
00929 template<typename T> inline
00930 typename Array<T>::reference
00931 Array<T>::operator[](size_type i)
00932 {
00933 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00934   assertIndex(i);
00935 #endif
00936   return vec()[i];
00937 }
00938 
00939 
00940 template<typename T> inline
00941 typename Array<T>::const_reference
00942 Array<T>::operator[](size_type i) const
00943 {
00944 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00945   assertIndex(i);
00946 #endif
00947   return vec()[i];
00948 }
00949 
00950 
00951 template<typename T> inline
00952 typename Array<T>::reference
00953 Array<T>::at(size_type i)
00954 {
00955 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00956   assertIndex(i);
00957 #endif
00958   return vec().at(i);
00959 }
00960 
00961 
00962 template<typename T> inline
00963 typename Array<T>::const_reference
00964 Array<T>::at(size_type i) const
00965 {
00966 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00967   assertIndex(i);
00968 #endif
00969   return vec().at(i);
00970 }
00971 
00972 
00973 template<typename T> inline
00974 typename Array<T>::reference
00975 Array<T>::front()
00976 {
00977 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00978   assertNotNull();
00979 #endif
00980   return vec().front();
00981 }
00982 
00983 
00984 template<typename T> inline
00985 typename Array<T>::const_reference
00986 Array<T>::front() const
00987 {
00988 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00989   assertNotNull();
00990 #endif
00991   return vec().front();
00992 }
00993 
00994 
00995 template<typename T> inline
00996 typename Array<T>::reference
00997 Array<T>::back()
00998 {
00999 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01000   assertNotNull();
01001 #endif
01002   return vec().back();
01003 }
01004 
01005 
01006 template<typename T> inline
01007 typename Array<T>::const_reference
01008 Array<T>::back() const
01009 {
01010 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01011   assertNotNull();
01012 #endif
01013   return vec().back();
01014 }
01015 
01016 
01017 template<typename T> inline
01018 void Array<T>::push_back(const value_type& x)
01019 {
01020   vec(true).push_back(x);
01021 }
01022 
01023 
01024 template<typename T> inline
01025 void Array<T>::pop_back()
01026 {
01027 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01028   assertNotNull();
01029 #endif
01030   vec(true).pop_back();
01031 }
01032 
01033 
01034 // 2009/11/13:: rabartl: After moving to a full RCPNode tracing and lookup
01035 // model, I had to how modifying functions like insert(...) and erase(...) 
01036 // work which have active iterators controled by the client and yet need to
01037 // allow the structure of the container change.  The way these troublesome
01038 // functions work is that first the raw std::vector iterator is extracted.
01039 // The function vec(true, true) then deletes the strong iterators but there is
01040 // still a weak ArrayRCP object that is owned by the client which is being
01041 // passed into this function.  The issue is that the design of ArrayRCP is
01042 // such that the RCPNode object is not removed but instead remains in order to
01043 // perform runtime checking.
01044 
01045 
01046 template<typename T> inline
01047 typename Array<T>::iterator
01048 Array<T>::insert(iterator position, const value_type& x)
01049 {
01050 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01051   // Assert a valid iterator and get vector iterator
01052   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01053   const difference_type i = position - begin();
01054   vec(true, true).insert(raw_poss, x);
01055   return begin() + i;
01056 #else
01057   return vec_.insert(position, x);
01058 #endif
01059 }
01060 
01061 
01062 template<typename T> inline
01063 void Array<T>::insert(iterator position, size_type n, const value_type& x)
01064 {
01065 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01066   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01067   vec(true, true).insert(raw_poss, n, x);
01068 #else
01069   return vec_.insert(position, n, x);
01070 #endif
01071 }
01072 
01073 
01074 template<typename T> template<typename InputIterator> inline
01075 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
01076 {
01077 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01078   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01079   vec(true, true).insert(raw_poss, first, last);
01080 #else
01081   return vec_.insert(position, first, last);
01082 #endif
01083 }
01084 
01085 
01086 template<typename T> inline
01087 typename Array<T>::iterator
01088 Array<T>::erase(iterator position)
01089 {
01090 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01091   assertNotNull();
01092   // Assert a valid iterator and get vector iterator
01093   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01094   const difference_type i = position - begin();
01095   vec(true, true).erase(raw_poss);
01096   return begin() + i;
01097 #else
01098   return vec_.erase(position);
01099 #endif
01100 }
01101 
01102 
01103 template<typename T> inline
01104 typename Array<T>::iterator
01105 Array<T>::erase(iterator first, iterator last)
01106 {
01107 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01108   assertNotNull();
01109   // Assert a valid iterator and get vector iterator
01110   const typename std::vector<T>::iterator raw_first = raw_position(first);
01111   const typename std::vector<T>::iterator raw_last = raw_position(last);
01112   const difference_type i = first - begin();
01113   vec(true,true).erase(raw_first,raw_last);
01114   return begin() + i;
01115 #else
01116   return vec_.erase(first,last);
01117 #endif
01118 }
01119 
01120 
01121 template<typename T> inline
01122 void Array<T>::swap(Array& x)
01123 {
01124   vec(true).swap(x.vec());
01125 }
01126 
01127 
01128 template<typename T> inline
01129 void Array<T>::clear()
01130 {
01131   vec(true).clear();
01132 }
01133 
01134 
01135 // Non-standard functions
01136 
01137 
01138 template<typename T> inline
01139 Array<T>& Array<T>::append(const T& x)
01140 {
01141   this->push_back(x);
01142   return *this;
01143 }
01144 
01145 
01146 template<typename T> inline
01147 void Array<T>::remove(int i)
01148 {
01149 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01150   assertIndex(i);
01151 #endif
01152   // Erase the i-th element of this array.
01153   this->erase( this->begin() + i );
01154 }
01155 
01156 
01157 template<typename T> inline
01158 int Array<T>::length() const
01159 {
01160   return this->size();
01161 }
01162 
01163 
01164 template<typename T> inline
01165 std::string Array<T>::toString() const
01166 {
01167   return (*this)().toString();
01168 }
01169 
01170 
01171 template<typename T> inline
01172 bool Array<T>::hasBoundsChecking()
01173 {
01174 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK  
01175   return true;
01176 #else
01177   return false;
01178 #endif
01179 }
01180 
01181 
01182 template<typename T> inline
01183 T* Array<T>::getRawPtr()
01184 {
01185   return ( size() ? &(*this)[0] : 0 );
01186 }
01187 
01188 
01189 template<typename T> inline
01190 const T* Array<T>::getRawPtr() const
01191 {
01192   return ( size() ? &(*this)[0] : 0 );
01193 }
01194 
01195 
01196 // Conversions to and from std::vector
01197 
01198 
01199 template<typename T> inline
01200 Array<T>::Array( const std::vector<T> &v ) :
01201 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01202   vec_(new std::vector<T>(v))
01203 #else
01204   vec_(v)
01205 #endif
01206 {}
01207 
01208 
01209 template<typename T> inline
01210 std::vector<T> Array<T>::toVector() const
01211 {
01212   if (!size())
01213     return std::vector<T>();
01214   std::vector<T> v(begin(),end());
01215   return v;
01216 }
01217 
01218 
01219 template<typename T> inline
01220 Array<T>& Array<T>::operator=( const std::vector<T> &v )
01221 {
01222   vec(true) = v;
01223   return *this;
01224 }
01225 
01226 
01227 // Views
01228 
01229 
01230 template<typename T> inline
01231 ArrayView<T> Array<T>::view( size_type offset, size_type size_in )
01232 {
01233   if (size_in) {
01234 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01235     return ArrayView<T>(this->begin().persistingView(offset, size_in));
01236 #else
01237     return arrayView( &vec()[offset], size_in );
01238 #endif
01239   }
01240   return Teuchos::null;
01241 }
01242 
01243 
01244 template<typename T> inline
01245 ArrayView<const T> Array<T>::view( size_type offset, size_type size_in ) const
01246 {
01247   if (size_in) {
01248 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01249     return ArrayView<const T>(this->begin().persistingView(offset, size_in));
01250 #else
01251     return arrayView( &vec()[offset], size_in );
01252 #endif
01253   }
01254   return Teuchos::null;
01255   // NOTE: Above, we use a different implementation to call the const version
01256   // of begin() instead of the non-const version.  This sets up a different
01257   // ArrayRCP object that gets checked.
01258 }
01259 
01260 
01261 template<typename T> inline
01262 ArrayView<T> Array<T>::operator()( size_type offset, size_type size_in )
01263 {
01264   return view(offset, size_in);
01265 }
01266 
01267 
01268 template<typename T> inline
01269 ArrayView<const T> Array<T>::operator()( size_type offset, size_type size_in ) const
01270 {
01271   return view(offset, size_in);
01272 }
01273 
01274 
01275 template<typename T> inline
01276 ArrayView<T> Array<T>::operator()()
01277 {
01278   if (!size())
01279     return null;
01280   return this->view(0, size());
01281 }
01282 
01283 
01284 template<typename T> inline
01285 ArrayView<const T> Array<T>::operator()() const
01286 {
01287   if (!size())
01288     return null;
01289   return this->view(0, size());
01290 }
01291 
01292 
01293 template<typename T> inline
01294 Array<T>::operator ArrayView<T>()
01295 {
01296   return this->operator()();
01297 }
01298 
01299 
01300 template<typename T> inline
01301 Array<T>::operator ArrayView<const T>() const
01302 {
01303   return this->operator()();
01304 }
01305 
01306 
01307 // private
01308 
01309 
01310 template<typename T>
01311 std::vector<T>&
01312 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
01313 {
01314 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01315   (void)activeIter;
01316   if (isStructureBeingModified) {
01317     // Give up my ArrayRCPs used for iterator access since the array we be
01318     // getting modifed!  Any clients that have views through weak pointers
01319     // better not touch them!
01320     extern_arcp_ = null;
01321     extern_carcp_ = null;
01322   }
01323   return *vec_;
01324 #else
01325   // get rid of "unused parameter" warnings
01326   (void)isStructureBeingModified;
01327   (void)activeIter;
01328   return vec_;
01329 #endif
01330 }
01331 
01332 
01333 template<typename T> inline
01334 const std::vector<T>&
01335 Array<T>::vec() const
01336 {
01337 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01338   return *vec_;
01339 #else
01340   return vec_;
01341 #endif
01342 }
01343 
01344 
01345 template<typename T> inline
01346 typename std::vector<T>::iterator
01347 Array<T>::raw_position( iterator position )
01348 {
01349 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01350   const iterator first = this->begin();
01351   const iterator last = this->end();
01352   TEST_FOR_EXCEPTION(
01353     !(first <= position && position <= last), DanglingReferenceError,
01354     "Error, this iterator is no longer valid for this Aray!"
01355     );
01356   // Note, above operator<=(...) functions will throw
01357   // IncompatibleIteratorsError if the iterators do not share the same
01358   // RCP_node object!
01359   return vec_->begin() + (position - this->begin());
01360 #else
01361   return position;
01362 #endif
01363 }
01364 
01365 
01366 template<typename T> inline
01367 void Array<T>::assertIndex(int i) const
01368 {
01369   TEST_FOR_EXCEPTION(
01370     !( 0 <= i && i < length() ), RangeError,
01371     typeName(*this)<<"::assertIndex(i): "
01372     "index " << i << " out of range [0, "<< length() << ")"
01373     );
01374 }
01375 
01376 
01377 template<typename T> inline
01378 void Array<T>::assertNotNull() const
01379 {
01380   TEST_FOR_EXCEPTION(
01381     !size(), NullReferenceError,
01382     typeName(*this)<<"::assertNotNull(): "
01383     "Error, the array has size zero!"
01384     );
01385 }
01386 
01387 
01388 } // namespace Teuchos
01389 
01390 
01391 // Nonmember functions
01392 
01393 
01394 template<typename T> inline
01395 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
01396 { return (a1.vec() == a2.vec()); }
01397 
01398 
01399 template<typename T> inline
01400 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
01401 { return (a1.vec() != a2.vec()); }
01402 
01403 
01404 template<typename T> inline
01405 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
01406 { a1.swap(a2); }
01407 
01408 
01409 template<typename T> inline
01410 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
01411 { return (a1.vec() < a2.vec()); }
01412 
01413 
01414 template<typename T> inline
01415 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
01416 { return (a1.vec() <= a2.vec()); }
01417 
01418 
01419 template<typename T> inline
01420 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
01421 { return (a1.vec() > a2.vec()); }
01422 
01423 
01424 template<typename T> inline
01425 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
01426 { return (a1.vec() >= a2.vec()); }
01427 
01428 
01429 template<typename T> inline
01430 std::ostream& Teuchos::operator<<(
01431   std::ostream& os, const Array<T>& array
01432   )
01433 {
01434   return os << Teuchos::toString(array);
01435 }
01436 
01437 
01438 template<typename T> inline
01439 int Teuchos::hashCode(const Array<T>& array)
01440 {
01441   int rtn = hashCode(array.length());
01442   for (int i=0; i<array.length(); i++)
01443   {
01444     rtn += hashCode(array[i]);
01445   }
01446   return rtn;
01447 }
01448 
01449 
01450 template<typename T> inline
01451 std::vector<T> Teuchos::createVector( const Array<T> &a )
01452 {
01453   return a.toVector();
01454 }
01455 
01456 
01457 template<typename T> inline
01458 std::string Teuchos::toString(const Array<T>& array)
01459 {
01460   return array.toString();
01461 }
01462 
01463 
01464 template<typename T>
01465 Teuchos::Array<T>
01466 Teuchos::fromStringToArray(const std::string& arrayStr)
01467 {
01468   const std::string str = Utils::trimWhiteSpace(arrayStr);
01469   std::istringstream iss(str);
01470   TEST_FOR_EXCEPTION(
01471     ( str[0]!='{' || str[str.length()-1] != '}' )
01472     ,InvalidArrayStringRepresentation
01473     ,"Error, the std::string:\n"
01474     "----------\n"
01475     <<str<<
01476     "\n----------\n"
01477     "is not a valid array represntation!"
01478     );
01479   char c;
01480   c = iss.get(); // Read initial '{'
01481   TEST_FOR_EXCEPT(c!='{'); // Should not throw!
01482   // Now we are ready to begin reading the entries of the array!
01483   Array<T> a;
01484   while( !iss.eof() ) {
01485     // Get the basic entry std::string
01486     std::string entryStr;
01487     std::getline(iss,entryStr,','); // Get next entry up to ,!
01488     // ToDo: Above, we might have to be careful to look for the opening and
01489     // closing of parentheses in order not to pick up an internal ',' in the
01490     // middle of an entry (for a std::complex number for instance).  The above
01491     // implementation assumes that there will be no commas in the middle of
01492     // the std::string representation of an entry.  This is certainly true for
01493     // the types bool, int, float, and double.
01494     //
01495     // Trim whitespace from beginning and end
01496     entryStr = Utils::trimWhiteSpace(entryStr);
01497     // Remove the final '}' if this is the last entry and we did not
01498     // actually terminate the above getline(...) on ','
01499     bool found_end = false;
01500     if(entryStr[entryStr.length()-1]=='}') {
01501       entryStr = entryStr.substr(0,entryStr.length()-1);
01502       found_end = true;
01503       if( entryStr.length()==0 && a.size()==0 )
01504         return a; // This is the empty array "{}" (with any spaces in it!)
01505     }
01506     TEST_FOR_EXCEPTION(
01507       0 == entryStr.length()
01508       ,InvalidArrayStringRepresentation
01509       ,"Error, the std::string:\n"
01510       "----------\n"
01511       <<str<<
01512       "\n----------\n"
01513       "is not a valid array represntation!"
01514       );
01515     // Finally we can convert the entry and add it to the array!
01516     std::istringstream entryiss(entryStr);
01517     T entry;
01518     Teuchos::extractDataFromISS( entryiss, entry );
01519     // ToDo: We may need to define a traits class to allow us to specialized
01520     // how conversion from a std::string to a object is done!
01521     a.push_back(entry);
01522     // At the end of the loop body here, if we have reached the last '}'
01523     // then the input stream iss should be empty and iss.eof() should be
01524     // true, so the loop should terminate.  We put an std::exception test here
01525     // just in case something has gone wrong.
01526     TEST_FOR_EXCEPTION(
01527       found_end && !iss.eof()
01528       ,InvalidArrayStringRepresentation
01529       ,"Error, the std::string:\n"
01530       "----------\n"
01531       <<str<<
01532       "\n----------\n"
01533       "is not a valid array represntation!"
01534       );
01535   }
01536   return a;
01537 }
01538 
01539 
01540 #endif // TEUCHOS_ARRAY_H

Generated on Tue Jul 13 09:22:58 2010 for Teuchos - Trilinos Tools Package by  doxygen 1.4.7