Teuchos Package Browser (Single Doxygen Collection) 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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_ARRAY_H
00043 #define TEUCHOS_ARRAY_H
00044 
00049 #include "Teuchos_ConfigDefs.hpp"
00050 #include "Teuchos_Assert.hpp"
00051 #include "Teuchos_TypeNameTraits.hpp"
00052 #include "Teuchos_ArrayRCP.hpp"
00053 #include "Teuchos_Tuple.hpp"
00054 #include "Teuchos_Utils.hpp"
00055 #include "Teuchos_Assert.hpp"
00056 
00057 
00058 namespace Teuchos {
00059 
00060 
00065 class InvalidArrayStringRepresentation : public std::logic_error
00066 {public:InvalidArrayStringRepresentation(const std::string& what_arg) : std::logic_error(what_arg) {}};
00067 
00068 
00069 template<typename T> class Array;
00070 
00071 
00072 // 2007/11/30: rabartl: Below, I had to move the initial declaration of these
00073 // non-member template functions outside of the Array class since the Sun
00074 // compiler on sass9000 would not accept this.  However, this did work on a
00075 // number of other compilers such a g++, Intel C++ etc.  The old in-class
00076 // non-member friend definition is clearly ISO 98 C++ as shown in Item 46 of
00077 // "Effective C++: Third Edition".  This is not the end of the world but this
00078 // is something to remember for this platform.
00079 
00080 
00085 template<typename T> inline
00086 bool operator==( const Array<T> &a1, const Array<T> &a2 );
00087 
00088 
00093 template<typename T> inline
00094 bool operator!=( const Array<T> &a1, const Array<T> &a2 );
00095 
00096 
00101 template<typename T> inline
00102 void swap( Array<T> &a1, Array<T> &a2 );
00103 
00104 
00109 template<typename T> inline
00110 bool operator<( const Array<T> &a1, const Array<T> &a2 );
00111 
00112 
00117 template<typename T> inline
00118 bool operator<=( const Array<T> &a1, const Array<T> &a2 );
00119 
00120 
00125 template<typename T> inline
00126 bool operator>( const Array<T> &a1, const Array<T> &a2 );
00127 
00128 
00133 template<typename T> inline
00134 bool operator>=( const Array<T> &a1, const Array<T> &a2 );
00135 
00136 
00174 template<typename T>
00175 class Array
00176 {
00177 public:
00178 
00179   // 2007/11/30: rabartl: Below, note that the only reason that these
00180   // functions are declared as friends is so that the compiler will do
00181   // automatic type conversions as described in "Effective C++: Third Edition"
00182   // Item 46.
00183 
00185   template<typename T2>
00186   friend bool Teuchos::operator==( const Array<T2> &a1, const Array<T2> &a2 );
00187 
00189   template<typename T2>
00190   friend bool Teuchos::operator!=( const Array<T2> &a1, const Array<T2> &a2 );
00191 
00193   template<typename T2>
00194   friend void swap( Array<T2> &a1, Array<T2> &a2 );
00195 
00197   template<typename T2>
00198   friend bool Teuchos::operator<( const Array<T2> &a1, const Array<T2> &a2 );
00199 
00201   template<typename T2>
00202   friend bool Teuchos::operator<=( const Array<T2> &a1, const Array<T2> &a2 );
00203 
00205   template<typename T2>
00206   friend bool Teuchos::operator>( const Array<T2> &a1, const Array<T2> &a2 );
00207 
00209   template<typename T2>
00210   friend bool Teuchos::operator>=( const Array<T2> &a1, const Array<T2> &a2 );
00211 
00214 
00216   typedef Teuchos_Ordinal Ordinal;
00218   typedef Ordinal size_type;
00220   typedef Ordinal difference_type;
00222   typedef typename std::vector<T>::value_type value_type;
00224   typedef typename std::vector<T>::pointer pointer;
00226   typedef typename std::vector<T>::const_pointer const_pointer;
00228   typedef typename std::vector<T>::reference reference;
00230   typedef typename std::vector<T>::const_reference const_reference;
00232   typedef typename std::vector<T>::allocator_type allocator_type;
00233 
00234 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00235 
00236   typedef ArrayRCP<T> iterator;
00238   typedef ArrayRCP<const T> const_iterator;
00240   typedef std::reverse_iterator<iterator> reverse_iterator;
00242   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00243 #else
00244 
00245   typedef typename std::vector<T>::iterator iterator;
00247   typedef typename std::vector<T>::const_iterator const_iterator;
00249   typedef typename std::vector<T>::reverse_iterator reverse_iterator;
00251   typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
00252 #endif
00253 
00255 
00257 
00259   inline Array();
00260 
00262   inline explicit Array(size_type n, const value_type& value = value_type());
00263 
00265   inline Array(const Array<T>& x);
00266 
00268   template<typename InputIterator>
00269   inline Array(InputIterator first, InputIterator last);
00270 
00272   inline Array(const ArrayView<const T>& a);
00273 
00275   template<int N>
00276   inline Array(const Tuple<T,N>& t);
00277 
00279   inline ~Array();
00280 
00282   inline Array& operator=(const Array<T>& a);
00283 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00293   inline void assign(size_type n, const value_type& val);
00295   template<typename InputIterator>
00296   inline void assign(InputIterator first, InputIterator last);
00298   inline iterator begin();
00300   inline iterator end();
00302   inline const_iterator begin() const;
00304   inline const_iterator end() const;
00306   inline reverse_iterator rbegin();
00308   inline reverse_iterator rend();
00310   inline const_reverse_iterator rbegin() const;
00312   inline const_reverse_iterator rend() const;
00314   inline size_type size() const;
00316   inline size_type max_size() const;
00318   inline void resize(size_type new_size, const value_type& x = value_type());
00320   inline size_type capacity() const;
00322   inline bool empty() const;
00324   inline void reserve(size_type n);
00326   inline reference operator[](size_type i);
00328   inline const_reference operator[](size_type i) const;
00330   inline reference at(size_type i);
00332   inline const_reference at(size_type i) const;
00334   inline reference front();
00336   inline const_reference front() const;
00338   inline reference back();
00340   inline const_reference back() const;
00342   inline void push_back(const value_type& x);
00344   inline void pop_back();
00346   inline iterator insert(iterator position, const value_type& x);
00348   inline void insert(iterator position, size_type n, const value_type& x);
00350   template<typename InputIterator>
00351   inline void insert(iterator position, InputIterator first, InputIterator last);
00353   inline iterator erase(iterator position);
00355   inline iterator erase(iterator first, iterator last);
00357   inline void swap(Array& x);
00359   inline void clear();
00360 
00362 
00364 
00369   inline Array<T>& append(const T& x);
00370 
00374   inline void remove(int i);
00375 
00380   inline int length() const;
00381 
00383   inline std::string toString() const;
00384 
00386   inline static bool hasBoundsChecking();
00387 
00389   inline T* getRawPtr();
00390 
00392   inline const T* getRawPtr() const;
00393 
00395 
00397 
00399   inline Array( const std::vector<T> &v );
00400 
00402   inline std::vector<T> toVector() const;
00403 
00405   inline Array& operator=( const std::vector<T> &v );
00406 
00408 
00410 
00411 
00425         inline ArrayView<T> view( size_type offset, size_type size );
00426 
00440         inline ArrayView<const T> view( size_type offset, size_type size ) const;
00441 
00445         inline ArrayView<T> operator()( size_type offset, size_type size );
00446 
00450         inline ArrayView<const T> operator()( size_type offset, size_type size ) const;
00451 
00456         inline ArrayView<T> operator()();
00457 
00462         inline ArrayView<const T> operator()() const;
00463 
00467         inline operator ArrayView<T>();
00468 
00472         inline operator ArrayView<const T>() const;
00473 
00475 
00476 private:
00477 
00478 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00479   RCP<std::vector<T> > vec_;
00480   mutable ArrayRCP<T> extern_arcp_;
00481   mutable ArrayRCP<const T> extern_carcp_;
00482 #else
00483   std::vector<T> vec_;
00484 #endif
00485 
00486   inline std::vector<T>& vec(
00487     bool isStructureBeingModified = false,
00488     bool activeIter = false
00489     );
00490 
00491   inline const std::vector<T>& vec() const;
00492 
00493   inline typename std::vector<T>::iterator
00494   raw_position( iterator position );
00495 
00496   inline void assertIndex(size_type i) const;
00497 
00498   inline void assertNotNull() const;
00499 
00500 };
00501 
00502 
00508 template<class T>
00509 ArrayRCP<T> arcp( const RCP<Array<T> > &v )
00510 {
00511   if ( is_null(v) || !v->size() )
00512     return null;
00513   return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
00514     &(*v)[0], 0, v->size(),
00515     v, false
00516     );
00517 }
00518 
00519 
00525 template<class T>
00526 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
00527 {
00528   if ( is_null(v) || !v->size() )
00529     return null;
00530   return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
00531     &(*v)[0], 0, v->size(),
00532     v, false
00533     );
00534 }
00535 
00536 
00542 template<class T>
00543 ArrayRCP<T> arcpFromArray( Array<T> &a )
00544 {
00545   if (a.size() == 0)
00546     return null;
00547 #ifdef TEUCHOS_DEBUG
00548   return a.begin(); // Catch dangling reference!
00549 #else
00550   return arcp(a.getRawPtr(), 0, a.size(), false);
00551 #endif
00552 }
00553 
00554 
00560 template<class T>
00561 ArrayRCP<const T> arcpFromArray( const Array<T> &a )
00562 {
00563   if (a.size() == 0)
00564     return null;
00565 #ifdef TEUCHOS_DEBUG
00566   return a.begin(); // Catch dangling reference!
00567 #else
00568   return arcp(a.getRawPtr(), 0, a.size(), false);
00569 #endif
00570 }
00571 
00572 
00585 template<typename T>
00586 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
00587 
00588 
00593 template<typename T> inline
00594 int hashCode(const Array<T>& array);
00595 
00596 
00603 template<typename T> inline
00604 std::vector<T> createVector( const Array<T> &a );
00605 
00606 
00611 template<typename T>
00612 std::string toString(const Array<T>& array);
00613 
00614 
00666 template<typename T>
00667 Array<T> fromStringToArray(const std::string& arrayStr);
00668 
00674 template<typename T>
00675 std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
00676   array = fromStringToArray<T>(in.str());
00677   return in;
00678 }
00679 
00685 template<typename T> inline
00686 void extractDataFromISS( std::istringstream& iss, T& data )
00687 {
00688   iss >> data; // Assumes type has operator>>(...) defined!
00689 }
00690 
00697 inline
00698 void extractDataFromISS( std::istringstream& iss, std::string& data )
00699 {
00700   // grab unformatted string.
00701   data = iss.str();
00702   // remove white space from beginning and end of string.
00703   data = Utils::trimWhiteSpace(data);
00704 }
00705 
00715 inline
00716 std::string getArrayTypeNameTraitsFormat(){
00717   return "Array(*)";
00718 }
00719 
00720 
00721 
00737 template<typename T>
00738 class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<Array<T> > {
00739 public:
00740   static std::string name(){
00741     std::string formatString = getArrayTypeNameTraitsFormat();
00742     size_t starPos = formatString.find("*");
00743     std::string prefix = formatString.substr(0,starPos);
00744     std::string postFix = formatString.substr(starPos+1);
00745     return prefix+TypeNameTraits<T>::name()+postFix;
00746   }
00747   static std::string concreteName(const Array<T>&)
00748     { return name(); }
00749 };
00750 
00751 
00752 } // namespace Teuchos
00753 
00754 
00755 //
00756 // Implementation
00757 //
00758 
00759 
00760 namespace Teuchos {
00761 
00762 
00763 // All constructors
00764 
00765 
00766 template<typename T> inline
00767 Array<T>::Array()
00768 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00769   : vec_(rcp(new std::vector<T>()))
00770 #endif
00771 {}
00772 
00773 
00774 template<typename T> inline
00775 Array<T>::Array(size_type n, const value_type& value) :
00776 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00777   vec_(rcp(new std::vector<T>(n,value)))
00778 #else
00779   vec_(n, value)
00780 #endif
00781 {}
00782 
00783 
00784 template<typename T> inline
00785 Array<T>::Array(const Array<T>& x) :
00786 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00787   vec_(rcp(new std::vector<T>(*x.vec_)))
00788 #else
00789   vec_(x.vec_)
00790 #endif
00791 {}
00792 
00793 
00794 template<typename T> template<typename InputIterator> inline
00795 Array<T>::Array(InputIterator first, InputIterator last) :
00796 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00797   vec_(rcp(new std::vector<T>(first, last)))
00798 #else
00799   vec_(first, last)
00800 #endif
00801 {}
00802 
00803 
00804 template<typename T> inline
00805 Array<T>::~Array()
00806 {}
00807 
00808 
00809 template<typename T> inline
00810 Array<T>::Array(const ArrayView<const T>& a)
00811 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00812   : vec_(rcp(new std::vector<T>()))
00813 #endif
00814 {
00815   insert(begin(), a.begin(), a.end());
00816 }
00817 
00818 
00819 template<typename T>
00820 template<int N>
00821 inline
00822 Array<T>::Array(const Tuple<T,N>& t)
00823 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00824   : vec_(rcp(new std::vector<T>()))
00825 #endif
00826 {
00827   insert(begin(), t.begin(), t.end());
00828 }
00829 
00830 
00831 template<typename T> inline
00832 Array<T>& Array<T>::operator=(const Array& a)
00833 {
00834   vec(true) = a.vec();
00835   return *this;
00836 }
00837 
00838 
00839 // Other std::vector functions
00840 
00841 
00842 template<typename T> inline
00843 void Array<T>::assign(size_type n, const value_type& val)
00844 {
00845   vec(true).assign(n,val);
00846 }
00847 
00848 
00849 template<typename T> template<typename InputIterator> inline
00850 void Array<T>::assign(InputIterator first, InputIterator last)
00851 {
00852   vec(true).assign(first,last);
00853 }
00854 
00855 
00856 template<typename T> inline
00857 typename Array<T>::iterator
00858 Array<T>::begin()
00859 {
00860 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00861   if (is_null(extern_arcp_)) {
00862     // Here we must use the same RCP to avoid creating two unrelated RCPNodes!
00863     extern_arcp_ = arcp(vec_); // Will be null if vec_ is sized!
00864   }
00865   // Returning a weak pointer will help to catch dangling references but still
00866   // keep the same behavior as optimized code.
00867   return extern_arcp_.create_weak();
00868 #else
00869   return vec().begin();
00870 #endif
00871 }
00872 
00873 
00874 template<typename T> inline
00875 typename Array<T>::iterator
00876 Array<T>::end()
00877 {
00878 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00879   return begin() + size();
00880 #else
00881   return vec().end();
00882 #endif
00883 }
00884 
00885 
00886 template<typename T> inline
00887 typename Array<T>::const_iterator
00888 Array<T>::begin() const
00889 {
00890 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00891   if (is_null(extern_carcp_)) {
00892     extern_carcp_ = const_cast<Array<T>*>(this)->begin();
00893   }
00894   // Returning a weak pointer will help to catch dangling references but still
00895   // keep the same behavior as optimized code.
00896   return extern_carcp_.create_weak();
00897 #else
00898   return vec().begin();
00899 #endif
00900 }
00901 
00902 
00903 template<typename T> inline
00904 typename Array<T>::const_iterator
00905 Array<T>::end() const
00906 {
00907 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00908   return begin() + size();
00909 #else
00910   return vec().end();
00911 #endif
00912 }
00913 
00914 
00915 template<typename T> inline
00916 typename Array<T>::reverse_iterator
00917 Array<T>::rbegin()
00918 {
00919 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00920   return reverse_iterator(end());
00921 #else
00922   return vec().rbegin();
00923 #endif
00924 }
00925 
00926 
00927 template<typename T> inline
00928 typename Array<T>::reverse_iterator
00929 Array<T>::rend()
00930 {
00931 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00932   return reverse_iterator(begin());
00933 #else
00934   return vec().rend();
00935 #endif
00936 }
00937 
00938 
00939 template<typename T> inline
00940 typename Array<T>::const_reverse_iterator
00941 Array<T>::rbegin() const
00942 {
00943 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00944   return const_reverse_iterator(end());
00945 #else
00946   return vec().rbegin();
00947 #endif
00948 }
00949 
00950 
00951 template<typename T> inline
00952 typename Array<T>::const_reverse_iterator
00953 Array<T>::rend() const
00954 {
00955 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00956   return const_reverse_iterator(begin());
00957 #else
00958   return vec().rend();
00959 #endif
00960 }
00961 
00962 
00963 template<typename T> inline
00964 typename Array<T>::size_type
00965 Array<T>::size() const
00966 {
00967   return vec().size();
00968 }
00969 
00970 
00971 template<typename T> inline
00972 typename Array<T>::size_type
00973 Array<T>::max_size() const
00974 {
00975   return std::numeric_limits<size_type>::max();
00976 }
00977 
00978 
00979 template<typename T> inline
00980 void
00981 Array<T>::resize(size_type new_size, const value_type& x)
00982 {
00983   vec(true).resize(new_size,x);
00984 }
00985 
00986 
00987 template<typename T> inline
00988 typename Array<T>::size_type
00989 Array<T>::capacity() const
00990 {
00991   return vec().capacity();
00992 }
00993 
00994 
00995 template<typename T> inline
00996 bool Array<T>::empty() const
00997 {
00998   return vec().empty();
00999 }
01000 
01001 
01002 template<typename T> inline
01003 void Array<T>::reserve(size_type n)
01004 {
01005   vec(true).reserve(n);
01006 }
01007 
01008 
01009 template<typename T> inline
01010 typename Array<T>::reference
01011 Array<T>::operator[](size_type i)
01012 {
01013 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01014   assertIndex(i);
01015 #endif
01016   return vec()[i];
01017 }
01018 
01019 
01020 template<typename T> inline
01021 typename Array<T>::const_reference
01022 Array<T>::operator[](size_type i) const
01023 {
01024 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01025   assertIndex(i);
01026 #endif
01027   return vec()[i];
01028 }
01029 
01030 
01031 template<typename T> inline
01032 typename Array<T>::reference
01033 Array<T>::at(size_type i)
01034 {
01035 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01036   assertIndex(i);
01037 #endif
01038   return vec().at(i);
01039 }
01040 
01041 
01042 template<typename T> inline
01043 typename Array<T>::const_reference
01044 Array<T>::at(size_type i) const
01045 {
01046 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01047   assertIndex(i);
01048 #endif
01049   return vec().at(i);
01050 }
01051 
01052 
01053 template<typename T> inline
01054 typename Array<T>::reference
01055 Array<T>::front()
01056 {
01057 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01058   assertNotNull();
01059 #endif
01060   return vec().front();
01061 }
01062 
01063 
01064 template<typename T> inline
01065 typename Array<T>::const_reference
01066 Array<T>::front() const
01067 {
01068 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01069   assertNotNull();
01070 #endif
01071   return vec().front();
01072 }
01073 
01074 
01075 template<typename T> inline
01076 typename Array<T>::reference
01077 Array<T>::back()
01078 {
01079 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01080   assertNotNull();
01081 #endif
01082   return vec().back();
01083 }
01084 
01085 
01086 template<typename T> inline
01087 typename Array<T>::const_reference
01088 Array<T>::back() const
01089 {
01090 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01091   assertNotNull();
01092 #endif
01093   return vec().back();
01094 }
01095 
01096 
01097 template<typename T> inline
01098 void Array<T>::push_back(const value_type& x)
01099 {
01100   vec(true).push_back(x);
01101 }
01102 
01103 
01104 template<typename T> inline
01105 void Array<T>::pop_back()
01106 {
01107 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01108   assertNotNull();
01109 #endif
01110   vec(true).pop_back();
01111 }
01112 
01113 
01114 // 2009/11/13:: rabartl: After moving to a full RCPNode tracing and lookup
01115 // model, I had to how modifying functions like insert(...) and erase(...)
01116 // work which have active iterators controled by the client and yet need to
01117 // allow the structure of the container change.  The way these troublesome
01118 // functions work is that first the raw std::vector iterator is extracted.
01119 // The function vec(true, true) then deletes the strong iterators but there is
01120 // still a weak ArrayRCP object that is owned by the client which is being
01121 // passed into this function.  The issue is that the design of ArrayRCP is
01122 // such that the RCPNode object is not removed but instead remains in order to
01123 // perform runtime checking.
01124 
01125 
01126 template<typename T> inline
01127 typename Array<T>::iterator
01128 Array<T>::insert(iterator position, const value_type& x)
01129 {
01130 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01131   // Assert a valid iterator and get vector iterator
01132   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01133   const difference_type i = position - begin();
01134   vec(true, true).insert(raw_poss, x);
01135   return begin() + i;
01136 #else
01137   return vec_.insert(position, x);
01138 #endif
01139 }
01140 
01141 
01142 template<typename T> inline
01143 void Array<T>::insert(iterator position, size_type n, const value_type& x)
01144 {
01145 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01146   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01147   vec(true, true).insert(raw_poss, n, x);
01148 #else
01149   vec_.insert(position, n, x);
01150 #endif
01151 }
01152 
01153 
01154 template<typename T> template<typename InputIterator> inline
01155 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
01156 {
01157 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01158   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01159   vec(true, true).insert(raw_poss, first, last);
01160 #else
01161   vec_.insert(position, first, last);
01162 #endif
01163 }
01164 
01165 
01166 template<typename T> inline
01167 typename Array<T>::iterator
01168 Array<T>::erase(iterator position)
01169 {
01170 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01171   assertNotNull();
01172   // Assert a valid iterator and get vector iterator
01173   const typename std::vector<T>::iterator raw_poss = raw_position(position);
01174   const difference_type i = position - begin();
01175   vec(true, true).erase(raw_poss);
01176   return begin() + i;
01177 #else
01178   return vec_.erase(position);
01179 #endif
01180 }
01181 
01182 
01183 template<typename T> inline
01184 typename Array<T>::iterator
01185 Array<T>::erase(iterator first, iterator last)
01186 {
01187 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01188   if (empty()) {
01189     TEUCHOS_ASSERT(first == begin());
01190     TEUCHOS_ASSERT(last == end());
01191     return end();
01192   }
01193   assertNotNull();
01194   // Assert a valid iterator and get vector iterator
01195   const typename std::vector<T>::iterator raw_first = raw_position(first);
01196   const typename std::vector<T>::iterator raw_last = raw_position(last);
01197   const difference_type i = first - begin();
01198   vec(true,true).erase(raw_first,raw_last);
01199   return begin() + i;
01200 #else
01201   return vec_.erase(first,last);
01202 #endif
01203 }
01204 
01205 
01206 template<typename T> inline
01207 void Array<T>::swap(Array& x)
01208 {
01209   vec(true).swap(x.vec());
01210 }
01211 
01212 
01213 template<typename T> inline
01214 void Array<T>::clear()
01215 {
01216   vec(true).clear();
01217 }
01218 
01219 
01220 // Non-standard functions
01221 
01222 
01223 template<typename T> inline
01224 Array<T>& Array<T>::append(const T& x)
01225 {
01226   this->push_back(x);
01227   return *this;
01228 }
01229 
01230 
01231 template<typename T> inline
01232 void Array<T>::remove(int i)
01233 {
01234 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01235   assertIndex(i);
01236 #endif
01237   // Erase the i-th element of this array.
01238   this->erase( this->begin() + i );
01239 }
01240 
01241 
01242 template<typename T> inline
01243 int Array<T>::length() const
01244 {
01245   return static_cast<int> (this->size ());
01246 }
01247 
01248 
01249 template<typename T> inline
01250 std::string Array<T>::toString() const
01251 {
01252   return (*this)().toString(); // Use ArrayView<T>::toString()
01253 }
01254 
01255 
01256 template<typename T> inline
01257 bool Array<T>::hasBoundsChecking()
01258 {
01259 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01260   return true;
01261 #else
01262   return false;
01263 #endif
01264 }
01265 
01266 
01267 template<typename T> inline
01268 T* Array<T>::getRawPtr()
01269 {
01270   return ( size() ? &(*this)[0] : 0 );
01271 }
01272 
01273 
01274 template<typename T> inline
01275 const T* Array<T>::getRawPtr() const
01276 {
01277   return ( size() ? &(*this)[0] : 0 );
01278 }
01279 
01280 
01281 // Conversions to and from std::vector
01282 
01283 
01284 template<typename T> inline
01285 Array<T>::Array( const std::vector<T> &v ) :
01286 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01287   vec_(new std::vector<T>(v))
01288 #else
01289   vec_(v)
01290 #endif
01291 {}
01292 
01293 
01294 template<typename T> inline
01295 std::vector<T> Array<T>::toVector() const
01296 {
01297   if (!size())
01298     return std::vector<T>();
01299   std::vector<T> v(begin(),end());
01300   return v;
01301 }
01302 
01303 
01304 template<typename T> inline
01305 Array<T>& Array<T>::operator=( const std::vector<T> &v )
01306 {
01307   vec(true) = v;
01308   return *this;
01309 }
01310 
01311 
01312 // Views
01313 
01314 
01315 template<typename T> inline
01316 ArrayView<T> Array<T>::view( size_type offset, size_type size_in )
01317 {
01318   if (size_in) {
01319 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01320     return ArrayView<T>(this->begin().persistingView(offset, size_in));
01321 #else
01322     return arrayView( &vec()[offset], size_in );
01323 #endif
01324   }
01325   return Teuchos::null;
01326 }
01327 
01328 
01329 template<typename T> inline
01330 ArrayView<const T> Array<T>::view( size_type offset, size_type size_in ) const
01331 {
01332   if (size_in) {
01333 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01334     return ArrayView<const T>(this->begin().persistingView(offset, size_in));
01335 #else
01336     return arrayView( &vec()[offset], size_in );
01337 #endif
01338   }
01339   return Teuchos::null;
01340   // NOTE: Above, we use a different implementation to call the const version
01341   // of begin() instead of the non-const version.  This sets up a different
01342   // ArrayRCP object that gets checked.
01343 }
01344 
01345 
01346 template<typename T> inline
01347 ArrayView<T> Array<T>::operator()( size_type offset, size_type size_in )
01348 {
01349   return view(offset, size_in);
01350 }
01351 
01352 
01353 template<typename T> inline
01354 ArrayView<const T> Array<T>::operator()( size_type offset, size_type size_in ) const
01355 {
01356   return view(offset, size_in);
01357 }
01358 
01359 
01360 template<typename T> inline
01361 ArrayView<T> Array<T>::operator()()
01362 {
01363   if (!size())
01364     return null;
01365   return this->view(0, size());
01366 }
01367 
01368 
01369 template<typename T> inline
01370 ArrayView<const T> Array<T>::operator()() const
01371 {
01372   if (!size())
01373     return null;
01374   return this->view(0, size());
01375 }
01376 
01377 
01378 template<typename T> inline
01379 Array<T>::operator ArrayView<T>()
01380 {
01381   return this->operator()();
01382 }
01383 
01384 
01385 template<typename T> inline
01386 Array<T>::operator ArrayView<const T>() const
01387 {
01388   return this->operator()();
01389 }
01390 
01391 
01392 // private
01393 
01394 
01395 template<typename T>
01396 std::vector<T>&
01397 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
01398 {
01399 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01400   (void)activeIter;
01401   if (isStructureBeingModified) {
01402     // Give up my ArrayRCPs used for iterator access since the array we be
01403     // getting modifed!  Any clients that have views through weak pointers
01404     // better not touch them!
01405     extern_arcp_ = null;
01406     extern_carcp_ = null;
01407   }
01408   return *vec_;
01409 #else
01410   // get rid of "unused parameter" warnings
01411   (void)isStructureBeingModified;
01412   (void)activeIter;
01413   return vec_;
01414 #endif
01415 }
01416 
01417 
01418 template<typename T> inline
01419 const std::vector<T>&
01420 Array<T>::vec() const
01421 {
01422 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01423   return *vec_;
01424 #else
01425   return vec_;
01426 #endif
01427 }
01428 
01429 
01430 template<typename T> inline
01431 typename std::vector<T>::iterator
01432 Array<T>::raw_position( iterator position )
01433 {
01434 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01435   const iterator first = this->begin();
01436   const iterator last = this->end();
01437   TEUCHOS_TEST_FOR_EXCEPTION(
01438     !(first <= position && position <= last), DanglingReferenceError,
01439     "Error, this iterator is no longer valid for this Aray!"
01440     );
01441   // Note, above operator<=(...) functions will throw
01442   // IncompatibleIteratorsError if the iterators do not share the same
01443   // RCP_node object!
01444   return vec_->begin() + (position - this->begin());
01445 #else
01446   return position;
01447 #endif
01448 }
01449 
01450 
01451 template<typename T> inline
01452 void Array<T>::assertIndex(size_type i) const
01453 {
01454   TEUCHOS_TEST_FOR_EXCEPTION(
01455     !( 0 <= i && i < size() ), RangeError,
01456     "Array<T>::assertIndex(i): i="<<i<<" out of range [0, "<< size() << ")"
01457     );
01458 }
01459 
01460 
01461 template<typename T> inline
01462 void Array<T>::assertNotNull() const
01463 {
01464   TEUCHOS_TEST_FOR_EXCEPTION(
01465     !size(), NullReferenceError,
01466     typeName(*this)<<"::assertNotNull(): "
01467     "Error, the array has size zero!"
01468     );
01469 }
01470 
01471 
01472 } // namespace Teuchos
01473 
01474 
01475 // Nonmember functions
01476 
01477 
01478 template<typename T> inline
01479 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
01480 { return (a1.vec() == a2.vec()); }
01481 
01482 
01483 template<typename T> inline
01484 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
01485 { return (a1.vec() != a2.vec()); }
01486 
01487 
01488 template<typename T> inline
01489 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
01490 { a1.swap(a2); }
01491 
01492 
01493 template<typename T> inline
01494 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
01495 { return (a1.vec() < a2.vec()); }
01496 
01497 
01498 template<typename T> inline
01499 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
01500 { return (a1.vec() <= a2.vec()); }
01501 
01502 
01503 template<typename T> inline
01504 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
01505 { return (a1.vec() > a2.vec()); }
01506 
01507 
01508 template<typename T> inline
01509 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
01510 { return (a1.vec() >= a2.vec()); }
01511 
01512 
01513 template<typename T> inline
01514 std::ostream& Teuchos::operator<<(
01515   std::ostream& os, const Array<T>& array
01516   )
01517 {
01518   return os << Teuchos::toString(array);
01519 }
01520 
01521 
01522 template<typename T> inline
01523 int Teuchos::hashCode(const Array<T>& array)
01524 {
01525   int rtn = hashCode(array.length());
01526   for (int i=0; i<array.length(); i++)
01527   {
01528     rtn += hashCode(array[i]);
01529   }
01530   return rtn;
01531 }
01532 
01533 
01534 template<typename T> inline
01535 std::vector<T> Teuchos::createVector( const Array<T> &a )
01536 {
01537   return a.toVector();
01538 }
01539 
01540 
01541 template<typename T> inline
01542 std::string Teuchos::toString(const Array<T>& array)
01543 {
01544   return array.toString();
01545 }
01546 
01547 
01548 template<typename T>
01549 Teuchos::Array<T>
01550 Teuchos::fromStringToArray(const std::string& arrayStr)
01551 {
01552   const std::string str = Utils::trimWhiteSpace(arrayStr);
01553   std::istringstream iss(str);
01554   TEUCHOS_TEST_FOR_EXCEPTION(
01555     ( str[0]!='{' || str[str.length()-1] != '}' )
01556     ,InvalidArrayStringRepresentation
01557     ,"Error, the std::string:\n"
01558     "----------\n"
01559     <<str<<
01560     "\n----------\n"
01561     "is not a valid array represntation!"
01562     );
01563   char c;
01564   c = iss.get(); // Read initial '{'
01565   TEUCHOS_TEST_FOR_EXCEPT(c!='{'); // Should not throw!
01566   // Now we are ready to begin reading the entries of the array!
01567   Array<T> a;
01568   while( !iss.eof() ) {
01569     // Get the basic entry std::string
01570     std::string entryStr;
01571     std::getline(iss,entryStr,','); // Get next entry up to ,!
01572     // ToDo: Above, we might have to be careful to look for the opening and
01573     // closing of parentheses in order not to pick up an internal ',' in the
01574     // middle of an entry (for a std::complex number for instance).  The above
01575     // implementation assumes that there will be no commas in the middle of
01576     // the std::string representation of an entry.  This is certainly true for
01577     // the types bool, int, float, and double.
01578     //
01579     // Trim whitespace from beginning and end
01580     entryStr = Utils::trimWhiteSpace(entryStr);
01581     TEUCHOS_TEST_FOR_EXCEPTION(
01582       0 == entryStr.length(),
01583       InvalidArrayStringRepresentation,
01584       "Error, the std::string:\n"
01585       "----------\n"
01586       <<str<<
01587       "\n----------\n"
01588       "is not a valid array represntation because it has an empty array entry!"
01589       );
01590     // Remove the final '}' if this is the last entry and we did not
01591     // actually terminate the above getline(...) on ','
01592     bool found_end = false;
01593     if(entryStr[entryStr.length()-1]=='}') {
01594       entryStr = entryStr.substr(0,entryStr.length()-1);
01595       found_end = true;
01596       if( entryStr.length()==0 && a.size()==0 )
01597         return a; // This is the empty array "{}" (with any spaces in it!)
01598     }
01599     // Finally we can convert the entry and add it to the array!
01600     std::istringstream entryiss(entryStr);
01601     T entry;
01602     Teuchos::extractDataFromISS( entryiss, entry );
01603     // ToDo: We may need to define a traits class to allow us to specialized
01604     // how conversion from a std::string to a object is done!
01605     a.push_back(entry);
01606     // At the end of the loop body here, if we have reached the last '}'
01607     // then the input stream iss should be empty and iss.eof() should be
01608     // true, so the loop should terminate.  We put an std::exception test here
01609     // just in case something has gone wrong.
01610     TEUCHOS_TEST_FOR_EXCEPTION(
01611       found_end && !iss.eof()
01612       ,InvalidArrayStringRepresentation
01613       ,"Error, the std::string:\n"
01614       "----------\n"
01615       <<str<<
01616       "\n----------\n"
01617       "is not a valid array represntation!"
01618       );
01619   }
01620   return a;
01621 }
01622 
01623 
01624 #endif // TEUCHOS_ARRAY_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines