Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
235  typedef Teuchos_Ordinal Ordinal;
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
508  RCP<std::vector<T> > vec_;
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>
770 class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<Array<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
1224 void Array<T>::insert(iterator position, size_type n, const value_type& x)
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>&
1544 Array<T>::vec() const
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
1556 Array<T>::raw_position( iterator position )
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
1576 void Array<T>::assertIndex(size_type i) const
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
1586 void Array<T>::assertNotNull() const
1587 {
1589  !size(), NullReferenceError,
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
reverse_iterator rend()
void remove(int i)
Remove the i-th element from the array, with optional boundschecking.
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.
iterator begin() const
Return an iterator to beginning of the array of data.
bool empty() const
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&lt;Array&lt;T&gt; &gt; object as an ArrayRCP&lt;T&gt; 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&lt;T&gt; object as a non-owning ArrayRCP&lt;T&gt; object.
ArrayRCP< const T > arcp(const RCP< const Array< T > > &v)
Wrap a RCP&lt;const Array&lt;T&gt; &gt; object as an ArrayRCP&lt;const T&gt; object.
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.
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.
std::string toString() const
Convert an Array to an std::string
T * data()
Return a raw pointer to beginning of array.
ArrayRCP< const T > arcpFromArray(const Array< T > &a)
Wrap a const Array&lt;T&gt; object as a non-owning ArrayRCP&lt;T&gt; object.
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())
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.
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.
iterator end() const
Return an iterator to past the end of the array of data.
int length() const
Return number of elements in the array.
size_type size() const
std::vector< T >::allocator_type allocator_type
The allocator type; for compatibility with std::vector.
std::vector< T > toVector() const
Explicit copy conversion to an 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)
Array()
Default constructor; creates an empty Array.
size_type max_size() const
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.
size_type capacity() const
~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...