Teuchos Package Browser (Single Doxygen Collection)  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 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_ARRAY_BOUNDSCHECK) && defined(HAVE_TEUCHOS_THREAD_SAFE) && !defined(REMOVE_THREAD_PROTECTION_FOR_ARRAY)
58 #include <mutex>
59 #define USE_MUTEX_LOCK_FOR_ARRAY
60 #endif
61 
62 namespace Teuchos {
63 
68 class InvalidArrayStringRepresentation : public std::logic_error
69 {public:InvalidArrayStringRepresentation(const std::string& what_arg) : std::logic_error(what_arg) {}};
70 
71 
72 template<typename T> class Array;
73 
74 
75 // 2007/11/30: rabartl: Below, I had to move the initial declaration of these
76 // non-member template functions outside of the Array class since the Sun
77 // compiler on sass9000 would not accept this. However, this did work on a
78 // number of other compilers such a g++, Intel C++ etc. The old in-class
79 // non-member friend definition is clearly ISO 98 C++ as shown in Item 46 of
80 // "Effective C++: Third Edition". This is not the end of the world but this
81 // is something to remember for this platform.
82 
83 
88 template<typename T> inline
89 bool operator==( const Array<T> &a1, const Array<T> &a2 );
90 
91 
96 template<typename T> inline
97 bool operator!=( const Array<T> &a1, const Array<T> &a2 );
98 
99 
104 template<typename T> inline
105 void swap( Array<T> &a1, Array<T> &a2 );
106 
107 
112 template<typename T> inline
113 bool operator<( const Array<T> &a1, const Array<T> &a2 );
114 
115 
120 template<typename T> inline
121 bool operator<=( const Array<T> &a1, const Array<T> &a2 );
122 
123 
128 template<typename T> inline
129 bool operator>( const Array<T> &a1, const Array<T> &a2 );
130 
131 
136 template<typename T> inline
137 bool operator>=( const Array<T> &a1, const Array<T> &a2 );
138 
139 
193 template<typename T>
194 class Array
195 {
196 public:
197 
198  // 2007/11/30: rabartl: Below, note that the only reason that these
199  // functions are declared as friends is so that the compiler will do
200  // automatic type conversions as described in "Effective C++: Third Edition"
201  // Item 46.
202 
204  template<typename T2>
205  friend bool Teuchos::operator==( const Array<T2> &a1, const Array<T2> &a2 );
206 
208  template<typename T2>
209  friend bool Teuchos::operator!=( const Array<T2> &a1, const Array<T2> &a2 );
210 
212  template<typename T2>
213  friend void swap( Array<T2> &a1, Array<T2> &a2 );
214 
216  template<typename T2>
217  friend bool Teuchos::operator<( const Array<T2> &a1, const Array<T2> &a2 );
218 
220  template<typename T2>
221  friend bool Teuchos::operator<=( const Array<T2> &a1, const Array<T2> &a2 );
222 
224  template<typename T2>
225  friend bool Teuchos::operator>( const Array<T2> &a1, const Array<T2> &a2 );
226 
228  template<typename T2>
229  friend bool Teuchos::operator>=( const Array<T2> &a1, const Array<T2> &a2 );
230 
233 
241  typedef typename std::vector<T>::value_type value_type;
243  typedef typename std::vector<T>::pointer pointer;
245  typedef typename std::vector<T>::const_pointer const_pointer;
247  typedef typename std::vector<T>::reference reference;
249  typedef typename std::vector<T>::const_reference const_reference;
251  typedef typename std::vector<T>::allocator_type allocator_type;
252 
253 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
254  typedef ArrayRCP<T> iterator;
259  typedef std::reverse_iterator<iterator> reverse_iterator;
261  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
262 #else
263  typedef typename std::vector<T>::iterator iterator;
266  typedef typename std::vector<T>::const_iterator const_iterator;
268  typedef typename std::vector<T>::reverse_iterator reverse_iterator;
270  typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
271 #endif
272 
274 
276 
278  inline Array();
279 
281  inline explicit Array(size_type n, const value_type& value = value_type());
282 
284  inline Array(const Array<T>& x);
285 
287  template<typename InputIterator>
288  inline Array(InputIterator first, InputIterator last);
289 
291  inline Array(const ArrayView<const T>& a);
292 
294  template<int N>
295  inline Array(const Tuple<T,N>& t);
296 
298  inline ~Array();
299 
301  inline Array& operator=(const Array<T>& a);
302 
304 
310 
312  inline void assign(size_type n, const value_type& val);
314  template<typename InputIterator>
315  inline void assign(InputIterator first, InputIterator last);
317  inline iterator begin();
319  inline iterator end();
321  inline const_iterator begin() const;
323  inline const_iterator end() const;
325  inline reverse_iterator rbegin();
327  inline reverse_iterator rend();
329  inline const_reverse_iterator rbegin() const;
331  inline const_reverse_iterator rend() const;
333  inline size_type size() const;
335  inline size_type max_size() const;
337  inline void resize(size_type new_size, const value_type& x = value_type());
339  inline size_type capacity() const;
341  inline bool empty() const;
343  inline void reserve(size_type n);
345  inline reference operator[](size_type i);
347  inline const_reference operator[](size_type i) const;
349  inline reference at(size_type i);
351  inline const_reference at(size_type i) const;
353  inline reference front();
355  inline const_reference front() const;
357  inline reference back();
359  inline const_reference back() const;
361  inline void push_back(const value_type& x);
363  inline void pop_back();
365  inline iterator insert(iterator position, const value_type& x);
367  inline void insert(iterator position, size_type n, const value_type& x);
369  template<typename InputIterator>
370  inline void insert(iterator position, InputIterator first, InputIterator last);
372  inline iterator erase(iterator position);
374  inline iterator erase(iterator first, iterator last);
376  inline void swap(Array& x);
378  inline void clear();
379 
381 
383 
388  inline Array<T>& append(const T& x);
389 
393  inline void remove(int i);
394 
399  inline int length() const;
400 
402  inline std::string toString() const;
403 
405  inline static bool hasBoundsChecking();
406 
408  inline T* getRawPtr();
409 
413  inline T* data();
414 
416  inline const T* getRawPtr() const;
417 
421  inline const T* data() const;
422 
424 
426 
428  inline Array( const std::vector<T> &v );
429 
431  inline std::vector<T> toVector() const;
432 
434  inline Array& operator=( const std::vector<T> &v );
435 
437 
439 
440 
454  inline ArrayView<T> view( size_type offset, size_type size );
455 
469  inline ArrayView<const T> view( size_type offset, size_type size ) const;
470 
474  inline ArrayView<T> operator()( size_type offset, size_type size );
475 
479  inline ArrayView<const T> operator()( size_type offset, size_type size ) const;
480 
485  inline ArrayView<T> operator()();
486 
491  inline ArrayView<const T> operator()() const;
492 
496  inline operator ArrayView<T>();
497 
501  inline operator ArrayView<const T>() const;
502 
504 
505 private:
506 
507 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
509  mutable ArrayRCP<T> extern_arcp_;
510  mutable ArrayRCP<const T> extern_carcp_;
511 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
512  mutable std::mutex mutex_lock; // this mutex provides thread safe debugging for the vec_, extern_arcp_, extern_carcp_
513 #endif
514 #else
515  std::vector<T> vec_;
516 #endif
517 
518  inline std::vector<T>& vec(
519  bool isStructureBeingModified = false,
520  bool activeIter = false
521  );
522 
523  inline const std::vector<T>& vec() const;
524 
525  inline typename std::vector<T>::iterator
526  raw_position( iterator position );
527 
528  inline void assertIndex(size_type i) const;
529 
530  inline void assertNotNull() const;
531 
532 };
533 
534 
540 template<class T>
542 {
543  if ( is_null(v) || !v->size() )
544  return null;
545  return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
546  &(*v)[0], 0, v->size(),
547  v, false
548  );
549 }
550 
551 
557 template<class T>
558 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
559 {
560  if ( is_null(v) || !v->size() )
561  return null;
562  return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
563  &(*v)[0], 0, v->size(),
564  v, false
565  );
566 }
567 
568 
574 template<class T>
576 {
577  if (a.size() == 0)
578  return null;
579 #ifdef TEUCHOS_DEBUG
580  return a.begin(); // Catch dangling reference!
581 #else
582  return arcp(a.getRawPtr(), 0, a.size(), false);
583 #endif
584 }
585 
586 
592 template<class T>
594 {
595  if (a.size() == 0)
596  return null;
597 #ifdef TEUCHOS_DEBUG
598  return a.begin(); // Catch dangling reference!
599 #else
600  return arcp(a.getRawPtr(), 0, a.size(), false);
601 #endif
602 }
603 
604 
617 template<typename T>
618 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
619 
620 
625 template<typename T> inline
626 int hashCode(const Array<T>& array);
627 
628 
635 template<typename T> inline
636 std::vector<T> createVector( const Array<T> &a );
637 
638 
643 template<typename T>
644 std::string toString(const Array<T>& array);
645 
646 
698 template<typename T>
699 Array<T> fromStringToArray(const std::string& arrayStr);
700 
706 template<typename T>
707 std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
708  array = fromStringToArray<T>(in.str());
709  return in;
710 }
711 
717 template<typename T> inline
718 void extractDataFromISS( std::istringstream& iss, T& data )
719 {
720  iss >> data; // Assumes type has operator>>(...) defined!
721 }
722 
729 inline
730 void extractDataFromISS( std::istringstream& iss, std::string& data )
731 {
732  // grab unformatted string.
733  data = iss.str();
734  // remove white space from beginning and end of string.
735  data = Utils::trimWhiteSpace(data);
736 }
737 
747 inline
749  return "Array(*)";
750 }
751 
752 
753 
769 template<typename T>
771 public:
772  static std::string name(){
773  std::string formatString = getArrayTypeNameTraitsFormat();
774  size_t starPos = formatString.find("*");
775  std::string prefix = formatString.substr(0,starPos);
776  std::string postFix = formatString.substr(starPos+1);
777  return prefix+TypeNameTraits<T>::name()+postFix;
778  }
779  static std::string concreteName(const Array<T>&)
780  { return name(); }
781 };
782 
783 
784 } // namespace Teuchos
785 
786 
787 //
788 // Implementation
789 //
790 
791 
792 namespace Teuchos {
793 
794 
795 // All constructors
796 
797 
798 template<typename T> inline
800 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
801  : vec_(rcp(new std::vector<T>()))
802 #endif
803 {}
804 
805 
806 template<typename T> inline
808 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
809  vec_(rcp(new std::vector<T>(n,value)))
810 #else
811  vec_(n, value)
812 #endif
813 {}
814 
815 
816 template<typename T> inline
818 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
819  vec_(rcp(new std::vector<T>(*x.vec_)))
820 #else
821  vec_(x.vec_)
822 #endif
823 {}
824 
825 
826 template<typename T> template<typename InputIterator> inline
827 Array<T>::Array(InputIterator first, InputIterator last) :
828 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
829  vec_(rcp(new std::vector<T>(first, last)))
830 #else
831  vec_(first, last)
832 #endif
833 {}
834 
835 
836 template<typename T> inline
838 {}
839 
840 
841 template<typename T> inline
843 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
844  : vec_(rcp(new std::vector<T>()))
845 #endif
846 {
847  insert(begin(), a.begin(), a.end());
848 }
849 
850 
851 template<typename T>
852 template<int N>
853 inline
855 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
856  : vec_(rcp(new std::vector<T>()))
857 #endif
858 {
859  insert(begin(), t.begin(), t.end());
860 }
861 
862 
863 template<typename T> inline
865 {
866 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
867  std::lock_guard<std::mutex> lockGuard(mutex_lock);
868 #endif
869  vec(true) = a.vec();
870  return *this;
871 }
872 
873 
874 // Other std::vector functions
875 
876 
877 template<typename T> inline
879 {
880 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
881  std::lock_guard<std::mutex> lockGuard(mutex_lock);
882 #endif
883  vec(true).assign(n,val);
884 }
885 
886 
887 template<typename T> template<typename InputIterator> inline
888 void Array<T>::assign(InputIterator first, InputIterator last)
889 {
890 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
891  std::lock_guard<std::mutex> lockGuard(mutex_lock);
892 #endif
893  vec(true).assign(first,last);
894 }
895 
896 
897 template<typename T> inline
898 typename Array<T>::iterator
900 {
901 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
902 
903 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
904  std::lock_guard<std::mutex> lockGuard(mutex_lock);
905 #endif
906 
907  if (is_null(extern_arcp_)) {
908  // Here we must use the same RCP to avoid creating two unrelated RCPNodes!
909  extern_arcp_ = arcp(vec_); // Will be null if vec_ is sized!
910  }
911  // Returning a weak pointer will help to catch dangling references but still
912  // keep the same behavior as optimized code.
913 
914  return extern_arcp_.create_weak();
915 #else
916  return vec().begin();
917 #endif
918 }
919 
920 
921 template<typename T> inline
922 typename Array<T>::iterator
924 {
925 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
926  return begin() + size();
927 #else
928  return vec().end();
929 #endif
930 }
931 
932 template<typename T> inline
935 {
936 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
937 
938 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
939  std::lock_guard<std::mutex> lockGuard(mutex_lock);
940 #endif
941  if (is_null(extern_carcp_)) {
942  // Note that this used to call the non-const begin() function above
943  // I've moved that code here to make the mutex locking more transparent and
944  // prevent the need to structure something awkward to avoid double locks
945  // The original line of code was this:
946  // extern_carcp_ = const_cast<Array<T>*>(this)->begin();
947  // Now replaced by the following code which mirrors the above begin() call
948  if (is_null(extern_arcp_)) {
949  extern_arcp_ = arcp(vec_);
950  }
951  // note that we call create_weak() twice, first on the non-const and then
952  // below on the const - this preserves the original design exactly
953  extern_carcp_ = extern_arcp_.create_weak();
954  }
955 
956  // Returning a weak pointer will help to catch dangling references but still
957  // keep the same behavior as optimized code.
958  return extern_carcp_.create_weak();
959 #else
960  return vec().begin();
961 #endif
962 }
963 
964 
965 template<typename T> inline
968 {
969 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
970  return begin() + size();
971 #else
972  return vec().end();
973 #endif
974 }
975 
976 
977 template<typename T> inline
980 {
981 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
982  return reverse_iterator(end());
983 #else
984  return vec().rbegin();
985 #endif
986 }
987 
988 
989 template<typename T> inline
992 {
993 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
994  return reverse_iterator(begin());
995 #else
996  return vec().rend();
997 #endif
998 }
999 
1000 
1001 template<typename T> inline
1004 {
1005 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1006  return const_reverse_iterator(end());
1007 #else
1008  return vec().rbegin();
1009 #endif
1010 }
1011 
1012 
1013 template<typename T> inline
1016 {
1017 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1018  return const_reverse_iterator(begin());
1019 #else
1020  return vec().rend();
1021 #endif
1022 }
1023 
1024 
1025 template<typename T> inline
1026 typename Array<T>::size_type
1028 {
1029  return vec().size();
1030 }
1031 
1032 
1033 template<typename T> inline
1034 typename Array<T>::size_type
1036 {
1037  return std::numeric_limits<size_type>::max();
1038 }
1039 
1040 
1041 template<typename T> inline
1042 void
1044 {
1045 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1046  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1047 #endif
1048  vec(true).resize(new_size,x);
1049 }
1050 
1051 
1052 template<typename T> inline
1053 typename Array<T>::size_type
1055 {
1056  return vec().capacity();
1057 }
1058 
1059 
1060 template<typename T> inline
1061 bool Array<T>::empty() const
1062 {
1063  return vec().empty();
1064 }
1065 
1066 
1067 template<typename T> inline
1069 {
1070 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1071  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1072 #endif
1073  vec(true).reserve(n);
1074 }
1075 
1076 
1077 template<typename T> inline
1078 typename Array<T>::reference
1080 {
1081 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1082  assertIndex(i);
1083 #endif
1084  return vec()[i];
1085 }
1086 
1087 
1088 template<typename T> inline
1091 {
1092 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1093  assertIndex(i);
1094 #endif
1095  return vec()[i];
1096 }
1097 
1098 
1099 template<typename T> inline
1100 typename Array<T>::reference
1102 {
1103 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1104  assertIndex(i);
1105 #endif
1106  return vec().at(i);
1107 }
1108 
1109 
1110 template<typename T> inline
1113 {
1114 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1115  assertIndex(i);
1116 #endif
1117  return vec().at(i);
1118 }
1119 
1120 
1121 template<typename T> inline
1122 typename Array<T>::reference
1124 {
1125 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1126  assertNotNull();
1127 #endif
1128  return vec().front();
1129 }
1130 
1131 
1132 template<typename T> inline
1135 {
1136 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1137  assertNotNull();
1138 #endif
1139  return vec().front();
1140 }
1141 
1142 
1143 template<typename T> inline
1144 typename Array<T>::reference
1146 {
1147 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1148  assertNotNull();
1149 #endif
1150  return vec().back();
1151 }
1152 
1153 
1154 template<typename T> inline
1157 {
1158 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1159  assertNotNull();
1160 #endif
1161  return vec().back();
1162 }
1163 
1164 
1165 template<typename T> inline
1167 {
1168 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1169  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1170 #endif
1171  vec(true).push_back(x);
1172 }
1173 
1174 
1175 template<typename T> inline
1177 {
1178 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1179  assertNotNull();
1180 #endif
1181 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1182  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1183 #endif
1184  vec(true).pop_back();
1185 }
1186 
1187 
1188 // 2009/11/13:: rabartl: After moving to a full RCPNode tracing and lookup
1189 // model, I had to how modifying functions like insert(...) and erase(...)
1190 // work which have active iterators controled by the client and yet need to
1191 // allow the structure of the container change. The way these troublesome
1192 // functions work is that first the raw std::vector iterator is extracted.
1193 // The function vec(true, true) then deletes the strong iterators but there is
1194 // still a weak ArrayRCP object that is owned by the client which is being
1195 // passed into this function. The issue is that the design of ArrayRCP is
1196 // such that the RCPNode object is not removed but instead remains in order to
1197 // perform runtime checking.
1198 
1199 
1200 template<typename T> inline
1201 typename Array<T>::iterator
1203 {
1204 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1205  // Assert a valid iterator and get vector iterator
1206  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1207  const difference_type i = position - begin();
1208 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1209  {
1210  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1211 #endif
1212  vec(true, true).insert(raw_poss, x);
1213 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1214  } // must unlock mutex_lock before calling begin() which will lock again
1215 #endif
1216  return begin() + i;
1217 #else
1218  return vec_.insert(position, x);
1219 #endif
1220 }
1221 
1222 
1223 template<typename T> inline
1225 {
1226 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1227  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1228 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1229  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1230 #endif
1231  vec(true, true).insert(raw_poss, n, x);
1232 #else
1233  vec_.insert(position, n, x);
1234 #endif
1235 }
1236 
1237 
1238 template<typename T> template<typename InputIterator> inline
1239 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
1240 {
1241 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1242  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1243 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1244  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1245 #endif
1246  vec(true, true).insert(raw_poss, first, last);
1247 #else
1248  vec_.insert(position, first, last);
1249 #endif
1250 }
1251 
1252 
1253 template<typename T> inline
1254 typename Array<T>::iterator
1256 {
1257 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1258  assertNotNull();
1259  // Assert a valid iterator and get vector iterator
1260  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1261  const difference_type i = position - begin();
1262 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1263  {
1264  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1265 #endif
1266  vec(true, true).erase(raw_poss);
1267 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1268  } // must unlock mutex_lock before call begin() or dead lock on second call
1269 #endif
1270  return begin() + i;
1271 #else
1272  return vec_.erase(position);
1273 #endif
1274 }
1275 
1276 
1277 template<typename T> inline
1278 typename Array<T>::iterator
1280 {
1281 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1282  if (empty()) {
1283  TEUCHOS_ASSERT(first == begin());
1284  TEUCHOS_ASSERT(last == end());
1285  return end();
1286  }
1287  assertNotNull();
1288  // Assert a valid iterator and get vector iterator
1289  const typename std::vector<T>::iterator raw_first = raw_position(first);
1290  const typename std::vector<T>::iterator raw_last = raw_position(last);
1291  const difference_type i = first - begin();
1292 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1293  {
1294  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1295 #endif
1296  vec(true,true).erase(raw_first,raw_last);
1297 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1298  } // must unlock mutex_lock before call begin() or dead lock on second call
1299 #endif
1300  return begin() + i;
1301 #else
1302  return vec_.erase(first,last);
1303 #endif
1304 }
1305 
1306 
1307 template<typename T> inline
1309 {
1310 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1311  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1312 #endif
1313  vec(true).swap(x.vec());
1314 }
1315 
1316 
1317 template<typename T> inline
1319 {
1320 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1321  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1322 #endif
1323  vec(true).clear();
1324 }
1325 
1326 
1327 // Non-standard functions
1328 
1329 
1330 template<typename T> inline
1332 {
1333  this->push_back(x);
1334  return *this;
1335 }
1336 
1337 
1338 template<typename T> inline
1339 void Array<T>::remove(int i)
1340 {
1341 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1342  assertIndex(i);
1343 #endif
1344  // Erase the i-th element of this array.
1345  this->erase( this->begin() + i );
1346 }
1347 
1348 
1349 template<typename T> inline
1350 int Array<T>::length() const
1351 {
1352  return static_cast<int> (this->size ());
1353 }
1354 
1355 
1356 template<typename T> inline
1357 std::string Array<T>::toString() const
1358 {
1359  return (*this)().toString(); // Use ArrayView<T>::toString()
1360 }
1361 
1362 
1363 template<typename T> inline
1365 {
1366 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1367  return true;
1368 #else
1369  return false;
1370 #endif
1371 }
1372 
1373 
1374 template<typename T> inline
1376 {
1377  return ( size() ? &(*this)[0] : nullptr );
1378 }
1379 
1380 template<typename T> inline
1382 {
1383  return ( size() ? &(*this)[0] : nullptr );
1384 }
1385 
1386 template<typename T> inline
1387 const T* Array<T>::getRawPtr() const
1388 {
1389  return ( size() ? &(*this)[0] : nullptr );
1390 }
1391 
1392 template<typename T> inline
1393 const T* Array<T>::data() const
1394 {
1395  return ( size() ? &(*this)[0] : nullptr );
1396 }
1397 
1398 // Conversions to and from std::vector
1399 
1400 
1401 template<typename T> inline
1402 Array<T>::Array( const std::vector<T> &v ) :
1403 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1404  vec_(new std::vector<T>(v))
1405 #else
1406  vec_(v)
1407 #endif
1408 {}
1409 
1410 
1411 template<typename T> inline
1412 std::vector<T> Array<T>::toVector() const
1413 {
1414  if (!size())
1415  return std::vector<T>();
1416  std::vector<T> v(begin(),end());
1417  return v;
1418 }
1419 
1420 
1421 template<typename T> inline
1422 Array<T>& Array<T>::operator=( const std::vector<T> &v )
1423 {
1424 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1425  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1426 #endif
1427  vec(true) = v;
1428  return *this;
1429 }
1430 
1431 
1432 // Views
1433 
1434 
1435 template<typename T> inline
1437 {
1438  if (size_in) {
1439 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1440  return ArrayView<T>(this->begin().persistingView(offset, size_in));
1441 #else
1442  return arrayView( &vec()[offset], size_in );
1443 #endif
1444  }
1445  return Teuchos::null;
1446 }
1447 
1448 
1449 template<typename T> inline
1451 {
1452  if (size_in) {
1453 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1454  return ArrayView<const T>(this->begin().persistingView(offset, size_in));
1455 #else
1456  return arrayView( &vec()[offset], size_in );
1457 #endif
1458  }
1459  return Teuchos::null;
1460  // NOTE: Above, we use a different implementation to call the const version
1461  // of begin() instead of the non-const version. This sets up a different
1462  // ArrayRCP object that gets checked.
1463 }
1464 
1465 
1466 template<typename T> inline
1468 {
1469  return view(offset, size_in);
1470 }
1471 
1472 
1473 template<typename T> inline
1475 {
1476  return view(offset, size_in);
1477 }
1478 
1479 
1480 template<typename T> inline
1482 {
1483  if (!size())
1484  return null;
1485  return this->view(0, size());
1486 }
1487 
1488 
1489 template<typename T> inline
1491 {
1492  if (!size())
1493  return null;
1494  return this->view(0, size());
1495 }
1496 
1497 
1498 template<typename T> inline
1500 {
1501  return this->operator()();
1502 }
1503 
1504 
1505 template<typename T> inline
1507 {
1508  return this->operator()();
1509 }
1510 
1511 
1512 // private
1513 
1514 
1515 template<typename T>
1516 std::vector<T>&
1517 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
1518 {
1519 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1520  (void)activeIter;
1521  if (isStructureBeingModified) {
1522  // Give up my ArrayRCPs used for iterator access since the array we be
1523  // getting modifed! Any clients that have views through weak pointers
1524  // better not touch them!
1525 
1526  // Note that in debug mode these are mutex protected - the mutex should
1527  // always be locked when this function is called with
1528  // isStructureBeingModified true
1529  extern_arcp_ = null;
1530  extern_carcp_ = null;
1531  }
1532  return *vec_;
1533 #else
1534  // get rid of "unused parameter" warnings
1535  (void)isStructureBeingModified;
1536  (void)activeIter;
1537  return vec_;
1538 #endif
1539 }
1540 
1541 
1542 template<typename T> inline
1543 const std::vector<T>&
1545 {
1546 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1547  return *vec_;
1548 #else
1549  return vec_;
1550 #endif
1551 }
1552 
1553 
1554 template<typename T> inline
1555 typename std::vector<T>::iterator
1557 {
1558 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1559  const iterator first = this->begin();
1560  const iterator last = this->end();
1562  !(first <= position && position <= last), DanglingReferenceError,
1563  "Error, this iterator is no longer valid for this Aray!"
1564  );
1565  // Note, above operator<=(...) functions will throw
1566  // IncompatibleIteratorsError if the iterators do not share the same
1567  // RCP_node object!
1568  return vec_->begin() + (position - this->begin());
1569 #else
1570  return position;
1571 #endif
1572 }
1573 
1574 
1575 template<typename T> inline
1577 {
1579  !( 0 <= i && i < size() ), RangeError,
1580  "Array<T>::assertIndex(i): i="<<i<<" out of range [0, "<< size() << ")"
1581  );
1582 }
1583 
1584 
1585 template<typename T> inline
1587 {
1590  typeName(*this)<<"::assertNotNull(): "
1591  "Error, the array has size zero!"
1592  );
1593 }
1594 
1595 
1596 } // namespace Teuchos
1597 
1598 
1599 // Nonmember functions
1600 
1601 
1602 template<typename T> inline
1603 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
1604 { return (a1.vec() == a2.vec()); }
1605 
1606 
1607 template<typename T> inline
1608 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
1609 { return (a1.vec() != a2.vec()); }
1610 
1611 
1612 template<typename T> inline
1613 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
1614 { a1.swap(a2); }
1615 
1616 
1617 template<typename T> inline
1618 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
1619 { return (a1.vec() < a2.vec()); }
1620 
1621 
1622 template<typename T> inline
1623 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
1624 { return (a1.vec() <= a2.vec()); }
1625 
1626 
1627 template<typename T> inline
1628 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
1629 { return (a1.vec() > a2.vec()); }
1630 
1631 
1632 template<typename T> inline
1633 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
1634 { return (a1.vec() >= a2.vec()); }
1635 
1636 
1637 template<typename T> inline
1638 std::ostream& Teuchos::operator<<(
1639  std::ostream& os, const Array<T>& array
1640  )
1641 {
1642  return os << Teuchos::toString(array);
1643 }
1644 
1645 
1646 template<typename T> inline
1647 int Teuchos::hashCode(const Array<T>& array)
1648 {
1649  int rtn = hashCode(array.length());
1650  for (int i=0; i<array.length(); i++)
1651  {
1652  rtn += hashCode(array[i]);
1653  }
1654  if (rtn < 0)
1655  {
1656  /* Convert the largest -ve int to zero and -1 to
1657  * std::numeric_limits<int>::max()
1658  * */
1659  size_t maxIntBeforeWrap = std::numeric_limits<int>::max();
1660  maxIntBeforeWrap ++;
1661  rtn += maxIntBeforeWrap;
1662  }
1663  return rtn;
1664 }
1665 
1666 
1667 template<typename T> inline
1668 std::vector<T> Teuchos::createVector( const Array<T> &a )
1669 {
1670  return a.toVector();
1671 }
1672 
1673 
1674 template<typename T> inline
1675 std::string Teuchos::toString(const Array<T>& array)
1676 {
1677  return array.toString();
1678 }
1679 
1680 
1681 template<typename T>
1683 Teuchos::fromStringToArray(const std::string& arrayStr)
1684 {
1685  const std::string str = Utils::trimWhiteSpace(arrayStr);
1686  std::istringstream iss(str);
1688  ( str[0]!='{' || str[str.length()-1] != '}' )
1689  ,InvalidArrayStringRepresentation
1690  ,"Error, the std::string:\n"
1691  "----------\n"
1692  <<str<<
1693  "\n----------\n"
1694  "is not a valid array represntation!"
1695  );
1696  char c;
1697  c = iss.get(); // Read initial '{'
1698  TEUCHOS_TEST_FOR_EXCEPT(c!='{'); // Should not throw!
1699  // Now we are ready to begin reading the entries of the array!
1700  Array<T> a;
1701  while( !iss.eof() ) {
1702  // Get the basic entry std::string
1703  std::string entryStr;
1704  std::getline(iss,entryStr,','); // Get next entry up to ,!
1705  // ToDo: Above, we might have to be careful to look for the opening and
1706  // closing of parentheses in order not to pick up an internal ',' in the
1707  // middle of an entry (for a std::complex number for instance). The above
1708  // implementation assumes that there will be no commas in the middle of
1709  // the std::string representation of an entry. This is certainly true for
1710  // the types bool, int, float, and double.
1711  //
1712  // Trim whitespace from beginning and end
1713  entryStr = Utils::trimWhiteSpace(entryStr);
1715  0 == entryStr.length(),
1716  InvalidArrayStringRepresentation,
1717  "Error, the std::string:\n"
1718  "----------\n"
1719  <<str<<
1720  "\n----------\n"
1721  "is not a valid array represntation because it has an empty array entry!"
1722  );
1723  // Remove the final '}' if this is the last entry and we did not
1724  // actually terminate the above getline(...) on ','
1725  bool found_end = false;
1726  if(entryStr[entryStr.length()-1]=='}') {
1727  entryStr = entryStr.substr(0,entryStr.length()-1);
1728  found_end = true;
1729  if( entryStr.length()==0 && a.size()==0 )
1730  return a; // This is the empty array "{}" (with any spaces in it!)
1731  }
1732  // Finally we can convert the entry and add it to the array!
1733  std::istringstream entryiss(entryStr);
1734  T entry;
1735  Teuchos::extractDataFromISS( entryiss, entry );
1736  // ToDo: We may need to define a traits class to allow us to specialized
1737  // how conversion from a std::string to a object is done!
1738  a.push_back(entry);
1739  // At the end of the loop body here, if we have reached the last '}'
1740  // then the input stream iss should be empty and iss.eof() should be
1741  // true, so the loop should terminate. We put an std::exception test here
1742  // just in case something has gone wrong.
1744  found_end && !iss.eof()
1745  ,InvalidArrayStringRepresentation
1746  ,"Error, the std::string:\n"
1747  "----------\n"
1748  <<str<<
1749  "\n----------\n"
1750  "is not a valid array represntation!"
1751  );
1752  }
1753  return a;
1754 }
1755 
1756 
1757 #endif // TEUCHOS_ARRAY_H
static std::string concreteName(const Array< T > &)
Dangling reference error exception class.
Null reference error exception class.
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.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
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.
std::vector< T >::iterator raw_position(iterator position)
void extractDataFromISS(std::istringstream &iss, std::string &data)
Extracts std::string data from an istringstream object.
RawPointerConversionTraits< Container >::Ptr_t getRawPtr(const Container &c)
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
std::vector< T > vec_
const std::vector< T > & vec() const
void assertIndex(size_type i) const
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.
bool operator!=(const Allocator< T > &a_t, const Allocator< U > &a_u)
Return ! (a_t == a_u) (see above).
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.
std::istringstream & operator>>(std::istringstream &in, TwoDArray< T > &array)
static std::string trimWhiteSpace(const std::string &str)
Trim whitespace from beginning and end of std::string.
std::ostream & operator<<(std::ostream &os, BigUInt< n > a)
Statically sized simple array (tuple) class.
TEUCHOS_ORDINAL_TYPE Teuchos_Ordinal
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.
bool operator>(BigUInt< n > const &a, BigUInt< n > const &b)
reference front()
Ordinal difference_type
The type of the difference between two size_type values.
bool operator>=(BigUInt< n > const &a, BigUInt< n > const &b)
#define TEUCHOSCORE_LIB_DLL_EXPORT
std::string toString(const HashSet< Key > &h)
std::vector< T > & vec(bool isStructureBeingModified=false, bool activeIter=false)
size_type size() const
T * data()
Return a raw pointer to beginning of array.
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.
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.
std::vector< T >::const_reverse_iterator const_reverse_iterator
The type of a const reverse iterator.
dependentList insert(myDepList.getEntryRCP(dependent1))
std::string toString() const
Convert an Array to an std::string
InvalidArrayStringRepresentation(const std::string &what_arg)
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.
reference operator[](size_type i)
void assertNotNull() const
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)
Range error exception class.
iterator end() const
Return an iterator to past the end of the array of data.
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)
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...
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...