Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_Array.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_ARRAY_H
43 #define TEUCHOS_ARRAY_H
44 
49 #include "Teuchos_ConfigDefs.hpp"
50 #include "Teuchos_Assert.hpp"
52 #include "Teuchos_ArrayRCP.hpp"
53 #include "Teuchos_Tuple.hpp"
54 #include "Teuchos_Utils.hpp"
55 #include "Teuchos_Assert.hpp"
56 
57 
58 namespace Teuchos {
59 
60 
65 class InvalidArrayStringRepresentation : public std::logic_error
66 {public:InvalidArrayStringRepresentation(const std::string& what_arg) : std::logic_error(what_arg) {}};
67 
68 
69 template<typename T> class Array;
70 
71 
72 // 2007/11/30: rabartl: Below, I had to move the initial declaration of these
73 // non-member template functions outside of the Array class since the Sun
74 // compiler on sass9000 would not accept this. However, this did work on a
75 // number of other compilers such a g++, Intel C++ etc. The old in-class
76 // non-member friend definition is clearly ISO 98 C++ as shown in Item 46 of
77 // "Effective C++: Third Edition". This is not the end of the world but this
78 // is something to remember for this platform.
79 
80 
85 template<typename T> inline
86 bool operator==( const Array<T> &a1, const Array<T> &a2 );
87 
88 
93 template<typename T> inline
94 bool operator!=( const Array<T> &a1, const Array<T> &a2 );
95 
96 
101 template<typename T> inline
102 void swap( Array<T> &a1, Array<T> &a2 );
103 
104 
109 template<typename T> inline
110 bool operator<( const Array<T> &a1, const Array<T> &a2 );
111 
112 
117 template<typename T> inline
118 bool operator<=( const Array<T> &a1, const Array<T> &a2 );
119 
120 
125 template<typename T> inline
126 bool operator>( const Array<T> &a1, const Array<T> &a2 );
127 
128 
133 template<typename T> inline
134 bool operator>=( const Array<T> &a1, const Array<T> &a2 );
135 
136 
190 template<typename T>
191 class Array
192 {
193 public:
194 
195  // 2007/11/30: rabartl: Below, note that the only reason that these
196  // functions are declared as friends is so that the compiler will do
197  // automatic type conversions as described in "Effective C++: Third Edition"
198  // Item 46.
199 
201  template<typename T2>
202  friend bool Teuchos::operator==( const Array<T2> &a1, const Array<T2> &a2 );
203 
205  template<typename T2>
206  friend bool Teuchos::operator!=( const Array<T2> &a1, const Array<T2> &a2 );
207 
209  template<typename T2>
210  friend void swap( Array<T2> &a1, Array<T2> &a2 );
211 
213  template<typename T2>
214  friend bool Teuchos::operator<( const Array<T2> &a1, const Array<T2> &a2 );
215 
217  template<typename T2>
218  friend bool Teuchos::operator<=( const Array<T2> &a1, const Array<T2> &a2 );
219 
221  template<typename T2>
222  friend bool Teuchos::operator>( const Array<T2> &a1, const Array<T2> &a2 );
223 
225  template<typename T2>
226  friend bool Teuchos::operator>=( const Array<T2> &a1, const Array<T2> &a2 );
227 
230 
232  typedef Teuchos_Ordinal Ordinal;
238  typedef typename std::vector<T>::value_type value_type;
240  typedef typename std::vector<T>::pointer pointer;
242  typedef typename std::vector<T>::const_pointer const_pointer;
244  typedef typename std::vector<T>::reference reference;
246  typedef typename std::vector<T>::const_reference const_reference;
248  typedef typename std::vector<T>::allocator_type allocator_type;
249 
250 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
251  typedef ArrayRCP<T> iterator;
256  typedef std::reverse_iterator<iterator> reverse_iterator;
258  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
259 #else
260  typedef typename std::vector<T>::iterator iterator;
263  typedef typename std::vector<T>::const_iterator const_iterator;
265  typedef typename std::vector<T>::reverse_iterator reverse_iterator;
267  typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
268 #endif
269 
271 
273 
275  inline Array();
276 
278  inline explicit Array(size_type n, const value_type& value = value_type());
279 
281  inline Array(const Array<T>& x);
282 
284  template<typename InputIterator>
285  inline Array(InputIterator first, InputIterator last);
286 
288  inline Array(const ArrayView<const T>& a);
289 
291  template<int N>
292  inline Array(const Tuple<T,N>& t);
293 
295  inline ~Array();
296 
298  inline Array& operator=(const Array<T>& a);
299 
301 
307 
309  inline void assign(size_type n, const value_type& val);
311  template<typename InputIterator>
312  inline void assign(InputIterator first, InputIterator last);
314  inline iterator begin();
316  inline iterator end();
318  inline const_iterator begin() const;
320  inline const_iterator end() const;
322  inline reverse_iterator rbegin();
324  inline reverse_iterator rend();
326  inline const_reverse_iterator rbegin() const;
328  inline const_reverse_iterator rend() const;
330  inline size_type size() const;
332  inline size_type max_size() const;
334  inline void resize(size_type new_size, const value_type& x = value_type());
336  inline size_type capacity() const;
338  inline bool empty() const;
340  inline void reserve(size_type n);
342  inline reference operator[](size_type i);
344  inline const_reference operator[](size_type i) const;
346  inline reference at(size_type i);
348  inline const_reference at(size_type i) const;
350  inline reference front();
352  inline const_reference front() const;
354  inline reference back();
356  inline const_reference back() const;
358  inline void push_back(const value_type& x);
360  inline void pop_back();
362  inline iterator insert(iterator position, const value_type& x);
364  inline void insert(iterator position, size_type n, const value_type& x);
366  template<typename InputIterator>
367  inline void insert(iterator position, InputIterator first, InputIterator last);
369  inline iterator erase(iterator position);
371  inline iterator erase(iterator first, iterator last);
373  inline void swap(Array& x);
375  inline void clear();
376 
378 
380 
385  inline Array<T>& append(const T& x);
386 
390  inline void remove(int i);
391 
396  inline int length() const;
397 
399  inline std::string toString() const;
400 
402  inline static bool hasBoundsChecking();
403 
405  inline T* getRawPtr();
406 
408  inline const T* getRawPtr() const;
409 
411 
413 
415  inline Array( const std::vector<T> &v );
416 
418  inline std::vector<T> toVector() const;
419 
421  inline Array& operator=( const std::vector<T> &v );
422 
424 
426 
427 
441  inline ArrayView<T> view( size_type offset, size_type size );
442 
456  inline ArrayView<const T> view( size_type offset, size_type size ) const;
457 
461  inline ArrayView<T> operator()( size_type offset, size_type size );
462 
466  inline ArrayView<const T> operator()( size_type offset, size_type size ) const;
467 
472  inline ArrayView<T> operator()();
473 
478  inline ArrayView<const T> operator()() const;
479 
483  inline operator ArrayView<T>();
484 
488  inline operator ArrayView<const T>() const;
489 
491 
492 private:
493 
494 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
495  RCP<std::vector<T> > vec_;
496  mutable ArrayRCP<T> extern_arcp_;
497  mutable ArrayRCP<const T> extern_carcp_;
498 #else
499  std::vector<T> vec_;
500 #endif
501 
502  inline std::vector<T>& vec(
503  bool isStructureBeingModified = false,
504  bool activeIter = false
505  );
506 
507  inline const std::vector<T>& vec() const;
508 
509  inline typename std::vector<T>::iterator
510  raw_position( iterator position );
511 
512  inline void assertIndex(size_type i) const;
513 
514  inline void assertNotNull() const;
515 
516 };
517 
518 
524 template<class T>
526 {
527  if ( is_null(v) || !v->size() )
528  return null;
529  return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
530  &(*v)[0], 0, v->size(),
531  v, false
532  );
533 }
534 
535 
541 template<class T>
542 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
543 {
544  if ( is_null(v) || !v->size() )
545  return null;
546  return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
547  &(*v)[0], 0, v->size(),
548  v, false
549  );
550 }
551 
552 
558 template<class T>
560 {
561  if (a.size() == 0)
562  return null;
563 #ifdef TEUCHOS_DEBUG
564  return a.begin(); // Catch dangling reference!
565 #else
566  return arcp(a.getRawPtr(), 0, a.size(), false);
567 #endif
568 }
569 
570 
576 template<class T>
578 {
579  if (a.size() == 0)
580  return null;
581 #ifdef TEUCHOS_DEBUG
582  return a.begin(); // Catch dangling reference!
583 #else
584  return arcp(a.getRawPtr(), 0, a.size(), false);
585 #endif
586 }
587 
588 
601 template<typename T>
602 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
603 
604 
609 template<typename T> inline
610 int hashCode(const Array<T>& array);
611 
612 
619 template<typename T> inline
620 std::vector<T> createVector( const Array<T> &a );
621 
622 
627 template<typename T>
628 std::string toString(const Array<T>& array);
629 
630 
682 template<typename T>
683 Array<T> fromStringToArray(const std::string& arrayStr);
684 
690 template<typename T>
691 std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
692  array = fromStringToArray<T>(in.str());
693  return in;
694 }
695 
701 template<typename T> inline
702 void extractDataFromISS( std::istringstream& iss, T& data )
703 {
704  iss >> data; // Assumes type has operator>>(...) defined!
705 }
706 
713 inline
714 void extractDataFromISS( std::istringstream& iss, std::string& data )
715 {
716  // grab unformatted string.
717  data = iss.str();
718  // remove white space from beginning and end of string.
719  data = Utils::trimWhiteSpace(data);
720 }
721 
731 inline
733  return "Array(*)";
734 }
735 
736 
737 
753 template<typename T>
754 class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<Array<T> > {
755 public:
756  static std::string name(){
757  std::string formatString = getArrayTypeNameTraitsFormat();
758  size_t starPos = formatString.find("*");
759  std::string prefix = formatString.substr(0,starPos);
760  std::string postFix = formatString.substr(starPos+1);
761  return prefix+TypeNameTraits<T>::name()+postFix;
762  }
763  static std::string concreteName(const Array<T>&)
764  { return name(); }
765 };
766 
767 
768 } // namespace Teuchos
769 
770 
771 //
772 // Implementation
773 //
774 
775 
776 namespace Teuchos {
777 
778 
779 // All constructors
780 
781 
782 template<typename T> inline
784 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
785  : vec_(rcp(new std::vector<T>()))
786 #endif
787 {}
788 
789 
790 template<typename T> inline
792 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
793  vec_(rcp(new std::vector<T>(n,value)))
794 #else
795  vec_(n, value)
796 #endif
797 {}
798 
799 
800 template<typename T> inline
802 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
803  vec_(rcp(new std::vector<T>(*x.vec_)))
804 #else
805  vec_(x.vec_)
806 #endif
807 {}
808 
809 
810 template<typename T> template<typename InputIterator> inline
811 Array<T>::Array(InputIterator first, InputIterator last) :
812 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
813  vec_(rcp(new std::vector<T>(first, last)))
814 #else
815  vec_(first, last)
816 #endif
817 {}
818 
819 
820 template<typename T> inline
822 {}
823 
824 
825 template<typename T> inline
827 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
828  : vec_(rcp(new std::vector<T>()))
829 #endif
830 {
831  insert(begin(), a.begin(), a.end());
832 }
833 
834 
835 template<typename T>
836 template<int N>
837 inline
839 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
840  : vec_(rcp(new std::vector<T>()))
841 #endif
842 {
843  insert(begin(), t.begin(), t.end());
844 }
845 
846 
847 template<typename T> inline
849 {
850  vec(true) = a.vec();
851  return *this;
852 }
853 
854 
855 // Other std::vector functions
856 
857 
858 template<typename T> inline
860 {
861  vec(true).assign(n,val);
862 }
863 
864 
865 template<typename T> template<typename InputIterator> inline
866 void Array<T>::assign(InputIterator first, InputIterator last)
867 {
868  vec(true).assign(first,last);
869 }
870 
871 
872 template<typename T> inline
873 typename Array<T>::iterator
875 {
876 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
877  if (is_null(extern_arcp_)) {
878  // Here we must use the same RCP to avoid creating two unrelated RCPNodes!
879  extern_arcp_ = arcp(vec_); // Will be null if vec_ is sized!
880  }
881  // Returning a weak pointer will help to catch dangling references but still
882  // keep the same behavior as optimized code.
883  return extern_arcp_.create_weak();
884 #else
885  return vec().begin();
886 #endif
887 }
888 
889 
890 template<typename T> inline
891 typename Array<T>::iterator
893 {
894 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
895  return begin() + size();
896 #else
897  return vec().end();
898 #endif
899 }
900 
901 
902 template<typename T> inline
905 {
906 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
907  if (is_null(extern_carcp_)) {
908  extern_carcp_ = const_cast<Array<T>*>(this)->begin();
909  }
910  // Returning a weak pointer will help to catch dangling references but still
911  // keep the same behavior as optimized code.
912  return extern_carcp_.create_weak();
913 #else
914  return vec().begin();
915 #endif
916 }
917 
918 
919 template<typename T> inline
922 {
923 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
924  return begin() + size();
925 #else
926  return vec().end();
927 #endif
928 }
929 
930 
931 template<typename T> inline
934 {
935 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
936  return reverse_iterator(end());
937 #else
938  return vec().rbegin();
939 #endif
940 }
941 
942 
943 template<typename T> inline
946 {
947 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
948  return reverse_iterator(begin());
949 #else
950  return vec().rend();
951 #endif
952 }
953 
954 
955 template<typename T> inline
958 {
959 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
960  return const_reverse_iterator(end());
961 #else
962  return vec().rbegin();
963 #endif
964 }
965 
966 
967 template<typename T> inline
970 {
971 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
972  return const_reverse_iterator(begin());
973 #else
974  return vec().rend();
975 #endif
976 }
977 
978 
979 template<typename T> inline
980 typename Array<T>::size_type
982 {
983  return vec().size();
984 }
985 
986 
987 template<typename T> inline
988 typename Array<T>::size_type
990 {
991  return std::numeric_limits<size_type>::max();
992 }
993 
994 
995 template<typename T> inline
996 void
998 {
999  vec(true).resize(new_size,x);
1000 }
1001 
1002 
1003 template<typename T> inline
1004 typename Array<T>::size_type
1006 {
1007  return vec().capacity();
1008 }
1009 
1010 
1011 template<typename T> inline
1012 bool Array<T>::empty() const
1013 {
1014  return vec().empty();
1015 }
1016 
1017 
1018 template<typename T> inline
1020 {
1021  vec(true).reserve(n);
1022 }
1023 
1024 
1025 template<typename T> inline
1026 typename Array<T>::reference
1028 {
1029 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1030  assertIndex(i);
1031 #endif
1032  return vec()[i];
1033 }
1034 
1035 
1036 template<typename T> inline
1039 {
1040 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1041  assertIndex(i);
1042 #endif
1043  return vec()[i];
1044 }
1045 
1046 
1047 template<typename T> inline
1048 typename Array<T>::reference
1050 {
1051 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1052  assertIndex(i);
1053 #endif
1054  return vec().at(i);
1055 }
1056 
1057 
1058 template<typename T> inline
1061 {
1062 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1063  assertIndex(i);
1064 #endif
1065  return vec().at(i);
1066 }
1067 
1068 
1069 template<typename T> inline
1070 typename Array<T>::reference
1072 {
1073 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1074  assertNotNull();
1075 #endif
1076  return vec().front();
1077 }
1078 
1079 
1080 template<typename T> inline
1083 {
1084 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1085  assertNotNull();
1086 #endif
1087  return vec().front();
1088 }
1089 
1090 
1091 template<typename T> inline
1092 typename Array<T>::reference
1094 {
1095 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1096  assertNotNull();
1097 #endif
1098  return vec().back();
1099 }
1100 
1101 
1102 template<typename T> inline
1105 {
1106 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1107  assertNotNull();
1108 #endif
1109  return vec().back();
1110 }
1111 
1112 
1113 template<typename T> inline
1115 {
1116  vec(true).push_back(x);
1117 }
1118 
1119 
1120 template<typename T> inline
1122 {
1123 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1124  assertNotNull();
1125 #endif
1126  vec(true).pop_back();
1127 }
1128 
1129 
1130 // 2009/11/13:: rabartl: After moving to a full RCPNode tracing and lookup
1131 // model, I had to how modifying functions like insert(...) and erase(...)
1132 // work which have active iterators controled by the client and yet need to
1133 // allow the structure of the container change. The way these troublesome
1134 // functions work is that first the raw std::vector iterator is extracted.
1135 // The function vec(true, true) then deletes the strong iterators but there is
1136 // still a weak ArrayRCP object that is owned by the client which is being
1137 // passed into this function. The issue is that the design of ArrayRCP is
1138 // such that the RCPNode object is not removed but instead remains in order to
1139 // perform runtime checking.
1140 
1141 
1142 template<typename T> inline
1143 typename Array<T>::iterator
1145 {
1146 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1147  // Assert a valid iterator and get vector iterator
1148  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1149  const difference_type i = position - begin();
1150  vec(true, true).insert(raw_poss, x);
1151  return begin() + i;
1152 #else
1153  return vec_.insert(position, x);
1154 #endif
1155 }
1156 
1157 
1158 template<typename T> inline
1159 void Array<T>::insert(iterator position, size_type n, const value_type& x)
1160 {
1161 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1162  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1163  vec(true, true).insert(raw_poss, n, x);
1164 #else
1165  vec_.insert(position, n, x);
1166 #endif
1167 }
1168 
1169 
1170 template<typename T> template<typename InputIterator> inline
1171 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
1172 {
1173 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1174  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1175  vec(true, true).insert(raw_poss, first, last);
1176 #else
1177  vec_.insert(position, first, last);
1178 #endif
1179 }
1180 
1181 
1182 template<typename T> inline
1183 typename Array<T>::iterator
1185 {
1186 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1187  assertNotNull();
1188  // Assert a valid iterator and get vector iterator
1189  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1190  const difference_type i = position - begin();
1191  vec(true, true).erase(raw_poss);
1192  return begin() + i;
1193 #else
1194  return vec_.erase(position);
1195 #endif
1196 }
1197 
1198 
1199 template<typename T> inline
1200 typename Array<T>::iterator
1202 {
1203 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1204  if (empty()) {
1205  TEUCHOS_ASSERT(first == begin());
1206  TEUCHOS_ASSERT(last == end());
1207  return end();
1208  }
1209  assertNotNull();
1210  // Assert a valid iterator and get vector iterator
1211  const typename std::vector<T>::iterator raw_first = raw_position(first);
1212  const typename std::vector<T>::iterator raw_last = raw_position(last);
1213  const difference_type i = first - begin();
1214  vec(true,true).erase(raw_first,raw_last);
1215  return begin() + i;
1216 #else
1217  return vec_.erase(first,last);
1218 #endif
1219 }
1220 
1221 
1222 template<typename T> inline
1224 {
1225  vec(true).swap(x.vec());
1226 }
1227 
1228 
1229 template<typename T> inline
1231 {
1232  vec(true).clear();
1233 }
1234 
1235 
1236 // Non-standard functions
1237 
1238 
1239 template<typename T> inline
1241 {
1242  this->push_back(x);
1243  return *this;
1244 }
1245 
1246 
1247 template<typename T> inline
1248 void Array<T>::remove(int i)
1249 {
1250 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1251  assertIndex(i);
1252 #endif
1253  // Erase the i-th element of this array.
1254  this->erase( this->begin() + i );
1255 }
1256 
1257 
1258 template<typename T> inline
1259 int Array<T>::length() const
1260 {
1261  return static_cast<int> (this->size ());
1262 }
1263 
1264 
1265 template<typename T> inline
1266 std::string Array<T>::toString() const
1267 {
1268  return (*this)().toString(); // Use ArrayView<T>::toString()
1269 }
1270 
1271 
1272 template<typename T> inline
1274 {
1275 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1276  return true;
1277 #else
1278  return false;
1279 #endif
1280 }
1281 
1282 
1283 template<typename T> inline
1285 {
1286  return ( size() ? &(*this)[0] : 0 );
1287 }
1288 
1289 
1290 template<typename T> inline
1291 const T* Array<T>::getRawPtr() const
1292 {
1293  return ( size() ? &(*this)[0] : 0 );
1294 }
1295 
1296 
1297 // Conversions to and from std::vector
1298 
1299 
1300 template<typename T> inline
1301 Array<T>::Array( const std::vector<T> &v ) :
1302 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1303  vec_(new std::vector<T>(v))
1304 #else
1305  vec_(v)
1306 #endif
1307 {}
1308 
1309 
1310 template<typename T> inline
1311 std::vector<T> Array<T>::toVector() const
1312 {
1313  if (!size())
1314  return std::vector<T>();
1315  std::vector<T> v(begin(),end());
1316  return v;
1317 }
1318 
1319 
1320 template<typename T> inline
1321 Array<T>& Array<T>::operator=( const std::vector<T> &v )
1322 {
1323  vec(true) = v;
1324  return *this;
1325 }
1326 
1327 
1328 // Views
1329 
1330 
1331 template<typename T> inline
1333 {
1334  if (size_in) {
1335 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1336  return ArrayView<T>(this->begin().persistingView(offset, size_in));
1337 #else
1338  return arrayView( &vec()[offset], size_in );
1339 #endif
1340  }
1341  return Teuchos::null;
1342 }
1343 
1344 
1345 template<typename T> inline
1347 {
1348  if (size_in) {
1349 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1350  return ArrayView<const T>(this->begin().persistingView(offset, size_in));
1351 #else
1352  return arrayView( &vec()[offset], size_in );
1353 #endif
1354  }
1355  return Teuchos::null;
1356  // NOTE: Above, we use a different implementation to call the const version
1357  // of begin() instead of the non-const version. This sets up a different
1358  // ArrayRCP object that gets checked.
1359 }
1360 
1361 
1362 template<typename T> inline
1364 {
1365  return view(offset, size_in);
1366 }
1367 
1368 
1369 template<typename T> inline
1371 {
1372  return view(offset, size_in);
1373 }
1374 
1375 
1376 template<typename T> inline
1378 {
1379  if (!size())
1380  return null;
1381  return this->view(0, size());
1382 }
1383 
1384 
1385 template<typename T> inline
1387 {
1388  if (!size())
1389  return null;
1390  return this->view(0, size());
1391 }
1392 
1393 
1394 template<typename T> inline
1396 {
1397  return this->operator()();
1398 }
1399 
1400 
1401 template<typename T> inline
1403 {
1404  return this->operator()();
1405 }
1406 
1407 
1408 // private
1409 
1410 
1411 template<typename T>
1412 std::vector<T>&
1413 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
1414 {
1415 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1416  (void)activeIter;
1417  if (isStructureBeingModified) {
1418  // Give up my ArrayRCPs used for iterator access since the array we be
1419  // getting modifed! Any clients that have views through weak pointers
1420  // better not touch them!
1421  extern_arcp_ = null;
1422  extern_carcp_ = null;
1423  }
1424  return *vec_;
1425 #else
1426  // get rid of "unused parameter" warnings
1427  (void)isStructureBeingModified;
1428  (void)activeIter;
1429  return vec_;
1430 #endif
1431 }
1432 
1433 
1434 template<typename T> inline
1435 const std::vector<T>&
1436 Array<T>::vec() const
1437 {
1438 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1439  return *vec_;
1440 #else
1441  return vec_;
1442 #endif
1443 }
1444 
1445 
1446 template<typename T> inline
1447 typename std::vector<T>::iterator
1448 Array<T>::raw_position( iterator position )
1449 {
1450 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1451  const iterator first = this->begin();
1452  const iterator last = this->end();
1454  !(first <= position && position <= last), DanglingReferenceError,
1455  "Error, this iterator is no longer valid for this Aray!"
1456  );
1457  // Note, above operator<=(...) functions will throw
1458  // IncompatibleIteratorsError if the iterators do not share the same
1459  // RCP_node object!
1460  return vec_->begin() + (position - this->begin());
1461 #else
1462  return position;
1463 #endif
1464 }
1465 
1466 
1467 template<typename T> inline
1468 void Array<T>::assertIndex(size_type i) const
1469 {
1471  !( 0 <= i && i < size() ), RangeError,
1472  "Array<T>::assertIndex(i): i="<<i<<" out of range [0, "<< size() << ")"
1473  );
1474 }
1475 
1476 
1477 template<typename T> inline
1478 void Array<T>::assertNotNull() const
1479 {
1481  !size(), NullReferenceError,
1482  typeName(*this)<<"::assertNotNull(): "
1483  "Error, the array has size zero!"
1484  );
1485 }
1486 
1487 
1488 } // namespace Teuchos
1489 
1490 
1491 // Nonmember functions
1492 
1493 
1494 template<typename T> inline
1495 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
1496 { return (a1.vec() == a2.vec()); }
1497 
1498 
1499 template<typename T> inline
1500 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
1501 { return (a1.vec() != a2.vec()); }
1502 
1503 
1504 template<typename T> inline
1505 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
1506 { a1.swap(a2); }
1507 
1508 
1509 template<typename T> inline
1510 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
1511 { return (a1.vec() < a2.vec()); }
1512 
1513 
1514 template<typename T> inline
1515 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
1516 { return (a1.vec() <= a2.vec()); }
1517 
1518 
1519 template<typename T> inline
1520 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
1521 { return (a1.vec() > a2.vec()); }
1522 
1523 
1524 template<typename T> inline
1525 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
1526 { return (a1.vec() >= a2.vec()); }
1527 
1528 
1529 template<typename T> inline
1530 std::ostream& Teuchos::operator<<(
1531  std::ostream& os, const Array<T>& array
1532  )
1533 {
1534  return os << Teuchos::toString(array);
1535 }
1536 
1537 
1538 template<typename T> inline
1539 int Teuchos::hashCode(const Array<T>& array)
1540 {
1541  int rtn = hashCode(array.length());
1542  for (int i=0; i<array.length(); i++)
1543  {
1544  rtn += hashCode(array[i]);
1545  }
1546  if (rtn < 0)
1547  {
1548  /* Convert the largest -ve int to zero and -1 to
1549  * std::numeric_limits<int>::max()
1550  * */
1551  size_t maxIntBeforeWrap = std::numeric_limits<int>::max();
1552  maxIntBeforeWrap ++;
1553  rtn += maxIntBeforeWrap;
1554  }
1555  return rtn;
1556 }
1557 
1558 
1559 template<typename T> inline
1560 std::vector<T> Teuchos::createVector( const Array<T> &a )
1561 {
1562  return a.toVector();
1563 }
1564 
1565 
1566 template<typename T> inline
1567 std::string Teuchos::toString(const Array<T>& array)
1568 {
1569  return array.toString();
1570 }
1571 
1572 
1573 template<typename T>
1575 Teuchos::fromStringToArray(const std::string& arrayStr)
1576 {
1577  const std::string str = Utils::trimWhiteSpace(arrayStr);
1578  std::istringstream iss(str);
1580  ( str[0]!='{' || str[str.length()-1] != '}' )
1581  ,InvalidArrayStringRepresentation
1582  ,"Error, the std::string:\n"
1583  "----------\n"
1584  <<str<<
1585  "\n----------\n"
1586  "is not a valid array represntation!"
1587  );
1588  char c;
1589  c = iss.get(); // Read initial '{'
1590  TEUCHOS_TEST_FOR_EXCEPT(c!='{'); // Should not throw!
1591  // Now we are ready to begin reading the entries of the array!
1592  Array<T> a;
1593  while( !iss.eof() ) {
1594  // Get the basic entry std::string
1595  std::string entryStr;
1596  std::getline(iss,entryStr,','); // Get next entry up to ,!
1597  // ToDo: Above, we might have to be careful to look for the opening and
1598  // closing of parentheses in order not to pick up an internal ',' in the
1599  // middle of an entry (for a std::complex number for instance). The above
1600  // implementation assumes that there will be no commas in the middle of
1601  // the std::string representation of an entry. This is certainly true for
1602  // the types bool, int, float, and double.
1603  //
1604  // Trim whitespace from beginning and end
1605  entryStr = Utils::trimWhiteSpace(entryStr);
1607  0 == entryStr.length(),
1608  InvalidArrayStringRepresentation,
1609  "Error, the std::string:\n"
1610  "----------\n"
1611  <<str<<
1612  "\n----------\n"
1613  "is not a valid array represntation because it has an empty array entry!"
1614  );
1615  // Remove the final '}' if this is the last entry and we did not
1616  // actually terminate the above getline(...) on ','
1617  bool found_end = false;
1618  if(entryStr[entryStr.length()-1]=='}') {
1619  entryStr = entryStr.substr(0,entryStr.length()-1);
1620  found_end = true;
1621  if( entryStr.length()==0 && a.size()==0 )
1622  return a; // This is the empty array "{}" (with any spaces in it!)
1623  }
1624  // Finally we can convert the entry and add it to the array!
1625  std::istringstream entryiss(entryStr);
1626  T entry;
1627  Teuchos::extractDataFromISS( entryiss, entry );
1628  // ToDo: We may need to define a traits class to allow us to specialized
1629  // how conversion from a std::string to a object is done!
1630  a.push_back(entry);
1631  // At the end of the loop body here, if we have reached the last '}'
1632  // then the input stream iss should be empty and iss.eof() should be
1633  // true, so the loop should terminate. We put an std::exception test here
1634  // just in case something has gone wrong.
1636  found_end && !iss.eof()
1637  ,InvalidArrayStringRepresentation
1638  ,"Error, the std::string:\n"
1639  "----------\n"
1640  <<str<<
1641  "\n----------\n"
1642  "is not a valid array represntation!"
1643  );
1644  }
1645  return a;
1646 }
1647 
1648 
1649 #endif // TEUCHOS_ARRAY_H
reverse_iterator rend()
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object...
ArrayView< T > arrayView(T *p, typename ArrayView< T >::size_type size)
Construct a const or non-const view to const or non-const data.
void reserve(size_type n)
int hashCode(const Array< T > &array)
Return the hash code.
Array< T > & append(const T &x)
Add a new entry at the end of the array.
Partial specialization of ArrayRCP for const T.
static bool hasBoundsChecking()
Return true if Array has been compiled with boundschecking on.
std::vector< T > toVector() const
Explicit copy conversion to an std::vector.
ArrayView< T > view(size_type offset, size_type size)
Return non-const view of a contiguous range of elements.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
std::vector< T >::value_type value_type
The type of an entry of the Array; for compatibility with std::vector.
void extractDataFromISS(std::istringstream &iss, std::string &data)
Extracts std::string data from an istringstream object.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
iterator erase(iterator position)
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP<Array<T> > object as an ArrayRCP<T> object.
Array & operator=(const Array< T > &a)
Assignment operator (does a deep copy).
T * getRawPtr()
Return a raw pointer to beginning of array or NULL if unsized.
std::vector< T >::const_pointer const_pointer
The type of a const pointer to T; for compatibility with std::vector.
ArrayRCP< T > arcpFromArray(Array< T > &a)
Wrap an Array<T> object as a non-owning ArrayRCP<T> object.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
ArrayRCP< const T > arcp(const RCP< const Array< T > > &v)
Wrap a RCP<const Array<T> > object as an ArrayRCP<const T> object.
std::string toString(const any &rhs)
Converts the value in any to a std::string.
iterator begin() const
Return an iterator to beginning of the array of data.
static std::string trimWhiteSpace(const std::string &str)
Trim whitespace from beginning and end of std::string.
Statically sized simple array (tuple) class.
Ordinal size_type
The type of Array sizes and capacities.
int length() const
Return number of elements in the array.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
reference front()
Ordinal difference_type
The type of the difference between two size_type values.
size_type size() const
ArrayRCP< const T > arcpFromArray(const Array< T > &a)
Wrap a const Array<T> object as a non-owning ArrayRCP<T> object.
size_type capacity() const
std::string getArrayTypeNameTraitsFormat()
Get the format that is used for the specialization of the TypeName traits class for Array...
friend void swap(Array< T2 > &a1, Array< T2 > &a2)
void resize(size_type new_size, const value_type &x=value_type())
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
friend bool Teuchos::operator>(const Array< T2 > &a1, const Array< T2 > &a2)
Teuchos_Ordinal Ordinal
The type of indices.
std::vector< T >::reference reference
The type of a reference to T; for compatibility with std::vector.
std::vector< T >::pointer pointer
The type of a pointer to T; for compatibility with std::vector.
size_type max_size() const
bool empty() const
std::vector< T >::const_iterator const_iterator
The type of a const forward iterator.
reverse_iterator rbegin()
std::vector< T >::const_reference const_reference
The type of a const reference to T; for compatibility with std::vector.
reference back()
void push_back(const value_type &x)
Nonowning array view.
Default traits class that just returns typeid(T).name().
void extractDataFromISS(std::istringstream &iss, T &data)
Extracts data from an istringstream object.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
std::vector< T >::const_reverse_iterator const_reverse_iterator
The type of a const reverse iterator.
std::string toString() const
Convert an Array to an std::string
friend bool Teuchos::operator>=(const Array< T2 > &a1, const Array< T2 > &a2)
std::vector< T >::allocator_type allocator_type
The allocator type; for compatibility with std::vector.
ArrayView< T > operator()()
Return an non-const ArrayView of *this.
reference at(size_type i)
Smart reference counting pointer class for automatic garbage collection.
friend bool Teuchos::operator!=(const Array< T2 > &a1, const Array< T2 > &a2)
reference operator[](size_type i)
Partial specialization of ArrayView for const T.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
void assign(size_type n, const value_type &val)
iterator end() const
Return an iterator to past the end of the array of data.
Array()
Default constructor; creates an empty Array.
std::vector< T >::iterator iterator
The type of a forward iterator.
A utilities class for Teuchos.
iterator insert(iterator position, const value_type &x)
iterator begin()
Defines basic traits returning the name of a type in a portable and readable way. ...
std::vector< T >::reverse_iterator reverse_iterator
The type of a reverse iterator.
~Array()
Destructor.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call...
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...