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