Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_Array.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Teuchos: Common Tools Package
4//
5// Copyright 2004 NTESS and the Teuchos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef TEUCHOS_ARRAY_H
11#define TEUCHOS_ARRAY_H
12
18#include "Teuchos_Assert.hpp"
20#include "Teuchos_ArrayRCP.hpp"
21#include "Teuchos_Tuple.hpp"
22#include "Teuchos_Utils.hpp"
23#include "Teuchos_Assert.hpp"
24
25#if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_ARRAY_BOUNDSCHECK) && defined(HAVE_TEUCHOS_THREAD_SAFE) && !defined(REMOVE_THREAD_PROTECTION_FOR_ARRAY)
26#include <mutex>
27#define USE_MUTEX_LOCK_FOR_ARRAY
28#endif
29
30namespace Teuchos {
31
36class InvalidArrayStringRepresentation : public std::logic_error
37{public:InvalidArrayStringRepresentation(const std::string& what_arg) : std::logic_error(what_arg) {}};
38
39
40template<typename T> class Array;
41
42
43// 2007/11/30: rabartl: Below, I had to move the initial declaration of these
44// non-member template functions outside of the Array class since the Sun
45// compiler on sass9000 would not accept this. However, this did work on a
46// number of other compilers such a g++, Intel C++ etc. The old in-class
47// non-member friend definition is clearly ISO 98 C++ as shown in Item 46 of
48// "Effective C++: Third Edition". This is not the end of the world but this
49// is something to remember for this platform.
50
51
56template<typename T> inline
57bool operator==( const Array<T> &a1, const Array<T> &a2 );
58
59
64template<typename T> inline
65bool operator!=( const Array<T> &a1, const Array<T> &a2 );
66
67
72template<typename T> inline
73void swap( Array<T> &a1, Array<T> &a2 );
74
75
80template<typename T> inline
81bool operator<( const Array<T> &a1, const Array<T> &a2 );
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
105bool operator>=( const Array<T> &a1, const Array<T> &a2 );
106
107
161template<typename T>
162class Array
163{
164public:
165
166 // 2007/11/30: rabartl: Below, note that the only reason that these
167 // functions are declared as friends is so that the compiler will do
168 // automatic type conversions as described in "Effective C++: Third Edition"
169 // Item 46.
170
172 template<typename T2>
173 friend bool Teuchos::operator==( const Array<T2> &a1, const Array<T2> &a2 );
174
176 template<typename T2>
177 friend bool Teuchos::operator!=( const Array<T2> &a1, const Array<T2> &a2 );
178
180 template<typename T2>
181 friend void swap( Array<T2> &a1, Array<T2> &a2 );
182
184 template<typename T2>
185 friend bool Teuchos::operator<( const Array<T2> &a1, const Array<T2> &a2 );
186
188 template<typename T2>
189 friend bool Teuchos::operator<=( const Array<T2> &a1, const Array<T2> &a2 );
190
192 template<typename T2>
193 friend bool Teuchos::operator>( const Array<T2> &a1, const Array<T2> &a2 );
194
196 template<typename T2>
197 friend bool Teuchos::operator>=( const Array<T2> &a1, const Array<T2> &a2 );
198
201
203 typedef Teuchos_Ordinal Ordinal;
209 typedef typename std::vector<T>::value_type value_type;
211 typedef typename std::vector<T>::pointer pointer;
213 typedef typename std::vector<T>::const_pointer const_pointer;
215 typedef typename std::vector<T>::reference reference;
217 typedef typename std::vector<T>::const_reference const_reference;
219 typedef typename std::vector<T>::allocator_type allocator_type;
220
221#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
223 typedef ArrayRCP<T> iterator;
227 typedef std::reverse_iterator<iterator> reverse_iterator;
229 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
230#else
232 typedef typename std::vector<T>::iterator iterator;
234 typedef typename std::vector<T>::const_iterator const_iterator;
236 typedef typename std::vector<T>::reverse_iterator reverse_iterator;
238 typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
239#endif
240
242
244
246 inline Array();
247
249 inline explicit Array(size_type n, const value_type& value = value_type());
250
252 inline Array(const Array<T>& x);
253
255 template<typename InputIterator>
257
259 inline Array(const ArrayView<const T>& a);
260
262 template<int N>
263 inline Array(const Tuple<T,N>& t);
264
266 inline Array(std::initializer_list<T> list);
267
269 inline ~Array();
270
272 inline Array& operator=(const Array<T>& a);
273
275
280
281
283 inline void assign(size_type n, const value_type& val);
285 template<typename InputIterator>
288 inline iterator begin();
290 inline iterator end();
292 inline const_iterator begin() const;
294 inline const_iterator end() const;
304 inline size_type size() const;
306 inline size_type max_size() const;
308 inline void resize(size_type new_size, const value_type& x = value_type());
310 inline size_type capacity() const;
312 inline bool empty() const;
314 inline void reserve(size_type n);
324 inline reference front();
326 inline const_reference front() const;
328 inline reference back();
330 inline const_reference back() const;
332 inline void push_back(const value_type& x);
334 inline void pop_back();
338 inline void insert(iterator position, size_type n, const value_type& x);
340 template<typename InputIterator>
347 inline void swap(Array& x);
349 inline void clear();
350
352
354
359 inline Array<T>& append(const T& x);
360
364 inline void remove(int i);
365
370 inline int length() const;
371
373 inline std::string toString() const;
374
376 inline static bool hasBoundsChecking();
377
379 inline T* getRawPtr();
380
384 inline T* data();
385
387 inline const T* getRawPtr() const;
388
392 inline const T* data() const;
393
395
397
399 inline Array( const std::vector<T> &v );
400
402 inline std::vector<T> toVector() const;
403
405 inline Array& operator=( const std::vector<T> &v );
406
408
410
411
426
441
446
451
457
463
467 inline operator ArrayView<T>();
468
472 inline operator ArrayView<const T>() const;
473
475
476private:
477
478#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
479 RCP<std::vector<T> > vec_;
482#ifdef USE_MUTEX_LOCK_FOR_ARRAY
483 mutable std::mutex mutex_lock; // this mutex provides thread safe debugging for the vec_, extern_arcp_, extern_carcp_
484#endif
485#else
486 std::vector<T> vec_;
487#endif
488
489 inline std::vector<T>& vec(
490 bool isStructureBeingModified = false,
491 bool activeIter = false
492 );
493
494 inline const std::vector<T>& vec() const;
495
496 inline typename std::vector<T>::iterator
497 raw_position( iterator position );
498
499 inline void assertIndex(size_type i) const;
500
501 inline void assertNotNull() const;
502
503};
504
505
511template<class T>
513{
514 if ( is_null(v) || !v->size() )
515 return null;
517 &(*v)[0], 0, v->size(),
518 v, false
519 );
520}
521
522
528template<class T>
530{
531 if ( is_null(v) || !v->size() )
532 return null;
534 &(*v)[0], 0, v->size(),
535 v, false
536 );
537}
538
539
545template<class T>
547{
548 if (a.size() == 0)
549 return null;
550#ifdef TEUCHOS_DEBUG
551 return a.begin(); // Catch dangling reference!
552#else
553 return arcp(a.getRawPtr(), 0, a.size(), false);
554#endif
555}
556
557
563template<class T>
565{
566 if (a.size() == 0)
567 return null;
568#ifdef TEUCHOS_DEBUG
569 return a.begin(); // Catch dangling reference!
570#else
571 return arcp(a.getRawPtr(), 0, a.size(), false);
572#endif
573}
574
575
588template<typename T>
589std::ostream& operator<<(std::ostream& os, const Array<T>& array);
590
591
596template<typename T> inline
598
599
606template<typename T> inline
607std::vector<T> createVector( const Array<T> &a );
608
609
614template<typename T>
615std::string toString(const Array<T>& array);
616
617
669template<typename T>
671
677template<typename T>
678std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
680 return in;
681}
682
688template<typename T> inline
689void extractDataFromISS( std::istringstream& iss, T& data )
690{
691 iss >> data; // Assumes type has operator>>(...) defined!
692}
693
700inline
701void extractDataFromISS( std::istringstream& iss, std::string& data )
702{
703 // grab unformatted string.
704 data = iss.str();
705 // remove white space from beginning and end of string.
706 data = Utils::trimWhiteSpace(data);
707}
708
718inline
720 return "Array(*)";
721}
722
723
724
740template<typename T>
741class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<Array<T> > {
742public:
743 static std::string name(){
744 std::string formatString = getArrayTypeNameTraitsFormat();
745 size_t starPos = formatString.find("*");
746 std::string prefix = formatString.substr(0,starPos);
747 std::string postFix = formatString.substr(starPos+1);
749 }
750 static std::string concreteName(const Array<T>&)
751 { return name(); }
752};
753
754
755} // namespace Teuchos
756
757
758//
759// Implementation
760//
761
762
763namespace Teuchos {
764
765
766// All constructors
767
768
769template<typename T> inline
771#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
772 : vec_(rcp(new std::vector<T>()))
773#endif
774{}
775
776
777template<typename T> inline
780 vec_(rcp(new std::vector<T>(n,value)))
781#else
782 vec_(n, value)
783#endif
784{}
785
786
787template<typename T> inline
790 vec_(rcp(new std::vector<T>(*x.vec_)))
791#else
792 vec_(x.vec_)
793#endif
794{}
795
796
797template<typename T> template<typename InputIterator> inline
800 vec_(rcp(new std::vector<T>(first, last)))
801#else
802 vec_(first, last)
803#endif
804{}
805
806
807template<typename T> inline
810
811
812template<typename T> inline
814#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
815 : vec_(rcp(new std::vector<T>()))
816#endif
817{
818 insert(begin(), a.begin(), a.end());
819}
820
821
822template<typename T>
823template<int N>
824inline
826#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
827 : vec_(rcp(new std::vector<T>()))
828#endif
829{
830 insert(begin(), t.begin(), t.end());
831}
832
833template<typename T> inline
834Array<T>::Array(std::initializer_list<T> a)
835#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
836 : vec_(rcp(new std::vector<T>(a)))
837#else
838 : vec_(a)
839#endif
840{}
841
842template<typename T> inline
844{
845#ifdef USE_MUTEX_LOCK_FOR_ARRAY
846 std::lock_guard<std::mutex> lockGuard(mutex_lock);
847#endif
848 vec(true) = a.vec();
849 return *this;
850}
851
852
853// Other std::vector functions
854
855
856template<typename T> inline
858{
859#ifdef USE_MUTEX_LOCK_FOR_ARRAY
860 std::lock_guard<std::mutex> lockGuard(mutex_lock);
861#endif
862 vec(true).assign(n,val);
863}
864
865
866template<typename T> template<typename InputIterator> inline
868{
869#ifdef USE_MUTEX_LOCK_FOR_ARRAY
870 std::lock_guard<std::mutex> lockGuard(mutex_lock);
871#endif
872 vec(true).assign(first,last);
873}
874
875
876template<typename T> inline
877typename Array<T>::iterator
879{
880#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
881
882#ifdef USE_MUTEX_LOCK_FOR_ARRAY
883 std::lock_guard<std::mutex> lockGuard(mutex_lock);
884#endif
885
886 if (is_null(extern_arcp_)) {
887 // Here we must use the same RCP to avoid creating two unrelated RCPNodes!
888 extern_arcp_ = arcp(vec_); // Will be null if vec_ is sized!
889 }
890 // Returning a weak pointer will help to catch dangling references but still
891 // keep the same behavior as optimized code.
892
893 return extern_arcp_.create_weak();
894#else
895 return vec().begin();
896#endif
897}
898
899
900template<typename T> inline
901typename Array<T>::iterator
903{
904#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
905 return begin() + size();
906#else
907 return vec().end();
908#endif
909}
910
911template<typename T> inline
914{
915#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
916
917#ifdef USE_MUTEX_LOCK_FOR_ARRAY
918 std::lock_guard<std::mutex> lockGuard(mutex_lock);
919#endif
920 if (is_null(extern_carcp_)) {
921 // Note that this used to call the non-const begin() function above
922 // I've moved that code here to make the mutex locking more transparent and
923 // prevent the need to structure something awkward to avoid double locks
924 // The original line of code was this:
925 // extern_carcp_ = const_cast<Array<T>*>(this)->begin();
926 // Now replaced by the following code which mirrors the above begin() call
927 if (is_null(extern_arcp_)) {
928 extern_arcp_ = arcp(vec_);
929 }
930 // note that we call create_weak() twice, first on the non-const and then
931 // below on the const - this preserves the original design exactly
933 }
934
935 // Returning a weak pointer will help to catch dangling references but still
936 // keep the same behavior as optimized code.
937 return extern_carcp_.create_weak();
938#else
939 return vec().begin();
940#endif
941}
942
943
944template<typename T> inline
947{
948#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
949 return begin() + size();
950#else
951 return vec().end();
952#endif
953}
954
955
956template<typename T> inline
959{
960#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
961 return reverse_iterator(end());
962#else
963 return vec().rbegin();
964#endif
965}
966
967
968template<typename T> inline
971{
972#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
973 return reverse_iterator(begin());
974#else
975 return vec().rend();
976#endif
977}
978
979
980template<typename T> inline
983{
984#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
985 return const_reverse_iterator(end());
986#else
987 return vec().rbegin();
988#endif
989}
990
991
992template<typename T> inline
995{
996#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
997 return const_reverse_iterator(begin());
998#else
999 return vec().rend();
1000#endif
1001}
1002
1003
1004template<typename T> inline
1005typename Array<T>::size_type
1007{
1008 return vec().size();
1009}
1010
1011
1012template<typename T> inline
1013typename Array<T>::size_type
1015{
1016 return std::numeric_limits<size_type>::max();
1017}
1018
1019
1020template<typename T> inline
1021void
1023{
1024#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1025 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1026#endif
1027 vec(true).resize(new_size,x);
1028}
1029
1030
1031template<typename T> inline
1032typename Array<T>::size_type
1034{
1035 return vec().capacity();
1036}
1037
1038
1039template<typename T> inline
1041{
1042 return vec().empty();
1043}
1044
1045
1046template<typename T> inline
1048{
1049#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1050 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1051#endif
1052 vec(true).reserve(n);
1053}
1054
1055
1056template<typename T> inline
1057typename Array<T>::reference
1059{
1060#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1061 assertIndex(i);
1062#endif
1063 return vec()[i];
1064}
1065
1066
1067template<typename T> inline
1070{
1071#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1072 assertIndex(i);
1073#endif
1074 return vec()[i];
1075}
1076
1077
1078template<typename T> inline
1079typename Array<T>::reference
1081{
1082#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1083 assertIndex(i);
1084#endif
1085 return vec().at(i);
1086}
1087
1088
1089template<typename T> inline
1092{
1093#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1094 assertIndex(i);
1095#endif
1096 return vec().at(i);
1097}
1098
1099
1100template<typename T> inline
1101typename Array<T>::reference
1103{
1104#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1105 assertNotNull();
1106#endif
1107 return vec().front();
1108}
1109
1110
1111template<typename T> inline
1114{
1115#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1116 assertNotNull();
1117#endif
1118 return vec().front();
1119}
1120
1121
1122template<typename T> inline
1123typename Array<T>::reference
1125{
1126#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1127 assertNotNull();
1128#endif
1129 return vec().back();
1130}
1131
1132
1133template<typename T> inline
1136{
1137#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1138 assertNotNull();
1139#endif
1140 return vec().back();
1141}
1142
1143
1144template<typename T> inline
1146{
1147#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1148 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1149#endif
1150 vec(true).push_back(x);
1151}
1152
1153
1154template<typename T> inline
1156{
1157#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1158 assertNotNull();
1159#endif
1160#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1161 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1162#endif
1163 vec(true).pop_back();
1164}
1165
1166
1167// 2009/11/13:: rabartl: After moving to a full RCPNode tracing and lookup
1168// model, I had to how modifying functions like insert(...) and erase(...)
1169// work which have active iterators controled by the client and yet need to
1170// allow the structure of the container change. The way these troublesome
1171// functions work is that first the raw std::vector iterator is extracted.
1172// The function vec(true, true) then deletes the strong iterators but there is
1173// still a weak ArrayRCP object that is owned by the client which is being
1174// passed into this function. The issue is that the design of ArrayRCP is
1175// such that the RCPNode object is not removed but instead remains in order to
1176// perform runtime checking.
1177
1178
1179template<typename T> inline
1180typename Array<T>::iterator
1182{
1183#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1184 // Assert a valid iterator and get vector iterator
1185 const typename std::vector<T>::iterator raw_poss = raw_position(position);
1186 const difference_type i = position - begin();
1187#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1188 {
1189 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1190#endif
1191 vec(true, true).insert(raw_poss, x);
1192#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1193 } // must unlock mutex_lock before calling begin() which will lock again
1194#endif
1195 return begin() + i;
1196#else
1197 return vec_.insert(position, x);
1198#endif
1199}
1200
1201
1202template<typename T> inline
1204{
1205#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1206 const typename std::vector<T>::iterator raw_poss = raw_position(position);
1207#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1208 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1209#endif
1210 vec(true, true).insert(raw_poss, n, x);
1211#else
1212 vec_.insert(position, n, x);
1213#endif
1214}
1215
1216
1217template<typename T> template<typename InputIterator> inline
1219{
1220#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1221 const typename std::vector<T>::iterator raw_poss = raw_position(position);
1222#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1223 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1224#endif
1225 vec(true, true).insert(raw_poss, first, last);
1226#else
1227 vec_.insert(position, first, last);
1228#endif
1229}
1230
1231
1232template<typename T> inline
1233typename Array<T>::iterator
1235{
1236#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1237 assertNotNull();
1238 // Assert a valid iterator and get vector iterator
1239 const typename std::vector<T>::iterator raw_poss = raw_position(position);
1240 const difference_type i = position - begin();
1241#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1242 {
1243 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1244#endif
1245 vec(true, true).erase(raw_poss);
1246#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1247 } // must unlock mutex_lock before call begin() or dead lock on second call
1248#endif
1249 return begin() + i;
1250#else
1251 return vec_.erase(position);
1252#endif
1253}
1254
1255
1256template<typename T> inline
1257typename Array<T>::iterator
1259{
1260#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1261 if (empty()) {
1262 TEUCHOS_ASSERT(first == begin());
1263 TEUCHOS_ASSERT(last == end());
1264 return end();
1265 }
1266 assertNotNull();
1267 // Assert a valid iterator and get vector iterator
1268 const typename std::vector<T>::iterator raw_first = raw_position(first);
1269 const typename std::vector<T>::iterator raw_last = raw_position(last);
1270 const difference_type i = first - begin();
1271#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1272 {
1273 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1274#endif
1275 vec(true,true).erase(raw_first,raw_last);
1276#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1277 } // must unlock mutex_lock before call begin() or dead lock on second call
1278#endif
1279 return begin() + i;
1280#else
1281 return vec_.erase(first,last);
1282#endif
1283}
1284
1285
1286template<typename T> inline
1288{
1289#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1290 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1291#endif
1292 vec(true).swap(x.vec());
1293}
1294
1295
1296template<typename T> inline
1298{
1299#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1300 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1301#endif
1302 vec(true).clear();
1303}
1304
1305
1306// Non-standard functions
1307
1308
1309template<typename T> inline
1311{
1312 this->push_back(x);
1313 return *this;
1314}
1315
1316
1317template<typename T> inline
1319{
1320#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1321 assertIndex(i);
1322#endif
1323 // Erase the i-th element of this array.
1324 this->erase( this->begin() + i );
1325}
1326
1327
1328template<typename T> inline
1330{
1331 return static_cast<int> (this->size ());
1332}
1333
1334
1335template<typename T> inline
1336std::string Array<T>::toString() const
1337{
1338 return (*this)().toString(); // Use ArrayView<T>::toString()
1339}
1340
1341
1342template<typename T> inline
1344{
1345#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1346 return true;
1347#else
1348 return false;
1349#endif
1350}
1351
1352
1353template<typename T> inline
1355{
1356 return ( size() ? &(*this)[0] : nullptr );
1357}
1358
1359template<typename T> inline
1361{
1362 return ( size() ? &(*this)[0] : nullptr );
1363}
1364
1365template<typename T> inline
1367{
1368 return ( size() ? &(*this)[0] : nullptr );
1369}
1370
1371template<typename T> inline
1372const T* Array<T>::data() const
1373{
1374 return ( size() ? &(*this)[0] : nullptr );
1375}
1376
1377// Conversions to and from std::vector
1378
1379
1380template<typename T> inline
1381Array<T>::Array( const std::vector<T> &v ) :
1383 vec_(new std::vector<T>(v))
1384#else
1385 vec_(v)
1386#endif
1387{}
1388
1389
1390template<typename T> inline
1391std::vector<T> Array<T>::toVector() const
1392{
1393 if (!size())
1394 return std::vector<T>();
1395 std::vector<T> v(begin(),end());
1396 return v;
1397}
1398
1399
1400template<typename T> inline
1401Array<T>& Array<T>::operator=( const std::vector<T> &v )
1402{
1403#ifdef USE_MUTEX_LOCK_FOR_ARRAY
1404 std::lock_guard<std::mutex> lockGuard(mutex_lock);
1405#endif
1406 vec(true) = v;
1407 return *this;
1408}
1409
1410
1411// Views
1412
1413
1414template<typename T> inline
1416{
1417 if (size_in) {
1418#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1419 return ArrayView<T>(this->begin().persistingView(offset, size_in));
1420#else
1421 return arrayView( &vec()[offset], size_in );
1422#endif
1423 }
1424 return Teuchos::null;
1425}
1426
1427
1428template<typename T> inline
1430{
1431 if (size_in) {
1432#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1433 return ArrayView<const T>(this->begin().persistingView(offset, size_in));
1434#else
1435 return arrayView( &vec()[offset], size_in );
1436#endif
1437 }
1438 return Teuchos::null;
1439 // NOTE: Above, we use a different implementation to call the const version
1440 // of begin() instead of the non-const version. This sets up a different
1441 // ArrayRCP object that gets checked.
1442}
1443
1444
1445template<typename T> inline
1450
1451
1452template<typename T> inline
1457
1458
1459template<typename T> inline
1461{
1462 if (!size())
1463 return null;
1464 return this->view(0, size());
1465}
1466
1467
1468template<typename T> inline
1470{
1471 if (!size())
1472 return null;
1473 return this->view(0, size());
1474}
1475
1476
1477template<typename T> inline
1479{
1480 return this->operator()();
1481}
1482
1483
1484template<typename T> inline
1486{
1487 return this->operator()();
1488}
1489
1490
1491// private
1492
1493
1494template<typename T>
1495std::vector<T>&
1497{
1498#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1501 // Give up my ArrayRCPs used for iterator access since the array we be
1502 // getting modifed! Any clients that have views through weak pointers
1503 // better not touch them!
1504
1505 // Note that in debug mode these are mutex protected - the mutex should
1506 // always be locked when this function is called with
1507 // isStructureBeingModified true
1508 extern_arcp_ = null;
1509 extern_carcp_ = null;
1510 }
1511 return *vec_;
1512#else
1513 // get rid of "unused parameter" warnings
1514 (void)isStructureBeingModified;
1515 (void)activeIter;
1516 return vec_;
1517#endif
1518}
1519
1520
1521template<typename T> inline
1522const std::vector<T>&
1523Array<T>::vec() const
1524{
1525#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1526 return *vec_;
1527#else
1528 return vec_;
1529#endif
1530}
1531
1532
1533template<typename T> inline
1534typename std::vector<T>::iterator
1535Array<T>::raw_position( iterator position )
1536{
1537#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1538 const iterator first = this->begin();
1539 const iterator last = this->end();
1541 !(first <= position && position <= last), DanglingReferenceError,
1542 "Error, this iterator is no longer valid for this Aray!"
1543 );
1544 // Note, above operator<=(...) functions will throw
1545 // IncompatibleIteratorsError if the iterators do not share the same
1546 // RCP_node object!
1547 return vec_->begin() + (position - this->begin());
1548#else
1549 return position;
1550#endif
1551}
1552
1553
1554template<typename T> inline
1555void Array<T>::assertIndex(size_type i) const
1556{
1558 !( 0 <= i && i < size() ), RangeError,
1559 "Array<T>::assertIndex(i): i="<<i<<" out of range [0, "<< size() << ")"
1560 );
1561}
1562
1563
1564template<typename T> inline
1565void Array<T>::assertNotNull() const
1566{
1568 !size(), NullReferenceError,
1569 typeName(*this)<<"::assertNotNull(): "
1570 "Error, the array has size zero!"
1571 );
1572}
1573
1574
1575} // namespace Teuchos
1576
1577
1578// Nonmember functions
1579
1580
1581template<typename T> inline
1582bool Teuchos::operator==( const Array<T> &a1, const Array<T> &a2 )
1583{ return (a1.vec() == a2.vec()); }
1584
1585
1586template<typename T> inline
1587bool Teuchos::operator!=( const Array<T> &a1, const Array<T> &a2 )
1588{ return (a1.vec() != a2.vec()); }
1589
1590
1591template<typename T> inline
1592void Teuchos::swap( Array<T> &a1, Array<T> &a2 )
1593{ a1.swap(a2); }
1594
1595
1596template<typename T> inline
1597bool Teuchos::operator<( const Array<T> &a1, const Array<T> &a2 )
1598{ return (a1.vec() < a2.vec()); }
1599
1600
1601template<typename T> inline
1602bool Teuchos::operator<=( const Array<T> &a1, const Array<T> &a2 )
1603{ return (a1.vec() <= a2.vec()); }
1604
1605
1606template<typename T> inline
1607bool Teuchos::operator>( const Array<T> &a1, const Array<T> &a2 )
1608{ return (a1.vec() > a2.vec()); }
1609
1610
1611template<typename T> inline
1612bool Teuchos::operator>=( const Array<T> &a1, const Array<T> &a2 )
1613{ return (a1.vec() >= a2.vec()); }
1614
1615
1616template<typename T> inline
1617std::ostream& Teuchos::operator<<(
1618 std::ostream& os, const Array<T>& array
1619 )
1620{
1621 return os << Teuchos::toString(array);
1622}
1623
1624
1625template<typename T> inline
1626int Teuchos::hashCode(const Array<T>& array)
1627{
1628 int rtn = hashCode(array.length());
1629 for (int i=0; i<array.length(); i++)
1630 {
1631 rtn += hashCode(array[i]);
1632 }
1633 if (rtn < 0)
1634 {
1635 /* Convert the largest -ve int to zero and -1 to
1636 * std::numeric_limits<int>::max()
1637 * */
1638 size_t maxIntBeforeWrap = std::numeric_limits<int>::max();
1639 maxIntBeforeWrap ++;
1640 rtn += maxIntBeforeWrap;
1641 }
1642 return rtn;
1643}
1644
1645
1646template<typename T> inline
1647std::vector<T> Teuchos::createVector( const Array<T> &a )
1648{
1649 return a.toVector();
1650}
1651
1652
1653template<typename T> inline
1654std::string Teuchos::toString(const Array<T>& array)
1655{
1656 return array.toString();
1657}
1658
1659
1660template<typename T>
1662Teuchos::fromStringToArray(const std::string& arrayStr)
1663{
1664 const std::string str = Utils::trimWhiteSpace(arrayStr);
1665 std::istringstream iss(str);
1667 ( str[0]!='{' || str[str.length()-1] != '}' )
1668 ,InvalidArrayStringRepresentation
1669 ,"Error, the std::string:\n"
1670 "----------\n"
1671 <<str<<
1672 "\n----------\n"
1673 "is not a valid array represntation!"
1674 );
1675 char c;
1676 c = iss.get(); // Read initial '{'
1677 TEUCHOS_TEST_FOR_EXCEPT(c!='{'); // Should not throw!
1678 // Now we are ready to begin reading the entries of the array!
1679 Array<T> a;
1680 while( !iss.eof() ) {
1681 // Get the basic entry std::string
1682 std::string entryStr;
1683 std::getline(iss,entryStr,','); // Get next entry up to ,!
1684 // ToDo: Above, we might have to be careful to look for the opening and
1685 // closing of parentheses in order not to pick up an internal ',' in the
1686 // middle of an entry (for a std::complex number for instance). The above
1687 // implementation assumes that there will be no commas in the middle of
1688 // the std::string representation of an entry. This is certainly true for
1689 // the types bool, int, float, and double.
1690 //
1691 // Trim whitespace from beginning and end
1692 entryStr = Utils::trimWhiteSpace(entryStr);
1694 0 == entryStr.length(),
1695 InvalidArrayStringRepresentation,
1696 "Error, the std::string:\n"
1697 "----------\n"
1698 <<str<<
1699 "\n----------\n"
1700 "is not a valid array represntation because it has an empty array entry!"
1701 );
1702 // Remove the final '}' if this is the last entry and we did not
1703 // actually terminate the above getline(...) on ','
1704 bool found_end = false;
1705 if(entryStr[entryStr.length()-1]=='}') {
1706 entryStr = entryStr.substr(0,entryStr.length()-1);
1707 found_end = true;
1708 if( entryStr.length()==0 && a.size()==0 )
1709 return a; // This is the empty array "{}" (with any spaces in it!)
1710 }
1711 // Finally we can convert the entry and add it to the array!
1712 std::istringstream entryiss(entryStr);
1713 T entry;
1714 Teuchos::extractDataFromISS( entryiss, entry );
1715 // ToDo: We may need to define a traits class to allow us to specialized
1716 // how conversion from a std::string to a object is done!
1717 a.push_back(entry);
1718 // At the end of the loop body here, if we have reached the last '}'
1719 // then the input stream iss should be empty and iss.eof() should be
1720 // true, so the loop should terminate. We put an std::exception test here
1721 // just in case something has gone wrong.
1723 found_end && !iss.eof()
1724 ,InvalidArrayStringRepresentation
1725 ,"Error, the std::string:\n"
1726 "----------\n"
1727 <<str<<
1728 "\n----------\n"
1729 "is not a valid array represntation!"
1730 );
1731 }
1732 return a;
1733}
1734
1735
1736#endif // TEUCHOS_ARRAY_H
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Defines basic traits returning the name of a type in a portable and readable way.
A utilities class for Teuchos.
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.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
const_reference back() const
void reserve(size_type n)
iterator insert(iterator position, const value_type &x)
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)
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.
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
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
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.
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)
Array(std::initializer_list< T > list)
Create an array with braced initialization.
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 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)
Smart reference counting pointer class for automatic garbage collection.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
void swap(RCP< T > &r_ptr)
Swap the contents with some other RCP object.
bool is_null() const
Returns true if the underlying pointer is null.
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
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.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.