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
00213 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00214
00215 typedef ArrayRCP<T> iterator;
00217 typedef ArrayRCP<const T> const_iterator;
00219 typedef std::reverse_iterator<iterator> reverse_iterator;
00221 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00222 #else
00223
00224 typedef typename std::vector<T>::iterator iterator;
00226 typedef typename std::vector<T>::const_iterator const_iterator;
00228 typedef typename std::vector<T>::reverse_iterator reverse_iterator;
00230 typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
00231 #endif
00232
00234 typedef typename std::vector<T>::size_type size_type;
00236 typedef typename std::vector<T>::difference_type difference_type;
00238 typedef typename std::vector<T>::allocator_type allocator_type;
00239
00241
00244
00245
00247 Array();
00249 explicit Array(size_type n, const value_type& value = value_type());
00251 Array(const Array<T>& x);
00253 template<typename InputIterator>
00254 Array(InputIterator first, InputIterator last);
00256 Array(const ArrayView<const T>& a);
00258 template<int N>
00259 Array(const Tuple<T,N>& t);
00261 ~Array();
00263 Array& operator=(const Array<T>& a);
00264
00266
00269
00271 void assign(size_type n, const value_type& val);
00273 template<typename InputIterator>
00274 void assign(InputIterator first, InputIterator last);
00276 iterator begin();
00278 iterator end();
00280 const_iterator begin() const;
00282 const_iterator end() const;
00284 reverse_iterator rbegin();
00286 reverse_iterator rend();
00288 const_reverse_iterator rbegin() const;
00290 const_reverse_iterator rend() const;
00292 size_type size() const;
00294 size_type max_size() const;
00296 void resize(size_type new_size, const value_type& x = value_type());
00298 size_type capacity() const;
00300 bool empty() const;
00302 void reserve(size_type n);
00304 reference operator[](size_type i);
00306 const_reference operator[](size_type i) const;
00308 reference at(size_type i);
00310 const_reference at(size_type i) const;
00312 reference front();
00314 const_reference front() const;
00316 reference back();
00318 const_reference back() const;
00320 void push_back(const value_type& x);
00322 void pop_back();
00324 iterator insert(iterator position, const value_type& x);
00326 void insert(iterator position, size_type n, const value_type& x);
00328 template<typename InputIterator>
00329 void insert(iterator position, InputIterator first, InputIterator last);
00331 iterator erase(iterator position);
00333 iterator erase(iterator first, iterator last);
00335 void swap(Array& x);
00337 void clear();
00338
00340
00343
00348 Array<T>& append(const T& x);
00349
00353 void remove(int i);
00354
00359 inline int length() const;
00360
00362 inline std::string toString() const;
00363
00365 inline static bool hasBoundsChecking();
00366
00368 inline T* getRawPtr();
00369
00371 inline const T* getRawPtr() const;
00372
00374
00377
00379 Array( const std::vector<T> &v );
00380
00382 std::vector<T> toVector() const;
00383
00385 Array& operator=( const std::vector<T> &v );
00386
00388
00390
00391
00403 ArrayView<T> view( size_type offset, size_type size );
00404
00416 ArrayView<const T> view( size_type offset, size_type size ) const;
00417
00421 ArrayView<T> operator()( size_type offset, size_type size );
00422
00426 ArrayView<const T> operator()( size_type offset, size_type size ) const;
00427
00432 ArrayView<T> operator()();
00433
00438 ArrayView<const T> operator()() const;
00439
00443 operator ArrayView<T>();
00444
00448 operator ArrayView<const T>() const;
00449
00451
00452 private:
00453
00454 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00455 RCP<std::vector<T> > vec_;
00456 mutable ArrayRCP<T> arcp_;
00457 mutable ArrayRCP<const T> carcp_;
00458 #else
00459 std::vector<T> vec_;
00460 #endif
00461
00462 inline std::vector<T>& vec(
00463 bool isStructureBeingModified = false,
00464 bool activeIter = false
00465 );
00466
00467 inline const std::vector<T>& vec() const;
00468
00469 inline typename std::vector<T>::iterator
00470 raw_position( iterator position );
00471
00472 inline void assertIndex(int i) const;
00473
00474 inline void assertNotNull() const;
00475
00476 };
00477
00478
00484 template<class T>
00485 ArrayRCP<T> arcp( const RCP<Array<T> > &v )
00486 {
00487 if ( is_null(v) || !v->size() )
00488 return null;
00489 return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
00490 &(*v)[0], 0, v->size(),
00491 v, false
00492 );
00493 }
00494
00495
00501 template<class T>
00502 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
00503 {
00504 if ( is_null(v) || !v->size() )
00505 return null;
00506 return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
00507 &(*v)[0], 0, v->size(),
00508 v, false
00509 );
00510 }
00511
00512
00525 template<typename T>
00526 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
00527
00528
00533 template<typename T> inline
00534 int hashCode(const Array<T>& array);
00535
00536
00543 template<typename T> inline
00544 std::vector<T> createVector( const Array<T> &a );
00545
00546
00551 template<typename T>
00552 std::string toString(const Array<T>& array);
00553
00554
00606 template<typename T>
00607 Array<T> fromStringToArray(const std::string& arrayStr);
00608
00609
00610 }
00611
00612
00613
00614
00615
00616
00617
00618 namespace Teuchos {
00619
00620
00621
00622
00623
00624 template<typename T> inline
00625 Array<T>::Array()
00626 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00627 : vec_(rcp(new std::vector<T>()))
00628 #endif
00629 {}
00630
00631
00632 template<typename T> inline
00633 Array<T>::Array(size_type n, const value_type& value) :
00634 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00635 vec_(rcp(new std::vector<T>(n,value)))
00636 #else
00637 vec_(n,value)
00638 #endif
00639 {}
00640
00641
00642 template<typename T> inline
00643 Array<T>::Array(const Array<T>& x) :
00644 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00645 vec_(rcp(new std::vector<T>(*x.vec_)))
00646 #else
00647 vec_(x.vec_)
00648 #endif
00649 {}
00650
00651
00652 template<typename T> template<typename InputIterator> inline
00653 Array<T>::Array(InputIterator first, InputIterator last) :
00654 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00655 vec_(rcp(new std::vector<T>(first,last)))
00656 #else
00657 vec_(first,last)
00658 #endif
00659 {}
00660
00661
00662 template<typename T> inline
00663 Array<T>::~Array()
00664 {
00665 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00666 const std::string errorMsg =
00667 "Error, there must be some client with a dangling reference to this array "
00668 "object! This could be a dangling iterator or a dangling view of something "
00669 "else.";
00670 TEST_FOR_EXCEPTION( arcp_.count() > 1, DanglingReferenceError, errorMsg );
00671 arcp_ = null;
00672 TEST_FOR_EXCEPTION( carcp_.count() > 1, DanglingReferenceError, errorMsg );
00673 carcp_ = null;
00674 TEST_FOR_EXCEPTION( vec_.count() > 1, DanglingReferenceError, errorMsg );
00675 #endif
00676 }
00677
00678
00679 template<typename T> inline
00680 Array<T>::Array(const ArrayView<const T>& a)
00681 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00682 : vec_(rcp(new std::vector<T>()))
00683 #endif
00684 {
00685 insert(begin(),a.begin(),a.end());
00686 }
00687
00688
00689 template<typename T>
00690 template<int N>
00691 inline
00692 Array<T>::Array(const Tuple<T,N>& t)
00693 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00694 : vec_(rcp(new std::vector<T>()))
00695 #endif
00696 {
00697 insert(begin(),t.begin(),t.end());
00698 }
00699
00700
00701 template<typename T> inline
00702 Array<T>& Array<T>::operator=(const Array& a)
00703 {
00704 vec(true) = a.vec();
00705 return *this;
00706 }
00707
00708
00709
00710
00711
00712 template<typename T> inline
00713 void Array<T>::assign(size_type n, const value_type& val)
00714 {
00715 vec(true).assign(n,val);
00716 }
00717
00718
00719 template<typename T> template<typename InputIterator> inline
00720 void Array<T>::assign(InputIterator first, InputIterator last)
00721 {
00722 vec(true).assign(first,last);
00723 }
00724
00725
00726 template<typename T> inline
00727 typename Array<T>::iterator
00728 Array<T>::begin()
00729 {
00730 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00731 if (is_null(arcp_))
00732 arcp_ = arcp(vec_);
00733 return arcp_;
00734 #else
00735 return vec().begin();
00736 #endif
00737 }
00738
00739
00740 template<typename T> inline
00741 typename Array<T>::iterator
00742 Array<T>::end()
00743 {
00744 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00745 return begin() + size();
00746 #else
00747 return vec().end();
00748 #endif
00749 }
00750
00751
00752 template<typename T> inline
00753 typename Array<T>::const_iterator
00754 Array<T>::begin() const
00755 {
00756 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00757 if (is_null(carcp_))
00758 carcp_ = arcp(rcp_const_cast<const std::vector<T> >(vec_));
00759 return carcp_;
00760 #else
00761 return vec().begin();
00762 #endif
00763 }
00764
00765
00766 template<typename T> inline
00767 typename Array<T>::const_iterator
00768 Array<T>::end() const
00769 {
00770 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00771 return begin() + size();
00772 #else
00773 return vec().end();
00774 #endif
00775 }
00776
00777
00778 template<typename T> inline
00779 typename Array<T>::reverse_iterator
00780 Array<T>::rbegin()
00781 {
00782 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00783 return reverse_iterator(end());
00784 #else
00785 return vec().rbegin();
00786 #endif
00787 }
00788
00789
00790 template<typename T> inline
00791 typename Array<T>::reverse_iterator
00792 Array<T>::rend()
00793 {
00794 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00795 return reverse_iterator(begin());
00796 #else
00797 return vec().rend();
00798 #endif
00799 }
00800
00801
00802 template<typename T> inline
00803 typename Array<T>::const_reverse_iterator
00804 Array<T>::rbegin() const
00805 {
00806 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00807 return const_reverse_iterator(end());
00808 #else
00809 return vec().rbegin();
00810 #endif
00811 }
00812
00813
00814 template<typename T> inline
00815 typename Array<T>::const_reverse_iterator
00816 Array<T>::rend() const
00817 {
00818 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00819 return const_reverse_iterator(begin());
00820 #else
00821 return vec().rend();
00822 #endif
00823 }
00824
00825
00826 template<typename T> inline
00827 typename Array<T>::size_type
00828 Array<T>::size() const
00829 {
00830 return vec().size();
00831 }
00832
00833
00834 template<typename T> inline
00835 typename Array<T>::size_type
00836 Array<T>::max_size() const
00837 {
00838 return vec().max_size();
00839 }
00840
00841
00842 template<typename T> inline
00843 void
00844 Array<T>::resize(size_type new_size, const value_type& x)
00845 {
00846 vec(true).resize(new_size,x);
00847 }
00848
00849
00850 template<typename T> inline
00851 typename Array<T>::size_type
00852 Array<T>::capacity() const
00853 {
00854 return vec().capacity();
00855 }
00856
00857
00858 template<typename T> inline
00859 bool Array<T>::empty() const
00860 {
00861 return vec().empty();
00862 }
00863
00864
00865 template<typename T> inline
00866 void Array<T>::reserve(size_type n)
00867 {
00868 vec(true).reserve(n);
00869 }
00870
00871
00872 template<typename T> inline
00873 typename Array<T>::reference
00874 Array<T>::operator[](size_type i)
00875 {
00876 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00877 assertIndex(i);
00878 #endif
00879 return vec()[i];
00880 }
00881
00882
00883 template<typename T> inline
00884 typename Array<T>::const_reference
00885 Array<T>::operator[](size_type i) const
00886 {
00887 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00888 assertIndex(i);
00889 #endif
00890 return vec()[i];
00891 }
00892
00893
00894 template<typename T> inline
00895 typename Array<T>::reference
00896 Array<T>::at(size_type i)
00897 {
00898 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00899 assertIndex(i);
00900 #endif
00901 return vec().at(i);
00902 }
00903
00904
00905 template<typename T> inline
00906 typename Array<T>::const_reference
00907 Array<T>::at(size_type i) const
00908 {
00909 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00910 assertIndex(i);
00911 #endif
00912 return vec().at(i);
00913 }
00914
00915
00916 template<typename T> inline
00917 typename Array<T>::reference
00918 Array<T>::front()
00919 {
00920 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00921 assertNotNull();
00922 #endif
00923 return vec().front();
00924 }
00925
00926
00927 template<typename T> inline
00928 typename Array<T>::const_reference
00929 Array<T>::front() const
00930 {
00931 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00932 assertNotNull();
00933 #endif
00934 return vec().front();
00935 }
00936
00937
00938 template<typename T> inline
00939 typename Array<T>::reference
00940 Array<T>::back()
00941 {
00942 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00943 assertNotNull();
00944 #endif
00945 return vec().back();
00946 }
00947
00948
00949 template<typename T> inline
00950 typename Array<T>::const_reference
00951 Array<T>::back() const
00952 {
00953 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00954 assertNotNull();
00955 #endif
00956 return vec().back();
00957 }
00958
00959
00960 template<typename T> inline
00961 void Array<T>::push_back(const value_type& x)
00962 {
00963 vec(true).push_back(x);
00964 }
00965
00966
00967 template<typename T> inline
00968 void Array<T>::pop_back()
00969 {
00970 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00971 assertNotNull();
00972 #endif
00973 vec(true).pop_back();
00974 }
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 template<typename T> inline
00986 typename Array<T>::iterator
00987 Array<T>::insert(iterator position, const value_type& x)
00988 {
00989 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00990
00991 const typename std::vector<T>::iterator raw_poss = raw_position(position);
00992 const difference_type i = position - begin();
00993 vec(true,true).insert(raw_poss,x);
00994 return begin() + i;
00995 #else
00996 return vec_.insert(position,x);
00997 #endif
00998 }
00999
01000
01001 template<typename T> inline
01002 void Array<T>::insert(iterator position, size_type n, const value_type& x)
01003 {
01004 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01005 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01006 vec(true,true).insert(raw_poss,n,x);
01007 #else
01008 return vec_.insert(position,n,x);
01009 #endif
01010 }
01011
01012
01013 template<typename T> template<typename InputIterator> inline
01014 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
01015 {
01016 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01017 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01018 vec(true,true).insert(raw_poss,first,last);
01019 #else
01020 return vec_.insert(position,first,last);
01021 #endif
01022 }
01023
01024
01025 template<typename T> inline
01026 typename Array<T>::iterator
01027 Array<T>::erase(iterator position)
01028 {
01029 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01030 assertNotNull();
01031
01032 const typename std::vector<T>::iterator raw_poss = raw_position(position);
01033 const difference_type i = position - begin();
01034 vec(true,true).erase(raw_poss);
01035 return begin() + i;
01036 #else
01037 return vec_.erase(position);
01038 #endif
01039 }
01040
01041
01042 template<typename T> inline
01043 typename Array<T>::iterator
01044 Array<T>::erase(iterator first, iterator last)
01045 {
01046 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01047 assertNotNull();
01048
01049 const typename std::vector<T>::iterator raw_first = raw_position(first);
01050 const typename std::vector<T>::iterator raw_last = raw_position(last);
01051 const difference_type i = first - begin();
01052 vec(true,true).erase(raw_first,raw_last);
01053 return begin() + i;
01054 #else
01055 return vec_.erase(first,last);
01056 #endif
01057 }
01058
01059
01060 template<typename T> inline
01061 void Array<T>::swap(Array& x)
01062 {
01063 vec(true).swap(x.vec());
01064 }
01065
01066
01067 template<typename T> inline
01068 void Array<T>::clear()
01069 {
01070 vec(true).clear();
01071 }
01072
01073
01074
01075
01076
01077 template<typename T> inline
01078 Array<T>& Array<T>::append(const T& x)
01079 {
01080 this->push_back(x);
01081 return *this;
01082 }
01083
01084
01085 template<typename T> inline
01086 void Array<T>::remove(int i)
01087 {
01088 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01089 assertIndex(i);
01090 #endif
01091
01092 this->erase( this->begin() + i );
01093 }
01094
01095
01096 template<typename T> inline
01097 int Array<T>::length() const
01098 {
01099 return this->size();
01100 }
01101
01102
01103 template<typename T> inline
01104 std::string Array<T>::toString() const
01105 {
01106 return (*this)().toString();
01107 }
01108
01109
01110 template<typename T> inline
01111 bool Array<T>::hasBoundsChecking()
01112 {
01113 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01114 return true;
01115 #else
01116 return false;
01117 #endif
01118 }
01119
01120
01121 template<typename T> inline
01122 T* Array<T>::getRawPtr()
01123 {
01124 return ( size() ? &(*this)[0] : 0 );
01125 }
01126
01127
01128 template<typename T> inline
01129 const T* Array<T>::getRawPtr() const
01130 {
01131 return ( size() ? &(*this)[0] : 0 );
01132 }
01133
01134
01135
01136
01137
01138 template<typename T> inline
01139 Array<T>::Array( const std::vector<T> &v ) :
01140 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01141 vec_(new std::vector<T>(v))
01142 #else
01143 vec_(v)
01144 #endif
01145 {}
01146
01147
01148 template<typename T> inline
01149 std::vector<T> Array<T>::toVector() const
01150 {
01151 if (!size())
01152 return std::vector<T>();
01153 std::vector<T> v(begin(),end());
01154 return v;
01155 }
01156
01157
01158 template<typename T> inline
01159 Array<T>& Array<T>::operator=( const std::vector<T> &v )
01160 {
01161 vec(true) = v;
01162 return *this;
01163 }
01164
01165
01166
01167
01168
01169 template<typename T> inline
01170 ArrayView<T> Array<T>::view( size_type offset, size_type size_in )
01171 {
01172 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01173 assertIndex(offset);
01174
01175
01176 if (size_in)
01177 assertIndex(offset+size_in-1);
01178 #endif
01179 if (size_in)
01180 return arrayView( &vec()[offset], size_in );
01181 return Teuchos::null;
01182
01183 }
01184
01185
01186 template<typename T> inline
01187 ArrayView<const T> Array<T>::view( size_type offset, size_type size_in ) const
01188 {
01189 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01190 assertIndex(offset);
01191 assertIndex(offset+size_in-1);
01192 #endif
01193 return arrayView( &vec()[offset], size_in );
01194
01195 }
01196
01197
01198 template<typename T> inline
01199 ArrayView<T> Array<T>::operator()( size_type offset, size_type size_in )
01200 {
01201 return view(offset,size_in);
01202 }
01203
01204
01205 template<typename T> inline
01206 ArrayView<const T> Array<T>::operator()( size_type offset, size_type size_in ) const
01207 {
01208 return view(offset,size_in);
01209 }
01210
01211
01212 template<typename T> inline
01213 ArrayView<T> Array<T>::operator()()
01214 {
01215 if (!size())
01216 return null;
01217 return arrayView( &vec()[0], size() );
01218
01219 }
01220
01221
01222 template<typename T> inline
01223 ArrayView<const T> Array<T>::operator()() const
01224 {
01225 if (!size())
01226 return null;
01227 return arrayView( &vec()[0], size() );
01228 }
01229
01230
01231 template<typename T> inline
01232 Array<T>::operator ArrayView<T>()
01233 {
01234 return this->operator()();
01235 }
01236
01237
01238 template<typename T> inline
01239 Array<T>::operator ArrayView<const T>() const
01240 {
01241 return this->operator()();
01242 }
01243
01244
01245
01246
01247
01248 template<typename T>
01249 std::vector<T>&
01250 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
01251 {
01252 (void)isStructureBeingModified;
01253 (void)activeIter;
01254 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01255 if (isStructureBeingModified) {
01256
01257
01258 arcp_ = null;
01259 carcp_ = null;
01260 if (activeIter) {
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273 }
01274 else {
01275
01276
01277 TEST_FOR_EXCEPTION( vec_.count() > 1, DanglingReferenceError,
01278 "Error, Array is being modified while a dangling reference exists!");
01279 }
01280 }
01281 return *vec_;
01282 #else
01283 return vec_;
01284 #endif
01285 }
01286
01287
01288 template<typename T> inline
01289 const std::vector<T>&
01290 Array<T>::vec() const
01291 {
01292 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01293 return *vec_;
01294 #else
01295 return vec_;
01296 #endif
01297 }
01298
01299
01300 template<typename T> inline
01301 typename std::vector<T>::iterator
01302 Array<T>::raw_position( iterator position )
01303 {
01304 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
01305 const iterator first = this->begin();
01306 const iterator last = this->end();
01307 TEST_FOR_EXCEPTION(
01308 !(first <= position && position <= last), DanglingReferenceError,
01309 "Error, this iterator is no longer valid for this Aray!"
01310 );
01311
01312
01313
01314 return vec_->begin() + (position - this->begin());
01315 #else
01316 return position;
01317 #endif
01318 }
01319
01320
01321 template<typename T> inline
01322 void Array<T>::assertIndex(int i) const
01323 {
01324 TEST_FOR_EXCEPTION(
01325 !( 0 <= i && i < length() ), RangeError,
01326 typeName(*this)<<"::assertIndex(i): "
01327 "index " << i << " out of range [0, "<< length() << ")"
01328 );
01329 }
01330
01331
01332 template<typename T> inline
01333 void Array<T>::assertNotNull() const
01334 {
01335 TEST_FOR_EXCEPTION(
01336 !size(), NullReferenceError,
01337 typeName(*this)<<"::assertNotNull(): "
01338 "Error, the array has size zero!"
01339 );
01340 }
01341
01342
01343 }
01344
01345
01346
01347
01348
01349 template<typename T> inline
01350 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
01351 { return (a1.vec() == a2.vec()); }
01352
01353
01354 template<typename T> inline
01355 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
01356 { return (a1.vec() != a2.vec()); }
01357
01358
01359 template<typename T> inline
01360 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
01361 { a1.swap(a2); }
01362
01363
01364 template<typename T> inline
01365 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
01366 { return (a1.vec() < a2.vec()); }
01367
01368
01369 template<typename T> inline
01370 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
01371 { return (a1.vec() <= a2.vec()); }
01372
01373
01374 template<typename T> inline
01375 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
01376 { return (a1.vec() > a2.vec()); }
01377
01378
01379 template<typename T> inline
01380 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
01381 { return (a1.vec() >= a2.vec()); }
01382
01383
01384 template<typename T> inline
01385 std::ostream& Teuchos::operator<<(
01386 std::ostream& os, const Array<T>& array
01387 )
01388 {
01389 return os << Teuchos::toString(array);
01390 }
01391
01392
01393 template<typename T> inline
01394 int Teuchos::hashCode(const Array<T>& array)
01395 {
01396 int rtn = hashCode(array.length());
01397 for (int i=0; i<array.length(); i++)
01398 {
01399 rtn += hashCode(array[i]);
01400 }
01401 return rtn;
01402 }
01403
01404
01405 template<typename T> inline
01406 std::vector<T> Teuchos::createVector( const Array<T> &a )
01407 {
01408 return a.toVector();
01409 }
01410
01411
01412 template<typename T> inline
01413 std::string Teuchos::toString(const Array<T>& array)
01414 {
01415 return array.toString();
01416 }
01417
01418
01419 template<typename T>
01420 Teuchos::Array<T>
01421 Teuchos::fromStringToArray(const std::string& arrayStr)
01422 {
01423 const std::string str = Utils::trimWhiteSpace(arrayStr);
01424 std::istringstream iss(str);
01425 TEST_FOR_EXCEPTION(
01426 ( str[0]!='{' || str[str.length()-1] != '}' )
01427 ,InvalidArrayStringRepresentation
01428 ,"Error, the std::string:\n"
01429 "----------\n"
01430 <<str<<
01431 "\n----------\n"
01432 "is not a valid array represntation!"
01433 );
01434 char c;
01435 c = iss.get();
01436 TEST_FOR_EXCEPT(c!='{');
01437
01438 Array<T> a;
01439 while( !iss.eof() ) {
01440
01441 std::string entryStr;
01442 std::getline(iss,entryStr,',');
01443
01444
01445
01446
01447
01448
01449
01450
01451 entryStr = Utils::trimWhiteSpace(entryStr);
01452
01453
01454 bool found_end = false;
01455 if(entryStr[entryStr.length()-1]=='}') {
01456 entryStr = entryStr.substr(0,entryStr.length()-1);
01457 found_end = true;
01458 if( entryStr.length()==0 && a.size()==0 )
01459 return a;
01460 }
01461 TEST_FOR_EXCEPTION(
01462 0 == entryStr.length()
01463 ,InvalidArrayStringRepresentation
01464 ,"Error, the std::string:\n"
01465 "----------\n"
01466 <<str<<
01467 "\n----------\n"
01468 "is not a valid array represntation!"
01469 );
01470
01471 std::istringstream entryiss(entryStr);
01472 T entry;
01473 entryiss >> entry;
01474
01475
01476 a.push_back(entry);
01477
01478
01479
01480
01481 TEST_FOR_EXCEPTION(
01482 found_end && !iss.eof()
01483 ,InvalidArrayStringRepresentation
01484 ,"Error, the std::string:\n"
01485 "----------\n"
01486 <<str<<
01487 "\n----------\n"
01488 "is not a valid array represntation!"
01489 );
01490 }
01491 return a;
01492 }
01493
01494
01495 #endif // TEUCHOS_ARRAY_H