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