00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00060
00061
00062
00063
00064
00065
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
00167
00168
00169
00170
00172 template<typename T2>
00173 friend bool Teuchos::operator==( const Array<T2> &a1, const Array<T2> &a2 );
00174
00176 template<typename T2>
00177 friend bool Teuchos::operator!=( const Array<T2> &a1, const Array<T2> &a2 );
00178
00180 template<typename T2>
00181 friend void swap( Array<T2> &a1, Array<T2> &a2 );
00182
00184 template<typename T2>
00185 friend bool Teuchos::operator<( const Array<T2> &a1, const Array<T2> &a2 );
00186
00188 template<typename T2>
00189 friend bool Teuchos::operator<=( const Array<T2> &a1, const Array<T2> &a2 );
00190
00192 template<typename T2>
00193 friend bool Teuchos::operator>( const Array<T2> &a1, const Array<T2> &a2 );
00194
00196 template<typename T2>
00197 friend bool Teuchos::operator>=( const Array<T2> &a1, const Array<T2> &a2 );
00198
00201
00203 typedef typename std::vector<T>::value_type value_type;
00205 typedef typename std::vector<T>::pointer pointer;
00207 typedef typename std::vector<T>::const_pointer const_pointer;
00209 typedef typename std::vector<T>::reference reference;
00211 typedef typename std::vector<T>::const_reference const_reference;
00212
00214 typedef Teuchos_Index Ordinal;
00215
00216 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00217
00218 typedef ArrayRCP<T> iterator;
00220 typedef ArrayRCP<const T> const_iterator;
00222 typedef std::reverse_iterator<iterator> reverse_iterator;
00224 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00225 #else
00226
00227 typedef typename std::vector<T>::iterator iterator;
00229 typedef typename std::vector<T>::const_iterator const_iterator;
00231 typedef typename std::vector<T>::reverse_iterator reverse_iterator;
00233 typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
00234 #endif
00235
00237 typedef typename std::vector<T>::size_type size_type;
00239 typedef typename std::vector<T>::difference_type difference_type;
00241 typedef typename std::vector<T>::allocator_type allocator_type;
00242
00244
00247
00248
00250 Array();
00252 explicit Array(Ordinal n, const value_type& value = value_type());
00254 Array(const Array<T>& x);
00256 template<typename InputIterator>
00257 Array(InputIterator first, InputIterator last);
00259 Array(const ArrayView<const T>& a);
00261 template<int N>
00262 Array(const Tuple<T,N>& t);
00264 ~Array();
00266 Array& operator=(const Array<T>& a);
00267
00269
00272
00274 void assign(Ordinal n, const value_type& val);
00276 template<typename InputIterator>
00277 void assign(InputIterator first, InputIterator last);
00279 iterator begin();
00281 iterator end();
00283 const_iterator begin() const;
00285 const_iterator end() const;
00287 reverse_iterator rbegin();
00289 reverse_iterator rend();
00291 const_reverse_iterator rbegin() const;
00293 const_reverse_iterator rend() const;
00295 size_type size() const;
00297 size_type max_size() const;
00299 void resize(Ordinal new_size, const value_type& x = value_type());
00301 size_type capacity() const;
00303 bool empty() const;
00305 void reserve(Ordinal n);
00307 reference operator[](Ordinal i);
00309 const_reference operator[](Ordinal i) const;
00311 reference at(Ordinal i);
00313 const_reference at(Ordinal i) const;
00315 reference front();
00317 const_reference front() const;
00319 reference back();
00321 const_reference back() const;
00323 void push_back(const value_type& x);
00325 void pop_back();
00327 iterator insert(iterator position, const value_type& x);
00329 void insert(iterator position, Ordinal n, const value_type& x);
00331 template<typename InputIterator>
00332 void insert(iterator position, InputIterator first, InputIterator last);
00334 iterator erase(iterator position);
00336 iterator erase(iterator first, iterator last);
00338 void swap(Array& x);
00340 void clear();
00341
00343
00346
00351 Array<T>& append(const T& x);
00352
00356 void remove(int i);
00357
00362 inline int length() const;
00363
00365 inline std::string toString() const;
00366
00368 inline static bool hasBoundsChecking();
00369
00371 inline T* getRawPtr();
00372
00374 inline const T* getRawPtr() const;
00375
00377
00380
00382 Array( const std::vector<T> &v );
00383
00385 std::vector<T> toVector() const;
00386
00388 Array& operator=( const std::vector<T> &v );
00389
00391
00393
00394
00406 ArrayView<T> view( Ordinal offset, Ordinal size );
00407
00419 ArrayView<const T> view( Ordinal offset, Ordinal size ) const;
00420
00424 ArrayView<T> operator()( Ordinal offset, Ordinal size );
00425
00429 ArrayView<const T> operator()( Ordinal offset, Ordinal size ) const;
00430
00435 ArrayView<T> operator()();
00436
00441 ArrayView<const T> operator()() const;
00442
00446 operator ArrayView<T>();
00447
00451 operator ArrayView<const T>() const;
00452
00454
00455 private:
00456
00457 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00458 RCP<std::vector<T> > vec_;
00459 mutable ArrayRCP<T> extern_arcp_;
00460 mutable ArrayRCP<const T> extern_carcp_;
00461 #else
00462 std::vector<T> vec_;
00463 #endif
00464
00465 inline std::vector<T>& vec(
00466 bool isStructureBeingModified = false,
00467 bool activeIter = false
00468 );
00469
00470 inline const std::vector<T>& vec() const;
00471
00472 inline typename std::vector<T>::iterator
00473 raw_position( iterator position );
00474
00475 inline void assertIndex(int i) const;
00476
00477 inline void assertNotNull() const;
00478
00479 };
00480
00481
00487 template<class T>
00488 ArrayRCP<T> arcp( const RCP<Array<T> > &v )
00489 {
00490 if ( is_null(v) || !v->size() )
00491 return null;
00492 return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
00493 &(*v)[0], 0, v->size(),
00494 v, false
00495 );
00496 }
00497
00498
00504 template<class T>
00505 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
00506 {
00507 if ( is_null(v) || !v->size() )
00508 return null;
00509 return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
00510 &(*v)[0], 0, v->size(),
00511 v, false
00512 );
00513 }
00514
00515
00528 template<typename T>
00529 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
00530
00531
00536 template<typename T> inline
00537 int hashCode(const Array<T>& array);
00538
00539
00546 template<typename T> inline
00547 std::vector<T> createVector( const Array<T> &a );
00548
00549
00554 template<typename T>
00555 std::string toString(const Array<T>& array);
00556
00557
00609 template<typename T>
00610 Array<T> fromStringToArray(const std::string& arrayStr);
00611
00617 template<typename T> inline
00618 void extractDataFromISS( std::istringstream& iss, T& data )
00619 {
00620 iss >> data;
00621 }
00622
00629 inline
00630 void extractDataFromISS( std::istringstream& iss, std::string& data )
00631 {
00632
00633 data = iss.str();
00634
00635 data = Utils::trimWhiteSpace(data);
00636 }
00637
00638 }
00639
00640
00641
00642
00643
00644
00645
00646 namespace Teuchos {
00647
00648
00649
00650
00651
00652 template<typename T> inline
00653 Array<T>::Array()
00654 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00655 : vec_(rcp(new std::vector<T>()))
00656 #endif
00657 {}
00658
00659
00660 template<typename T> inline
00661 Array<T>::Array(Ordinal n, const value_type& value) :
00662 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00663 vec_(rcp(new std::vector<T>(n,value)))
00664 #else
00665 vec_(n,value)
00666 #endif
00667 {}
00668
00669
00670 template<typename T> inline
00671 Array<T>::Array(const Array<T>& x) :
00672 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00673 vec_(rcp(new std::vector<T>(*x.vec_)))
00674 #else
00675 vec_(x.vec_)
00676 #endif
00677 {}
00678
00679
00680 template<typename T> template<typename InputIterator> inline
00681 Array<T>::Array(InputIterator first, InputIterator last) :
00682 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00683 vec_(rcp(new std::vector<T>(first,last)))
00684 #else
00685 vec_(first,last)
00686 #endif
00687 {}
00688
00689
00690 template<typename T> inline
00691 Array<T>::~Array()
00692 {
00693 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00694 const std::string errorMsg =
00695 "Error, there must be some client with a dangling reference to this array "
00696 "object! This could be a dangling iterator or a dangling view of something "
00697 "else.";
00698 TEST_FOR_EXCEPTION( extern_arcp_.count() > 1, DanglingReferenceError, errorMsg );
00699 extern_arcp_ = null;
00700 TEST_FOR_EXCEPTION( extern_carcp_.count() > 1, DanglingReferenceError, errorMsg );
00701 extern_carcp_ = null;
00702 TEST_FOR_EXCEPTION( vec_.count() > 1, DanglingReferenceError, errorMsg );
00703 #endif
00704 }
00705
00706
00707 template<typename T> inline
00708 Array<T>::Array(const ArrayView<const T>& a)
00709 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00710 : vec_(rcp(new std::vector<T>()))
00711 #endif
00712 {
00713 insert(begin(),a.begin(),a.end());
00714 }
00715
00716
00717 template<typename T>
00718 template<int N>
00719 inline
00720 Array<T>::Array(const Tuple<T,N>& t)
00721 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00722 : vec_(rcp(new std::vector<T>()))
00723 #endif
00724 {
00725 insert(begin(),t.begin(),t.end());
00726 }
00727
00728
00729 template<typename T> inline
00730 Array<T>& Array<T>::operator=(const Array& a)
00731 {
00732 vec(true) = a.vec();
00733 return *this;
00734 }
00735
00736
00737
00738
00739
00740 template<typename T> inline
00741 void Array<T>::assign(Ordinal n, const value_type& val)
00742 {
00743 vec(true).assign(n,val);
00744 }
00745
00746
00747 template<typename T> template<typename InputIterator> inline
00748 void Array<T>::assign(InputIterator first, InputIterator last)
00749 {
00750 vec(true).assign(first,last);
00751 }
00752
00753
00754 template<typename T> inline
00755 typename Array<T>::iterator
00756 Array<T>::begin()
00757 {
00758 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00759 if (is_null(extern_arcp_))
00760 extern_arcp_ = arcp(vec_);
00761 return extern_arcp_;
00762 #else
00763 return vec().begin();
00764 #endif
00765 }
00766
00767
00768 template<typename T> inline
00769 typename Array<T>::iterator
00770 Array<T>::end()
00771 {
00772 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00773 return begin() + size();
00774 #else
00775 return vec().end();
00776 #endif
00777 }
00778
00779
00780 template<typename T> inline
00781 typename Array<T>::const_iterator
00782 Array<T>::begin() const
00783 {
00784 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00785 if (is_null(extern_carcp_))
00786 extern_carcp_ = arcp(rcp_const_cast<const std::vector<T> >(vec_));
00787 return extern_carcp_;
00788 #else
00789 return vec().begin();
00790 #endif
00791 }
00792
00793
00794 template<typename T> inline
00795 typename Array<T>::const_iterator
00796 Array<T>::end() const
00797 {
00798 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00799 return begin() + size();
00800 #else
00801 return vec().end();
00802 #endif
00803 }
00804
00805
00806 template<typename T> inline
00807 typename Array<T>::reverse_iterator
00808 Array<T>::rbegin()
00809 {
00810 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00811 return reverse_iterator(end());
00812 #else
00813 return vec().rbegin();
00814 #endif
00815 }
00816
00817
00818 template<typename T> inline
00819 typename Array<T>::reverse_iterator
00820 Array<T>::rend()
00821 {
00822 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00823 return reverse_iterator(begin());
00824 #else
00825 return vec().rend();
00826 #endif
00827 }
00828
00829
00830 template<typename T> inline
00831 typename Array<T>::const_reverse_iterator
00832 Array<T>::rbegin() const
00833 {
00834 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00835 return const_reverse_iterator(end());
00836 #else
00837 return vec().rbegin();
00838 #endif
00839 }
00840
00841
00842 template<typename T> inline
00843 typename Array<T>::const_reverse_iterator
00844 Array<T>::rend() const
00845 {
00846 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00847 return const_reverse_iterator(begin());
00848 #else
00849 return vec().rend();
00850 #endif
00851 }
00852
00853
00854 template<typename T> inline
00855 typename Array<T>::size_type
00856 Array<T>::size() const
00857 {
00858 return vec().size();
00859 }
00860
00861
00862 template<typename T> inline
00863 typename Array<T>::size_type
00864 Array<T>::max_size() const
00865 {
00866 return vec().max_size();
00867 }
00868
00869
00870 template<typename T> inline
00871 void
00872 Array<T>::resize(Ordinal new_size, const value_type& x)
00873 {
00874 vec(true).resize(new_size,x);
00875 }
00876
00877
00878 template<typename T> inline
00879 typename Array<T>::size_type
00880 Array<T>::capacity() const
00881 {
00882 return vec().capacity();
00883 }
00884
00885
00886 template<typename T> inline
00887 bool Array<T>::empty() const
00888 {
00889 return vec().empty();
00890 }
00891
00892
00893 template<typename T> inline
00894 void Array<T>::reserve(Ordinal n)
00895 {
00896 vec(true).reserve(n);
00897 }
00898
00899
00900 template<typename T> inline
00901 typename Array<T>::reference
00902 Array<T>::operator[](Ordinal i)
00903 {
00904 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00905 assertIndex(i);
00906 #endif
00907 return vec()[i];
00908 }
00909
00910
00911 template<typename T> inline
00912 typename Array<T>::const_reference
00913 Array<T>::operator[](Ordinal i) const
00914 {
00915 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00916 assertIndex(i);
00917 #endif
00918 return vec()[i];
00919 }
00920
00921
00922 template<typename T> inline
00923 typename Array<T>::reference
00924 Array<T>::at(Ordinal i)
00925 {
00926 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00927 assertIndex(i);
00928 #endif
00929 return vec().at(i);
00930 }
00931
00932
00933 template<typename T> inline
00934 typename Array<T>::const_reference
00935 Array<T>::at(Ordinal i) const
00936 {
00937 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00938 assertIndex(i);
00939 #endif
00940 return vec().at(i);
00941 }
00942
00943
00944 template<typename T> inline
00945 typename Array<T>::reference
00946 Array<T>::front()
00947 {
00948 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00949 assertNotNull();
00950 #endif
00951 return vec().front();
00952 }
00953
00954
00955 template<typename T> inline
00956 typename Array<T>::const_reference
00957 Array<T>::front() const
00958 {
00959 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00960 assertNotNull();
00961 #endif
00962 return vec().front();
00963 }
00964
00965
00966 template<typename T> inline
00967 typename Array<T>::reference
00968 Array<T>::back()
00969 {
00970 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00971 assertNotNull();
00972 #endif
00973 return vec().back();
00974 }
00975
00976
00977 template<typename T> inline
00978 typename Array<T>::const_reference
00979 Array<T>::back() const
00980 {
00981 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00982 assertNotNull();
00983 #endif
00984 return vec().back();
00985 }
00986
00987
00988 template<typename T> inline
00989 void Array<T>::push_back(const value_type& x)
00990 {
00991 vec(true).push_back(x);
00992 }
00993
00994
00995 template<typename T> inline
00996 void Array<T>::pop_back()
00997 {
00998 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00999 assertNotNull();
01000 #endif
01001 vec(true).pop_back();
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 template<typename T> inline
01014 typename Array<T>::iterator
01015 Array<T>::insert(iterator position, const value_type& x)
01016 {
01017 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01018
01019 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01020 const difference_type i = position - begin();
01021 vec(true,true).insert(raw_poss,x);
01022 return begin() + i;
01023 #else
01024 return vec_.insert(position,x);
01025 #endif
01026 }
01027
01028
01029 template<typename T> inline
01030 void Array<T>::insert(iterator position, Ordinal n, const value_type& x)
01031 {
01032 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01033 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01034 vec(true,true).insert(raw_poss,n,x);
01035 #else
01036 return vec_.insert(position,n,x);
01037 #endif
01038 }
01039
01040
01041 template<typename T> template<typename InputIterator> inline
01042 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
01043 {
01044 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01045 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01046 vec(true,true).insert(raw_poss,first,last);
01047 #else
01048 return vec_.insert(position,first,last);
01049 #endif
01050 }
01051
01052
01053 template<typename T> inline
01054 typename Array<T>::iterator
01055 Array<T>::erase(iterator position)
01056 {
01057 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01058 assertNotNull();
01059
01060 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01061 const difference_type i = position - begin();
01062 vec(true,true).erase(raw_poss);
01063 return begin() + i;
01064 #else
01065 return vec_.erase(position);
01066 #endif
01067 }
01068
01069
01070 template<typename T> inline
01071 typename Array<T>::iterator
01072 Array<T>::erase(iterator first, iterator last)
01073 {
01074 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01075 assertNotNull();
01076
01077 const typename std::vector<T>::iterator raw_first = raw_position(first);
01078 const typename std::vector<T>::iterator raw_last = raw_position(last);
01079 const difference_type i = first - begin();
01080 vec(true,true).erase(raw_first,raw_last);
01081 return begin() + i;
01082 #else
01083 return vec_.erase(first,last);
01084 #endif
01085 }
01086
01087
01088 template<typename T> inline
01089 void Array<T>::swap(Array& x)
01090 {
01091 vec(true).swap(x.vec());
01092 }
01093
01094
01095 template<typename T> inline
01096 void Array<T>::clear()
01097 {
01098 vec(true).clear();
01099 }
01100
01101
01102
01103
01104
01105 template<typename T> inline
01106 Array<T>& Array<T>::append(const T& x)
01107 {
01108 this->push_back(x);
01109 return *this;
01110 }
01111
01112
01113 template<typename T> inline
01114 void Array<T>::remove(int i)
01115 {
01116 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01117 assertIndex(i);
01118 #endif
01119
01120 this->erase( this->begin() + i );
01121 }
01122
01123
01124 template<typename T> inline
01125 int Array<T>::length() const
01126 {
01127 return this->size();
01128 }
01129
01130
01131 template<typename T> inline
01132 std::string Array<T>::toString() const
01133 {
01134 return (*this)().toString();
01135 }
01136
01137
01138 template<typename T> inline
01139 bool Array<T>::hasBoundsChecking()
01140 {
01141 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01142 return true;
01143 #else
01144 return false;
01145 #endif
01146 }
01147
01148
01149 template<typename T> inline
01150 T* Array<T>::getRawPtr()
01151 {
01152 return ( size() ? &(*this)[0] : 0 );
01153 }
01154
01155
01156 template<typename T> inline
01157 const T* Array<T>::getRawPtr() const
01158 {
01159 return ( size() ? &(*this)[0] : 0 );
01160 }
01161
01162
01163
01164
01165
01166 template<typename T> inline
01167 Array<T>::Array( const std::vector<T> &v ) :
01168 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01169 vec_(new std::vector<T>(v))
01170 #else
01171 vec_(v)
01172 #endif
01173 {}
01174
01175
01176 template<typename T> inline
01177 std::vector<T> Array<T>::toVector() const
01178 {
01179 if (!size())
01180 return std::vector<T>();
01181 std::vector<T> v(begin(),end());
01182 return v;
01183 }
01184
01185
01186 template<typename T> inline
01187 Array<T>& Array<T>::operator=( const std::vector<T> &v )
01188 {
01189 vec(true) = v;
01190 return *this;
01191 }
01192
01193
01194
01195
01196
01197 template<typename T> inline
01198 ArrayView<T> Array<T>::view( Ordinal offset, Ordinal size_in )
01199 {
01200 if (size_in) {
01201 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01202 return ArrayView<T>(this->begin().persistingView(offset, size_in));
01203 #else
01204 return arrayView( &vec()[offset], size_in );
01205 #endif
01206 }
01207 return Teuchos::null;
01208 }
01209
01210
01211 template<typename T> inline
01212 ArrayView<const T> Array<T>::view( Ordinal offset, Ordinal size_in ) const
01213 {
01214 if (size_in) {
01215 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01216 return ArrayView<const T>(this->begin().persistingView(offset, size_in));
01217 #else
01218 return arrayView( &vec()[offset], size_in );
01219 #endif
01220 }
01221 return Teuchos::null;
01222
01223
01224
01225 }
01226
01227
01228 template<typename T> inline
01229 ArrayView<T> Array<T>::operator()( Ordinal offset, Ordinal size_in )
01230 {
01231 return view(offset, size_in);
01232 }
01233
01234
01235 template<typename T> inline
01236 ArrayView<const T> Array<T>::operator()( Ordinal offset, Ordinal size_in ) const
01237 {
01238 return view(offset, size_in);
01239 }
01240
01241
01242 template<typename T> inline
01243 ArrayView<T> Array<T>::operator()()
01244 {
01245 if (!size())
01246 return null;
01247 return this->view(0, size());
01248 }
01249
01250
01251 template<typename T> inline
01252 ArrayView<const T> Array<T>::operator()() const
01253 {
01254 if (!size())
01255 return null;
01256 return this->view(0, size());
01257 }
01258
01259
01260 template<typename T> inline
01261 Array<T>::operator ArrayView<T>()
01262 {
01263 return this->operator()();
01264 }
01265
01266
01267 template<typename T> inline
01268 Array<T>::operator ArrayView<const T>() const
01269 {
01270 return this->operator()();
01271 }
01272
01273
01274
01275
01276
01277 template<typename T>
01278 std::vector<T>&
01279 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
01280 {
01281 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01282 if (isStructureBeingModified) {
01283
01284
01285 extern_arcp_ = null;
01286 extern_carcp_ = null;
01287 if (activeIter) {
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 }
01300 else {
01301
01302
01303 TEST_FOR_EXCEPTION( vec_.count() > 1, DanglingReferenceError,
01304 "Error, Array is being modified while a dangling reference exists!");
01305 }
01306 }
01307 return *vec_;
01308 #else
01309
01310 (void)isStructureBeingModified;
01311 (void)activeIter;
01312 return vec_;
01313 #endif
01314 }
01315
01316
01317 template<typename T> inline
01318 const std::vector<T>&
01319 Array<T>::vec() const
01320 {
01321 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01322 return *vec_;
01323 #else
01324 return vec_;
01325 #endif
01326 }
01327
01328
01329 template<typename T> inline
01330 typename std::vector<T>::iterator
01331 Array<T>::raw_position( iterator position )
01332 {
01333 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01334 const iterator first = this->begin();
01335 const iterator last = this->end();
01336 TEST_FOR_EXCEPTION(
01337 !(first <= position && position <= last), DanglingReferenceError,
01338 "Error, this iterator is no longer valid for this Aray!"
01339 );
01340
01341
01342
01343 return vec_->begin() + (position - this->begin());
01344 #else
01345 return position;
01346 #endif
01347 }
01348
01349
01350 template<typename T> inline
01351 void Array<T>::assertIndex(int i) const
01352 {
01353 TEST_FOR_EXCEPTION(
01354 !( 0 <= i && i < length() ), RangeError,
01355 typeName(*this)<<"::assertIndex(i): "
01356 "index " << i << " out of range [0, "<< length() << ")"
01357 );
01358 }
01359
01360
01361 template<typename T> inline
01362 void Array<T>::assertNotNull() const
01363 {
01364 TEST_FOR_EXCEPTION(
01365 !size(), NullReferenceError,
01366 typeName(*this)<<"::assertNotNull(): "
01367 "Error, the array has size zero!"
01368 );
01369 }
01370
01371
01372 }
01373
01374
01375
01376
01377
01378 template<typename T> inline
01379 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
01380 { return (a1.vec() == a2.vec()); }
01381
01382
01383 template<typename T> inline
01384 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
01385 { return (a1.vec() != a2.vec()); }
01386
01387
01388 template<typename T> inline
01389 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
01390 { a1.swap(a2); }
01391
01392
01393 template<typename T> inline
01394 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
01395 { return (a1.vec() < a2.vec()); }
01396
01397
01398 template<typename T> inline
01399 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
01400 { return (a1.vec() <= a2.vec()); }
01401
01402
01403 template<typename T> inline
01404 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
01405 { return (a1.vec() > a2.vec()); }
01406
01407
01408 template<typename T> inline
01409 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
01410 { return (a1.vec() >= a2.vec()); }
01411
01412
01413 template<typename T> inline
01414 std::ostream& Teuchos::operator<<(
01415 std::ostream& os, const Array<T>& array
01416 )
01417 {
01418 return os << Teuchos::toString(array);
01419 }
01420
01421
01422 template<typename T> inline
01423 int Teuchos::hashCode(const Array<T>& array)
01424 {
01425 int rtn = hashCode(array.length());
01426 for (int i=0; i<array.length(); i++)
01427 {
01428 rtn += hashCode(array[i]);
01429 }
01430 return rtn;
01431 }
01432
01433
01434 template<typename T> inline
01435 std::vector<T> Teuchos::createVector( const Array<T> &a )
01436 {
01437 return a.toVector();
01438 }
01439
01440
01441 template<typename T> inline
01442 std::string Teuchos::toString(const Array<T>& array)
01443 {
01444 return array.toString();
01445 }
01446
01447
01448 template<typename T>
01449 Teuchos::Array<T>
01450 Teuchos::fromStringToArray(const std::string& arrayStr)
01451 {
01452 const std::string str = Utils::trimWhiteSpace(arrayStr);
01453 std::istringstream iss(str);
01454 TEST_FOR_EXCEPTION(
01455 ( str[0]!='{' || str[str.length()-1] != '}' )
01456 ,InvalidArrayStringRepresentation
01457 ,"Error, the std::string:\n"
01458 "----------\n"
01459 <<str<<
01460 "\n----------\n"
01461 "is not a valid array represntation!"
01462 );
01463 char c;
01464 c = iss.get();
01465 TEST_FOR_EXCEPT(c!='{');
01466
01467 Array<T> a;
01468 while( !iss.eof() ) {
01469
01470 std::string entryStr;
01471 std::getline(iss,entryStr,',');
01472
01473
01474
01475
01476
01477
01478
01479
01480 entryStr = Utils::trimWhiteSpace(entryStr);
01481
01482
01483 bool found_end = false;
01484 if(entryStr[entryStr.length()-1]=='}') {
01485 entryStr = entryStr.substr(0,entryStr.length()-1);
01486 found_end = true;
01487 if( entryStr.length()==0 && a.size()==0 )
01488 return a;
01489 }
01490 TEST_FOR_EXCEPTION(
01491 0 == entryStr.length()
01492 ,InvalidArrayStringRepresentation
01493 ,"Error, the std::string:\n"
01494 "----------\n"
01495 <<str<<
01496 "\n----------\n"
01497 "is not a valid array represntation!"
01498 );
01499
01500 std::istringstream entryiss(entryStr);
01501 T entry;
01502 Teuchos::extractDataFromISS( entryiss, entry );
01503
01504
01505 a.push_back(entry);
01506
01507
01508
01509
01510 TEST_FOR_EXCEPTION(
01511 found_end && !iss.eof()
01512 ,InvalidArrayStringRepresentation
01513 ,"Error, the std::string:\n"
01514 "----------\n"
01515 <<str<<
01516 "\n----------\n"
01517 "is not a valid array represntation!"
01518 );
01519 }
01520 return a;
01521 }
01522
01523
01524 #endif // TEUCHOS_ARRAY_H