Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
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
62namespace Teuchos {
63
68class InvalidArrayStringRepresentation : public std::logic_error
69{public:InvalidArrayStringRepresentation(const std::string& what_arg) : std::logic_error(what_arg) {}};
70
71
72template<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
88template<typename T> inline
89bool operator==( const Array<T> &a1, const Array<T> &a2 );
90
91
96template<typename T> inline
97bool operator!=( const Array<T> &a1, const Array<T> &a2 );
98
99
104template<typename T> inline
105void swap( Array<T> &a1, Array<T> &a2 );
106
107
112template<typename T> inline
113bool operator<( const Array<T> &a1, const Array<T> &a2 );
114
115
120template<typename T> inline
121bool operator<=( const Array<T> &a1, const Array<T> &a2 );
122
123
128template<typename T> inline
129bool operator>( const Array<T> &a1, const Array<T> &a2 );
130
131
136template<typename T> inline
137bool operator>=( const Array<T> &a1, const Array<T> &a2 );
138
139
193template<typename T>
194class Array
195{
196public:
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
255 typedef ArrayRCP<T> iterator;
259 typedef std::reverse_iterator<iterator> reverse_iterator;
261 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
262#else
264 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
309
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;
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);
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
455
470
475
480
486
492
496 inline operator ArrayView<T>();
497
501 inline operator ArrayView<const T>() const;
502
504
505private:
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
527
528 inline void assertIndex(size_type i) const;
529
530 inline void assertNotNull() const;
531
532};
533
534
540template<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
557template<class T>
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
574template<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
592template<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
617template<typename T>
618std::ostream& operator<<(std::ostream& os, const Array<T>& array);
619
620
625template<typename T> inline
626int hashCode(const Array<T>& array);
627
628
635template<typename T> inline
636std::vector<T> createVector( const Array<T> &a );
637
638
643template<typename T>
644std::string toString(const Array<T>& array);
645
646
698template<typename T>
699Array<T> fromStringToArray(const std::string& arrayStr);
700
706template<typename T>
707std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
708 array = fromStringToArray<T>(in.str());
709 return in;
710}
711
717template<typename T> inline
718void extractDataFromISS( std::istringstream& iss, T& data )
719{
720 iss >> data; // Assumes type has operator>>(...) defined!
721}
722
729inline
730void 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
747inline
749 return "Array(*)";
750}
751
752
753
769template<typename T>
771public:
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
792namespace Teuchos {
793
794
795// All constructors
796
797
798template<typename T> inline
800#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
801 : vec_(rcp(new std::vector<T>()))
802#endif
803{}
804
805
806template<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
816template<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
826template<typename T> template<typename InputIterator> inline
827Array<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
836template<typename T> inline
838{}
839
840
841template<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
851template<typename T>
852template<int N>
853inline
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
863template<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
877template<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
887template<typename T> template<typename InputIterator> inline
888void 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
897template<typename T> inline
898typename 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
921template<typename T> inline
922typename Array<T>::iterator
924{
925#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
926 return begin() + size();
927#else
928 return vec().end();
929#endif
930}
931
932template<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
965template<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
977template<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
989template<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
1001template<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
1013template<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
1025template<typename T> inline
1026typename Array<T>::size_type
1028{
1029 return vec().size();
1030}
1031
1032
1033template<typename T> inline
1034typename Array<T>::size_type
1036{
1037 return std::numeric_limits<size_type>::max();
1038}
1039
1040
1041template<typename T> inline
1042void
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
1052template<typename T> inline
1053typename Array<T>::size_type
1055{
1056 return vec().capacity();
1057}
1058
1059
1060template<typename T> inline
1062{
1063 return vec().empty();
1064}
1065
1066
1067template<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
1077template<typename T> inline
1078typename Array<T>::reference
1080{
1081#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1082 assertIndex(i);
1083#endif
1084 return vec()[i];
1085}
1086
1087
1088template<typename T> inline
1091{
1092#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1093 assertIndex(i);
1094#endif
1095 return vec()[i];
1096}
1097
1098
1099template<typename T> inline
1100typename Array<T>::reference
1102{
1103#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1104 assertIndex(i);
1105#endif
1106 return vec().at(i);
1107}
1108
1109
1110template<typename T> inline
1113{
1114#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1115 assertIndex(i);
1116#endif
1117 return vec().at(i);
1118}
1119
1120
1121template<typename T> inline
1122typename Array<T>::reference
1124{
1125#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1126 assertNotNull();
1127#endif
1128 return vec().front();
1129}
1130
1131
1132template<typename T> inline
1135{
1136#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1137 assertNotNull();
1138#endif
1139 return vec().front();
1140}
1141
1142
1143template<typename T> inline
1144typename Array<T>::reference
1146{
1147#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1148 assertNotNull();
1149#endif
1150 return vec().back();
1151}
1152
1153
1154template<typename T> inline
1157{
1158#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1159 assertNotNull();
1160#endif
1161 return vec().back();
1162}
1163
1164
1165template<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
1175template<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
1200template<typename T> inline
1201typename 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
1223template<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
1238template<typename T> template<typename InputIterator> inline
1239void 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
1253template<typename T> inline
1254typename 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
1277template<typename T> inline
1278typename 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
1307template<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
1317template<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
1330template<typename T> inline
1332{
1333 this->push_back(x);
1334 return *this;
1335}
1336
1337
1338template<typename T> inline
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
1349template<typename T> inline
1351{
1352 return static_cast<int> (this->size ());
1353}
1354
1355
1356template<typename T> inline
1357std::string Array<T>::toString() const
1358{
1359 return (*this)().toString(); // Use ArrayView<T>::toString()
1360}
1361
1362
1363template<typename T> inline
1365{
1366#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1367 return true;
1368#else
1369 return false;
1370#endif
1371}
1372
1373
1374template<typename T> inline
1376{
1377 return ( size() ? &(*this)[0] : nullptr );
1378}
1379
1380template<typename T> inline
1382{
1383 return ( size() ? &(*this)[0] : nullptr );
1384}
1385
1386template<typename T> inline
1387const T* Array<T>::getRawPtr() const
1388{
1389 return ( size() ? &(*this)[0] : nullptr );
1390}
1391
1392template<typename T> inline
1393const T* Array<T>::data() const
1394{
1395 return ( size() ? &(*this)[0] : nullptr );
1396}
1397
1398// Conversions to and from std::vector
1399
1400
1401template<typename T> inline
1402Array<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
1411template<typename T> inline
1412std::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
1421template<typename T> inline
1422Array<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
1435template<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
1449template<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
1466template<typename T> inline
1468{
1469 return view(offset, size_in);
1470}
1471
1472
1473template<typename T> inline
1475{
1476 return view(offset, size_in);
1477}
1478
1479
1480template<typename T> inline
1482{
1483 if (!size())
1484 return null;
1485 return this->view(0, size());
1486}
1487
1488
1489template<typename T> inline
1491{
1492 if (!size())
1493 return null;
1494 return this->view(0, size());
1495}
1496
1497
1498template<typename T> inline
1500{
1501 return this->operator()();
1502}
1503
1504
1505template<typename T> inline
1507{
1508 return this->operator()();
1509}
1510
1511
1512// private
1513
1514
1515template<typename T>
1516std::vector<T>&
1517Array<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
1542template<typename T> inline
1543const std::vector<T>&
1545{
1546#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1547 return *vec_;
1548#else
1549 return vec_;
1550#endif
1551}
1552
1553
1554template<typename T> inline
1555typename 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
1575template<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
1585template<typename T> inline
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
1602template<typename T> inline
1603bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
1604{ return (a1.vec() == a2.vec()); }
1605
1606
1607template<typename T> inline
1608bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
1609{ return (a1.vec() != a2.vec()); }
1610
1611
1612template<typename T> inline
1613void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
1614{ a1.swap(a2); }
1615
1616
1617template<typename T> inline
1618bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
1619{ return (a1.vec() < a2.vec()); }
1620
1621
1622template<typename T> inline
1623bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
1624{ return (a1.vec() <= a2.vec()); }
1625
1626
1627template<typename T> inline
1628bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
1629{ return (a1.vec() > a2.vec()); }
1630
1631
1632template<typename T> inline
1633bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
1634{ return (a1.vec() >= a2.vec()); }
1635
1636
1637template<typename T> inline
1638std::ostream& Teuchos::operator<<(
1639 std::ostream& os, const Array<T>& array
1640 )
1641{
1642 return os << Teuchos::toString(array);
1643}
1644
1645
1646template<typename T> inline
1647int 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
1667template<typename T> inline
1668std::vector<T> Teuchos::createVector( const Array<T> &a )
1669{
1670 return a.toVector();
1671}
1672
1673
1674template<typename T> inline
1675std::string Teuchos::toString(const Array<T>& array)
1676{
1677 return array.toString();
1678}
1679
1680
1681template<typename T>
1683Teuchos::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
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
TEUCHOS_ORDINAL_TYPE Teuchos_Ordinal
#define TEUCHOSCORE_LIB_DLL_EXPORT
Defines basic traits returning the name of a type in a portable and readable way.
A utilities class for Teuchos.
Reference-counted smart pointer for managing arrays.
ArrayRCP< T > arcpFromArray(Array< T > &a)
Wrap an Array<T> object as a non-owning ArrayRCP<T> object.
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP<Array<T> > object as an ArrayRCP<T> object.
ArrayRCP< const T > arcpFromArray(const Array< T > &a)
Wrap a const Array<T> object as a non-owning ArrayRCP<T> object.
ArrayRCP< const T > arcp(const RCP< const Array< T > > &v)
Wrap a RCP<const Array<T> > object as an ArrayRCP<const T> object.
Nonowning array view.
iterator end() const
Return an iterator to past the end of the array of data.
iterator begin() const
Return an iterator to beginning of the array of data.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
const_reference back() const
void reserve(size_type n)
reference back()
iterator insert(iterator position, const value_type &x)
std::vector< T > vec_
Array(const ArrayView< const T > &a)
Create an Array which is a deep copy of the given ArrayView.
const_iterator end() const
Array(const std::vector< T > &v)
Copy constructor from an std::vector (does a deep copy).
friend void swap(Array< T2 > &a1, Array< T2 > &a2)
iterator begin()
T * getRawPtr()
Return a raw pointer to beginning of array or NULL if unsized.
Ordinal difference_type
The type of the difference between two size_type values.
void assertIndex(size_type i) const
int length() const
Return number of elements in the array.
const_iterator begin() const
ArrayView< const T > operator()() const
Return an const ArrayView of *this.
Array(const Array< T > &x)
Copy constructor (does a deep copy).
Array & operator=(const Array< T > &a)
Assignment operator (does a deep copy).
bool operator<(const Array< T > &a1, const Array< T > &a2)
Less-than operator.
Array()
Default constructor; creates an empty Array.
void assign(InputIterator first, InputIterator last)
void insert(iterator position, size_type n, const value_type &x)
std::string toString(const Array< T > &array)
Convert an array to a string representation.
void swap(Array &x)
size_type size() const
std::vector< T > & vec(bool isStructureBeingModified=false, bool activeIter=false)
friend bool Teuchos::operator!=(const Array< T2 > &a1, const Array< T2 > &a2)
std::vector< T >::iterator iterator
The type of a forward iterator.
std::vector< T >::allocator_type allocator_type
The allocator type; for compatibility with std::vector.
std::vector< T >::const_pointer const_pointer
The type of a const pointer to T; for compatibility with std::vector.
std::vector< T >::const_reference const_reference
The type of a const reference to T; for compatibility with std::vector.
const_reverse_iterator rend() const
const std::vector< T > & vec() const
reference front()
std::ostream & operator<<(std::ostream &os, const Array< T > &array)
Write an Array to an ostream.
Ordinal size_type
The type of Array sizes and capacities.
std::vector< T >::reverse_iterator reverse_iterator
The type of a reverse iterator.
iterator erase(iterator first, iterator last)
void assign(size_type n, const value_type &val)
std::vector< T >::reference reference
The type of a reference to T; for compatibility with std::vector.
reference at(size_type i)
ArrayView< const T > view(size_type offset, size_type size) const
Return const view of a contiguous range of elements.
size_type capacity() const
const_reference at(size_type i) const
bool operator>=(const Array< T > &a1, const Array< T > &a2)
Greater-than-or-equal operator.
std::vector< T >::iterator raw_position(iterator position)
Array & operator=(const std::vector< T > &v)
Assignment operator for std::vector.
Array(size_type n, const value_type &value=value_type())
Create an array of length n, and fill it with the given value.
Array< T > fromStringToArray(const std::string &arrayStr)
Converts from std::string representation (as created by toString()) back into the array object.
ArrayView< T > view(size_type offset, size_type size)
Return non-const view of a contiguous range of elements.
void remove(int i)
Remove the i-th element from the array, with optional boundschecking.
ArrayView< const T > operator()(size_type offset, size_type size) const
Return a const view of a contiguous range of elements (calls view(offset,size)).
bool empty() const
const_reference operator[](size_type i) const
void push_back(const value_type &x)
const_reference front() const
std::vector< T >::const_reverse_iterator const_reverse_iterator
The type of a const reverse iterator.
void extractDataFromISS(std::istringstream &iss, T &data)
Extracts data from an istringstream object.
const_reverse_iterator rbegin() const
bool operator>(const Array< T > &a1, const Array< T > &a2)
Greater-than operator.
ArrayView< T > operator()(size_type offset, size_type size)
Return a non-const view of a contiguous range of elements (calls view(offset,size)).
static bool hasBoundsChecking()
Return true if Array has been compiled with boundschecking on.
int hashCode(const Array< T > &array)
Return the hash code.
std::vector< T > toVector() const
Explicit copy conversion to an std::vector.
const T * data() const
Return a const raw pointer to beginning of array.
std::string toString() const
Convert an Array to an std::string
bool operator!=(const Array< T > &a1, const Array< T > &a2)
Non-equality operator.
void insert(iterator position, InputIterator first, InputIterator last)
reverse_iterator rend()
bool operator<=(const Array< T > &a1, const Array< T > &a2)
Less-than-or-equal operator.
std::vector< T > createVector(const Array< T > &a)
Copy conversion to an std::vector.
const T * getRawPtr() const
Return a const raw pointer to beginning of array or NULL if unsized.
reverse_iterator rbegin()
bool operator==(const Array< T > &a1, const Array< T > &a2)
Equality operator.
size_type max_size() const
T * data()
Return a raw pointer to beginning of array.
ArrayView< T > operator()()
Return an non-const ArrayView of *this.
Array(InputIterator first, InputIterator last)
Create an array, and fill it with values from the given iterator range.
std::vector< T >::pointer pointer
The type of a pointer to T; for compatibility with std::vector.
void resize(size_type new_size, const value_type &x=value_type())
std::vector< T >::value_type value_type
The type of an entry of the Array; for compatibility with std::vector.
Teuchos_Ordinal Ordinal
The type of indices.
std::vector< T >::const_iterator const_iterator
The type of a const forward iterator.
reference operator[](size_type i)
void assertNotNull() const
void extractDataFromISS(std::istringstream &iss, std::string &data)
Extracts std::string data from an istringstream object.
std::string getArrayTypeNameTraitsFormat()
Get the format that is used for the specialization of the TypeName traits class for Array.
~Array()
Destructor.
Array(const Tuple< T, N > &t)
Copy constructor from the given Tuple.
Array< T > & append(const T &x)
Add a new entry at the end of the array.
void swap(Array< T > &a1, Array< T > &a2)
Non-member swap (specializes default std version).
iterator erase(iterator position)
Dangling reference error exception class.
InvalidArrayStringRepresentation(const std::string &what_arg)
Null reference error exception class.
Smart reference counting pointer class for automatic garbage collection.
Range error exception class.
Statically sized simple array (tuple) class.
static std::string concreteName(const Array< T > &)
Default traits class that just returns typeid(T).name().
static std::string trimWhiteSpace(const std::string &str)
Trim whitespace from beginning and end of std::string.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
#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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
bool operator>=(BigUInt< n > const &a, BigUInt< n > const &b)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
std::ostream & operator<<(std::ostream &os, BigUInt< n > a)
bool operator<(BigUInt< n > const &a, BigUInt< n > const &b)
std::string toString(const HashSet< Key > &h)
std::istringstream & operator>>(std::istringstream &in, TwoDArray< T > &array)
bool operator<=(BigUInt< n > const &a, BigUInt< n > const &b)
dependentList insert(myDepList.getEntryRCP(dependent1))
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)
bool operator>(BigUInt< n > const &a, BigUInt< n > const &b)