Teuchos Package Browser (Single Doxygen Collection)  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 
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(std::initializer_list<T> list);
299 
301  inline ~Array();
302 
304  inline Array& operator=(const Array<T>& a);
305 
307 
313 
315  inline void assign(size_type n, const value_type& val);
317  template<typename InputIterator>
318  inline void assign(InputIterator first, InputIterator last);
320  inline iterator begin();
322  inline iterator end();
324  inline const_iterator begin() const;
326  inline const_iterator end() const;
328  inline reverse_iterator rbegin();
330  inline reverse_iterator rend();
332  inline const_reverse_iterator rbegin() const;
334  inline const_reverse_iterator rend() const;
336  inline size_type size() const;
338  inline size_type max_size() const;
340  inline void resize(size_type new_size, const value_type& x = value_type());
342  inline size_type capacity() const;
344  inline bool empty() const;
346  inline void reserve(size_type n);
348  inline reference operator[](size_type i);
350  inline const_reference operator[](size_type i) const;
352  inline reference at(size_type i);
354  inline const_reference at(size_type i) const;
356  inline reference front();
358  inline const_reference front() const;
360  inline reference back();
362  inline const_reference back() const;
364  inline void push_back(const value_type& x);
366  inline void pop_back();
368  inline iterator insert(iterator position, const value_type& x);
370  inline void insert(iterator position, size_type n, const value_type& x);
372  template<typename InputIterator>
373  inline void insert(iterator position, InputIterator first, InputIterator last);
375  inline iterator erase(iterator position);
377  inline iterator erase(iterator first, iterator last);
379  inline void swap(Array& x);
381  inline void clear();
382 
384 
386 
391  inline Array<T>& append(const T& x);
392 
396  inline void remove(int i);
397 
402  inline int length() const;
403 
405  inline std::string toString() const;
406 
408  inline static bool hasBoundsChecking();
409 
411  inline T* getRawPtr();
412 
416  inline T* data();
417 
419  inline const T* getRawPtr() const;
420 
424  inline const T* data() const;
425 
427 
429 
431  inline Array( const std::vector<T> &v );
432 
434  inline std::vector<T> toVector() const;
435 
437  inline Array& operator=( const std::vector<T> &v );
438 
440 
442 
443 
457  inline ArrayView<T> view( size_type offset, size_type size );
458 
472  inline ArrayView<const T> view( size_type offset, size_type size ) const;
473 
477  inline ArrayView<T> operator()( size_type offset, size_type size );
478 
482  inline ArrayView<const T> operator()( size_type offset, size_type size ) const;
483 
488  inline ArrayView<T> operator()();
489 
494  inline ArrayView<const T> operator()() const;
495 
499  inline operator ArrayView<T>();
500 
504  inline operator ArrayView<const T>() const;
505 
507 
508 private:
509 
510 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
512  mutable ArrayRCP<T> extern_arcp_;
513  mutable ArrayRCP<const T> extern_carcp_;
514 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
515  mutable std::mutex mutex_lock; // this mutex provides thread safe debugging for the vec_, extern_arcp_, extern_carcp_
516 #endif
517 #else
518  std::vector<T> vec_;
519 #endif
520 
521  inline std::vector<T>& vec(
522  bool isStructureBeingModified = false,
523  bool activeIter = false
524  );
525 
526  inline const std::vector<T>& vec() const;
527 
528  inline typename std::vector<T>::iterator
529  raw_position( iterator position );
530 
531  inline void assertIndex(size_type i) const;
532 
533  inline void assertNotNull() const;
534 
535 };
536 
537 
543 template<class T>
545 {
546  if ( is_null(v) || !v->size() )
547  return null;
548  return arcpWithEmbeddedObjPostDestroy<T,RCP<Array<T> > >(
549  &(*v)[0], 0, v->size(),
550  v, false
551  );
552 }
553 
554 
560 template<class T>
561 ArrayRCP<const T> arcp( const RCP<const Array<T> > &v )
562 {
563  if ( is_null(v) || !v->size() )
564  return null;
565  return arcpWithEmbeddedObjPostDestroy<const T,RCP<const Array<T> > >(
566  &(*v)[0], 0, v->size(),
567  v, false
568  );
569 }
570 
571 
577 template<class T>
579 {
580  if (a.size() == 0)
581  return null;
582 #ifdef TEUCHOS_DEBUG
583  return a.begin(); // Catch dangling reference!
584 #else
585  return arcp(a.getRawPtr(), 0, a.size(), false);
586 #endif
587 }
588 
589 
595 template<class T>
597 {
598  if (a.size() == 0)
599  return null;
600 #ifdef TEUCHOS_DEBUG
601  return a.begin(); // Catch dangling reference!
602 #else
603  return arcp(a.getRawPtr(), 0, a.size(), false);
604 #endif
605 }
606 
607 
620 template<typename T>
621 std::ostream& operator<<(std::ostream& os, const Array<T>& array);
622 
623 
628 template<typename T> inline
629 int hashCode(const Array<T>& array);
630 
631 
638 template<typename T> inline
639 std::vector<T> createVector( const Array<T> &a );
640 
641 
646 template<typename T>
647 std::string toString(const Array<T>& array);
648 
649 
701 template<typename T>
702 Array<T> fromStringToArray(const std::string& arrayStr);
703 
709 template<typename T>
710 std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
711  array = fromStringToArray<T>(in.str());
712  return in;
713 }
714 
720 template<typename T> inline
721 void extractDataFromISS( std::istringstream& iss, T& data )
722 {
723  iss >> data; // Assumes type has operator>>(...) defined!
724 }
725 
732 inline
733 void extractDataFromISS( std::istringstream& iss, std::string& data )
734 {
735  // grab unformatted string.
736  data = iss.str();
737  // remove white space from beginning and end of string.
738  data = Utils::trimWhiteSpace(data);
739 }
740 
750 inline
752  return "Array(*)";
753 }
754 
755 
756 
772 template<typename T>
774 public:
775  static std::string name(){
776  std::string formatString = getArrayTypeNameTraitsFormat();
777  size_t starPos = formatString.find("*");
778  std::string prefix = formatString.substr(0,starPos);
779  std::string postFix = formatString.substr(starPos+1);
780  return prefix+TypeNameTraits<T>::name()+postFix;
781  }
782  static std::string concreteName(const Array<T>&)
783  { return name(); }
784 };
785 
786 
787 } // namespace Teuchos
788 
789 
790 //
791 // Implementation
792 //
793 
794 
795 namespace Teuchos {
796 
797 
798 // All constructors
799 
800 
801 template<typename T> inline
803 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
804  : vec_(rcp(new std::vector<T>()))
805 #endif
806 {}
807 
808 
809 template<typename T> inline
811 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
812  vec_(rcp(new std::vector<T>(n,value)))
813 #else
814  vec_(n, value)
815 #endif
816 {}
817 
818 
819 template<typename T> inline
821 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
822  vec_(rcp(new std::vector<T>(*x.vec_)))
823 #else
824  vec_(x.vec_)
825 #endif
826 {}
827 
828 
829 template<typename T> template<typename InputIterator> inline
830 Array<T>::Array(InputIterator first, InputIterator last) :
831 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
832  vec_(rcp(new std::vector<T>(first, last)))
833 #else
834  vec_(first, last)
835 #endif
836 {}
837 
838 
839 template<typename T> inline
841 {}
842 
843 
844 template<typename T> inline
846 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
847  : vec_(rcp(new std::vector<T>()))
848 #endif
849 {
850  insert(begin(), a.begin(), a.end());
851 }
852 
853 
854 template<typename T>
855 template<int N>
856 inline
858 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
859  : vec_(rcp(new std::vector<T>()))
860 #endif
861 {
862  insert(begin(), t.begin(), t.end());
863 }
864 
865 template<typename T> inline
866 Array<T>::Array(std::initializer_list<T> a)
867 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
868  : vec_(rcp(new std::vector<T>(a)))
869 #else
870  : vec_(a)
871 #endif
872 {}
873 
874 template<typename T> inline
876 {
877 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
878  std::lock_guard<std::mutex> lockGuard(mutex_lock);
879 #endif
880  vec(true) = a.vec();
881  return *this;
882 }
883 
884 
885 // Other std::vector functions
886 
887 
888 template<typename T> inline
890 {
891 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
892  std::lock_guard<std::mutex> lockGuard(mutex_lock);
893 #endif
894  vec(true).assign(n,val);
895 }
896 
897 
898 template<typename T> template<typename InputIterator> inline
899 void Array<T>::assign(InputIterator first, InputIterator last)
900 {
901 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
902  std::lock_guard<std::mutex> lockGuard(mutex_lock);
903 #endif
904  vec(true).assign(first,last);
905 }
906 
907 
908 template<typename T> inline
909 typename Array<T>::iterator
911 {
912 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
913 
914 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
915  std::lock_guard<std::mutex> lockGuard(mutex_lock);
916 #endif
917 
918  if (is_null(extern_arcp_)) {
919  // Here we must use the same RCP to avoid creating two unrelated RCPNodes!
920  extern_arcp_ = arcp(vec_); // Will be null if vec_ is sized!
921  }
922  // Returning a weak pointer will help to catch dangling references but still
923  // keep the same behavior as optimized code.
924 
925  return extern_arcp_.create_weak();
926 #else
927  return vec().begin();
928 #endif
929 }
930 
931 
932 template<typename T> inline
933 typename Array<T>::iterator
935 {
936 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
937  return begin() + size();
938 #else
939  return vec().end();
940 #endif
941 }
942 
943 template<typename T> inline
946 {
947 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
948 
949 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
950  std::lock_guard<std::mutex> lockGuard(mutex_lock);
951 #endif
952  if (is_null(extern_carcp_)) {
953  // Note that this used to call the non-const begin() function above
954  // I've moved that code here to make the mutex locking more transparent and
955  // prevent the need to structure something awkward to avoid double locks
956  // The original line of code was this:
957  // extern_carcp_ = const_cast<Array<T>*>(this)->begin();
958  // Now replaced by the following code which mirrors the above begin() call
959  if (is_null(extern_arcp_)) {
960  extern_arcp_ = arcp(vec_);
961  }
962  // note that we call create_weak() twice, first on the non-const and then
963  // below on the const - this preserves the original design exactly
964  extern_carcp_ = extern_arcp_.create_weak();
965  }
966 
967  // Returning a weak pointer will help to catch dangling references but still
968  // keep the same behavior as optimized code.
969  return extern_carcp_.create_weak();
970 #else
971  return vec().begin();
972 #endif
973 }
974 
975 
976 template<typename T> inline
979 {
980 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
981  return begin() + size();
982 #else
983  return vec().end();
984 #endif
985 }
986 
987 
988 template<typename T> inline
991 {
992 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
993  return reverse_iterator(end());
994 #else
995  return vec().rbegin();
996 #endif
997 }
998 
999 
1000 template<typename T> inline
1003 {
1004 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1005  return reverse_iterator(begin());
1006 #else
1007  return vec().rend();
1008 #endif
1009 }
1010 
1011 
1012 template<typename T> inline
1015 {
1016 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1017  return const_reverse_iterator(end());
1018 #else
1019  return vec().rbegin();
1020 #endif
1021 }
1022 
1023 
1024 template<typename T> inline
1027 {
1028 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1029  return const_reverse_iterator(begin());
1030 #else
1031  return vec().rend();
1032 #endif
1033 }
1034 
1035 
1036 template<typename T> inline
1037 typename Array<T>::size_type
1039 {
1040  return vec().size();
1041 }
1042 
1043 
1044 template<typename T> inline
1045 typename Array<T>::size_type
1047 {
1048  return std::numeric_limits<size_type>::max();
1049 }
1050 
1051 
1052 template<typename T> inline
1053 void
1055 {
1056 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1057  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1058 #endif
1059  vec(true).resize(new_size,x);
1060 }
1061 
1062 
1063 template<typename T> inline
1064 typename Array<T>::size_type
1066 {
1067  return vec().capacity();
1068 }
1069 
1070 
1071 template<typename T> inline
1072 bool Array<T>::empty() const
1073 {
1074  return vec().empty();
1075 }
1076 
1077 
1078 template<typename T> inline
1080 {
1081 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1082  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1083 #endif
1084  vec(true).reserve(n);
1085 }
1086 
1087 
1088 template<typename T> inline
1089 typename Array<T>::reference
1091 {
1092 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1093  assertIndex(i);
1094 #endif
1095  return vec()[i];
1096 }
1097 
1098 
1099 template<typename T> inline
1102 {
1103 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1104  assertIndex(i);
1105 #endif
1106  return vec()[i];
1107 }
1108 
1109 
1110 template<typename T> inline
1111 typename Array<T>::reference
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
1124 {
1125 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1126  assertIndex(i);
1127 #endif
1128  return vec().at(i);
1129 }
1130 
1131 
1132 template<typename T> inline
1133 typename Array<T>::reference
1135 {
1136 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1137  assertNotNull();
1138 #endif
1139  return vec().front();
1140 }
1141 
1142 
1143 template<typename T> inline
1146 {
1147 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1148  assertNotNull();
1149 #endif
1150  return vec().front();
1151 }
1152 
1153 
1154 template<typename T> inline
1155 typename Array<T>::reference
1157 {
1158 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1159  assertNotNull();
1160 #endif
1161  return vec().back();
1162 }
1163 
1164 
1165 template<typename T> inline
1168 {
1169 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1170  assertNotNull();
1171 #endif
1172  return vec().back();
1173 }
1174 
1175 
1176 template<typename T> inline
1178 {
1179 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1180  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1181 #endif
1182  vec(true).push_back(x);
1183 }
1184 
1185 
1186 template<typename T> inline
1188 {
1189 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1190  assertNotNull();
1191 #endif
1192 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1193  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1194 #endif
1195  vec(true).pop_back();
1196 }
1197 
1198 
1199 // 2009/11/13:: rabartl: After moving to a full RCPNode tracing and lookup
1200 // model, I had to how modifying functions like insert(...) and erase(...)
1201 // work which have active iterators controled by the client and yet need to
1202 // allow the structure of the container change. The way these troublesome
1203 // functions work is that first the raw std::vector iterator is extracted.
1204 // The function vec(true, true) then deletes the strong iterators but there is
1205 // still a weak ArrayRCP object that is owned by the client which is being
1206 // passed into this function. The issue is that the design of ArrayRCP is
1207 // such that the RCPNode object is not removed but instead remains in order to
1208 // perform runtime checking.
1209 
1210 
1211 template<typename T> inline
1212 typename Array<T>::iterator
1214 {
1215 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1216  // Assert a valid iterator and get vector iterator
1217  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1218  const difference_type i = position - begin();
1219 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1220  {
1221  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1222 #endif
1223  vec(true, true).insert(raw_poss, x);
1224 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1225  } // must unlock mutex_lock before calling begin() which will lock again
1226 #endif
1227  return begin() + i;
1228 #else
1229  return vec_.insert(position, x);
1230 #endif
1231 }
1232 
1233 
1234 template<typename T> inline
1236 {
1237 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1238  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1239 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1240  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1241 #endif
1242  vec(true, true).insert(raw_poss, n, x);
1243 #else
1244  vec_.insert(position, n, x);
1245 #endif
1246 }
1247 
1248 
1249 template<typename T> template<typename InputIterator> inline
1250 void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
1251 {
1252 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1253  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1254 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1255  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1256 #endif
1257  vec(true, true).insert(raw_poss, first, last);
1258 #else
1259  vec_.insert(position, first, last);
1260 #endif
1261 }
1262 
1263 
1264 template<typename T> inline
1265 typename Array<T>::iterator
1267 {
1268 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1269  assertNotNull();
1270  // Assert a valid iterator and get vector iterator
1271  const typename std::vector<T>::iterator raw_poss = raw_position(position);
1272  const difference_type i = position - begin();
1273 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1274  {
1275  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1276 #endif
1277  vec(true, true).erase(raw_poss);
1278 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1279  } // must unlock mutex_lock before call begin() or dead lock on second call
1280 #endif
1281  return begin() + i;
1282 #else
1283  return vec_.erase(position);
1284 #endif
1285 }
1286 
1287 
1288 template<typename T> inline
1289 typename Array<T>::iterator
1291 {
1292 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1293  if (empty()) {
1294  TEUCHOS_ASSERT(first == begin());
1295  TEUCHOS_ASSERT(last == end());
1296  return end();
1297  }
1298  assertNotNull();
1299  // Assert a valid iterator and get vector iterator
1300  const typename std::vector<T>::iterator raw_first = raw_position(first);
1301  const typename std::vector<T>::iterator raw_last = raw_position(last);
1302  const difference_type i = first - begin();
1303 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1304  {
1305  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1306 #endif
1307  vec(true,true).erase(raw_first,raw_last);
1308 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1309  } // must unlock mutex_lock before call begin() or dead lock on second call
1310 #endif
1311  return begin() + i;
1312 #else
1313  return vec_.erase(first,last);
1314 #endif
1315 }
1316 
1317 
1318 template<typename T> inline
1320 {
1321 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1322  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1323 #endif
1324  vec(true).swap(x.vec());
1325 }
1326 
1327 
1328 template<typename T> inline
1330 {
1331 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1332  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1333 #endif
1334  vec(true).clear();
1335 }
1336 
1337 
1338 // Non-standard functions
1339 
1340 
1341 template<typename T> inline
1343 {
1344  this->push_back(x);
1345  return *this;
1346 }
1347 
1348 
1349 template<typename T> inline
1350 void Array<T>::remove(int i)
1351 {
1352 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1353  assertIndex(i);
1354 #endif
1355  // Erase the i-th element of this array.
1356  this->erase( this->begin() + i );
1357 }
1358 
1359 
1360 template<typename T> inline
1361 int Array<T>::length() const
1362 {
1363  return static_cast<int> (this->size ());
1364 }
1365 
1366 
1367 template<typename T> inline
1368 std::string Array<T>::toString() const
1369 {
1370  return (*this)().toString(); // Use ArrayView<T>::toString()
1371 }
1372 
1373 
1374 template<typename T> inline
1376 {
1377 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1378  return true;
1379 #else
1380  return false;
1381 #endif
1382 }
1383 
1384 
1385 template<typename T> inline
1387 {
1388  return ( size() ? &(*this)[0] : nullptr );
1389 }
1390 
1391 template<typename T> inline
1393 {
1394  return ( size() ? &(*this)[0] : nullptr );
1395 }
1396 
1397 template<typename T> inline
1398 const T* Array<T>::getRawPtr() const
1399 {
1400  return ( size() ? &(*this)[0] : nullptr );
1401 }
1402 
1403 template<typename T> inline
1404 const T* Array<T>::data() const
1405 {
1406  return ( size() ? &(*this)[0] : nullptr );
1407 }
1408 
1409 // Conversions to and from std::vector
1410 
1411 
1412 template<typename T> inline
1413 Array<T>::Array( const std::vector<T> &v ) :
1414 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1415  vec_(new std::vector<T>(v))
1416 #else
1417  vec_(v)
1418 #endif
1419 {}
1420 
1421 
1422 template<typename T> inline
1423 std::vector<T> Array<T>::toVector() const
1424 {
1425  if (!size())
1426  return std::vector<T>();
1427  std::vector<T> v(begin(),end());
1428  return v;
1429 }
1430 
1431 
1432 template<typename T> inline
1433 Array<T>& Array<T>::operator=( const std::vector<T> &v )
1434 {
1435 #ifdef USE_MUTEX_LOCK_FOR_ARRAY
1436  std::lock_guard<std::mutex> lockGuard(mutex_lock);
1437 #endif
1438  vec(true) = v;
1439  return *this;
1440 }
1441 
1442 
1443 // Views
1444 
1445 
1446 template<typename T> inline
1448 {
1449  if (size_in) {
1450 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1451  return ArrayView<T>(this->begin().persistingView(offset, size_in));
1452 #else
1453  return arrayView( &vec()[offset], size_in );
1454 #endif
1455  }
1456  return Teuchos::null;
1457 }
1458 
1459 
1460 template<typename T> inline
1462 {
1463  if (size_in) {
1464 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1465  return ArrayView<const T>(this->begin().persistingView(offset, size_in));
1466 #else
1467  return arrayView( &vec()[offset], size_in );
1468 #endif
1469  }
1470  return Teuchos::null;
1471  // NOTE: Above, we use a different implementation to call the const version
1472  // of begin() instead of the non-const version. This sets up a different
1473  // ArrayRCP object that gets checked.
1474 }
1475 
1476 
1477 template<typename T> inline
1479 {
1480  return view(offset, size_in);
1481 }
1482 
1483 
1484 template<typename T> inline
1486 {
1487  return view(offset, size_in);
1488 }
1489 
1490 
1491 template<typename T> inline
1493 {
1494  if (!size())
1495  return null;
1496  return this->view(0, size());
1497 }
1498 
1499 
1500 template<typename T> inline
1502 {
1503  if (!size())
1504  return null;
1505  return this->view(0, size());
1506 }
1507 
1508 
1509 template<typename T> inline
1511 {
1512  return this->operator()();
1513 }
1514 
1515 
1516 template<typename T> inline
1518 {
1519  return this->operator()();
1520 }
1521 
1522 
1523 // private
1524 
1525 
1526 template<typename T>
1527 std::vector<T>&
1528 Array<T>::vec( bool isStructureBeingModified, bool activeIter )
1529 {
1530 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1531  (void)activeIter;
1532  if (isStructureBeingModified) {
1533  // Give up my ArrayRCPs used for iterator access since the array we be
1534  // getting modifed! Any clients that have views through weak pointers
1535  // better not touch them!
1536 
1537  // Note that in debug mode these are mutex protected - the mutex should
1538  // always be locked when this function is called with
1539  // isStructureBeingModified true
1540  extern_arcp_ = null;
1541  extern_carcp_ = null;
1542  }
1543  return *vec_;
1544 #else
1545  // get rid of "unused parameter" warnings
1546  (void)isStructureBeingModified;
1547  (void)activeIter;
1548  return vec_;
1549 #endif
1550 }
1551 
1552 
1553 template<typename T> inline
1554 const std::vector<T>&
1556 {
1557 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1558  return *vec_;
1559 #else
1560  return vec_;
1561 #endif
1562 }
1563 
1564 
1565 template<typename T> inline
1566 typename std::vector<T>::iterator
1568 {
1569 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1570  const iterator first = this->begin();
1571  const iterator last = this->end();
1573  !(first <= position && position <= last), DanglingReferenceError,
1574  "Error, this iterator is no longer valid for this Aray!"
1575  );
1576  // Note, above operator<=(...) functions will throw
1577  // IncompatibleIteratorsError if the iterators do not share the same
1578  // RCP_node object!
1579  return vec_->begin() + (position - this->begin());
1580 #else
1581  return position;
1582 #endif
1583 }
1584 
1585 
1586 template<typename T> inline
1588 {
1590  !( 0 <= i && i < size() ), RangeError,
1591  "Array<T>::assertIndex(i): i="<<i<<" out of range [0, "<< size() << ")"
1592  );
1593 }
1594 
1595 
1596 template<typename T> inline
1598 {
1600  !size(), NullReferenceError,
1601  typeName(*this)<<"::assertNotNull(): "
1602  "Error, the array has size zero!"
1603  );
1604 }
1605 
1606 
1607 } // namespace Teuchos
1608 
1609 
1610 // Nonmember functions
1611 
1612 
1613 template<typename T> inline
1614 bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
1615 { return (a1.vec() == a2.vec()); }
1616 
1617 
1618 template<typename T> inline
1619 bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
1620 { return (a1.vec() != a2.vec()); }
1621 
1622 
1623 template<typename T> inline
1624 void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
1625 { a1.swap(a2); }
1626 
1627 
1628 template<typename T> inline
1629 bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
1630 { return (a1.vec() < a2.vec()); }
1631 
1632 
1633 template<typename T> inline
1634 bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
1635 { return (a1.vec() <= a2.vec()); }
1636 
1637 
1638 template<typename T> inline
1639 bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
1640 { return (a1.vec() > a2.vec()); }
1641 
1642 
1643 template<typename T> inline
1644 bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
1645 { return (a1.vec() >= a2.vec()); }
1646 
1647 
1648 template<typename T> inline
1649 std::ostream& Teuchos::operator<<(
1650  std::ostream& os, const Array<T>& array
1651  )
1652 {
1653  return os << Teuchos::toString(array);
1654 }
1655 
1656 
1657 template<typename T> inline
1658 int Teuchos::hashCode(const Array<T>& array)
1659 {
1660  int rtn = hashCode(array.length());
1661  for (int i=0; i<array.length(); i++)
1662  {
1663  rtn += hashCode(array[i]);
1664  }
1665  if (rtn < 0)
1666  {
1667  /* Convert the largest -ve int to zero and -1 to
1668  * std::numeric_limits<int>::max()
1669  * */
1670  size_t maxIntBeforeWrap = std::numeric_limits<int>::max();
1671  maxIntBeforeWrap ++;
1672  rtn += maxIntBeforeWrap;
1673  }
1674  return rtn;
1675 }
1676 
1677 
1678 template<typename T> inline
1679 std::vector<T> Teuchos::createVector( const Array<T> &a )
1680 {
1681  return a.toVector();
1682 }
1683 
1684 
1685 template<typename T> inline
1686 std::string Teuchos::toString(const Array<T>& array)
1687 {
1688  return array.toString();
1689 }
1690 
1691 
1692 template<typename T>
1694 Teuchos::fromStringToArray(const std::string& arrayStr)
1695 {
1696  const std::string str = Utils::trimWhiteSpace(arrayStr);
1697  std::istringstream iss(str);
1699  ( str[0]!='{' || str[str.length()-1] != '}' )
1700  ,InvalidArrayStringRepresentation
1701  ,"Error, the std::string:\n"
1702  "----------\n"
1703  <<str<<
1704  "\n----------\n"
1705  "is not a valid array represntation!"
1706  );
1707  char c;
1708  c = iss.get(); // Read initial '{'
1709  TEUCHOS_TEST_FOR_EXCEPT(c!='{'); // Should not throw!
1710  // Now we are ready to begin reading the entries of the array!
1711  Array<T> a;
1712  while( !iss.eof() ) {
1713  // Get the basic entry std::string
1714  std::string entryStr;
1715  std::getline(iss,entryStr,','); // Get next entry up to ,!
1716  // ToDo: Above, we might have to be careful to look for the opening and
1717  // closing of parentheses in order not to pick up an internal ',' in the
1718  // middle of an entry (for a std::complex number for instance). The above
1719  // implementation assumes that there will be no commas in the middle of
1720  // the std::string representation of an entry. This is certainly true for
1721  // the types bool, int, float, and double.
1722  //
1723  // Trim whitespace from beginning and end
1724  entryStr = Utils::trimWhiteSpace(entryStr);
1726  0 == entryStr.length(),
1727  InvalidArrayStringRepresentation,
1728  "Error, the std::string:\n"
1729  "----------\n"
1730  <<str<<
1731  "\n----------\n"
1732  "is not a valid array represntation because it has an empty array entry!"
1733  );
1734  // Remove the final '}' if this is the last entry and we did not
1735  // actually terminate the above getline(...) on ','
1736  bool found_end = false;
1737  if(entryStr[entryStr.length()-1]=='}') {
1738  entryStr = entryStr.substr(0,entryStr.length()-1);
1739  found_end = true;
1740  if( entryStr.length()==0 && a.size()==0 )
1741  return a; // This is the empty array "{}" (with any spaces in it!)
1742  }
1743  // Finally we can convert the entry and add it to the array!
1744  std::istringstream entryiss(entryStr);
1745  T entry;
1746  Teuchos::extractDataFromISS( entryiss, entry );
1747  // ToDo: We may need to define a traits class to allow us to specialized
1748  // how conversion from a std::string to a object is done!
1749  a.push_back(entry);
1750  // At the end of the loop body here, if we have reached the last '}'
1751  // then the input stream iss should be empty and iss.eof() should be
1752  // true, so the loop should terminate. We put an std::exception test here
1753  // just in case something has gone wrong.
1755  found_end && !iss.eof()
1756  ,InvalidArrayStringRepresentation
1757  ,"Error, the std::string:\n"
1758  "----------\n"
1759  <<str<<
1760  "\n----------\n"
1761  "is not a valid array represntation!"
1762  );
1763  }
1764  return a;
1765 }
1766 
1767 
1768 #endif // TEUCHOS_ARRAY_H
static std::string concreteName(const Array< T > &)
Dangling reference error exception class.
Null reference error exception class.
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.
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.
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.
std::vector< T >::iterator raw_position(iterator position)
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...
std::vector< T > vec_
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.
void assertNotNull() const
bool operator!=(const Allocator< T > &a_t, const Allocator< U > &a_u)
Return ! (a_t == a_u) (see above).
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.
const std::vector< T > & vec() const
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.
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::string toString() const
Convert an Array to an std::string
std::vector< T > & vec(bool isStructureBeingModified=false, bool activeIter=false)
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
InvalidArrayStringRepresentation(const std::string &what_arg)
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.
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)
Range error exception class.
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)
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...
void assertIndex(size_type i) const
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...