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
16
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>
256 inline Array(InputIterator first, InputIterator last);
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>
286 inline void assign(InputIterator first, InputIterator last);
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);
322 inline const_reference at(size_type i) const;
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();
336 inline iterator insert(iterator position, const value_type& x);
338 inline void insert(iterator position, size_type n, const value_type& x);
340 template<typename InputIterator>
341 inline void insert(iterator position, InputIterator first, InputIterator last);
343 inline iterator erase(iterator position);
345 inline iterator erase(iterator first, iterator last);
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_;
480 mutable ArrayRCP<T> extern_arcp_;
481 mutable ArrayRCP<const T> extern_carcp_;
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
597int hashCode(const Array<T>& array);
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>
670Array<T> fromStringToArray(const std::string& arrayStr);
671
677template<typename T>
678std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
679 array = fromStringToArray<T>(in.str());
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.
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);
748 return prefix+TypeNameTraits<T>::name()+postFix;
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
779#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
780 vec_(rcp(new std::vector<T>(n,value)))
781#else
782 vec_(n, value)
783#endif
784{}
785
786
787template<typename T> inline
789#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
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
798Array<T>::Array(InputIterator first, InputIterator last) :
799#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
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
867void Array<T>::assign(InputIterator first, InputIterator last)
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
932 extern_carcp_ = extern_arcp_.create_weak();
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
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
1218void Array<T>::insert(iterator position, InputIterator first, InputIterator last)
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
1366const T* Array<T>::getRawPtr() const
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 ) :
1382#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
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
1447{
1448 return view(offset, size_in);
1449}
1450
1451
1452template<typename T> inline
1454{
1455 return view(offset, size_in);
1456}
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>&
1496Array<T>::vec( bool isStructureBeingModified, bool activeIter )
1497{
1498#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1499 (void)activeIter;
1500 if (isStructureBeingModified) {
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
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] != '}' )
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(),
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.
Reference-counted smart pointer for managing arrays.
ArrayRCP< T > arcpWithEmbeddedObjPostDestroy(T *p, typename ArrayRCP< T >::size_type lowerOffset, typename ArrayRCP< T >::size_type size, const Embedded &embedded, bool owns_mem=true)
ArrayRCP(ENull null_arg=null)
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.
ArrayView< T > arrayView(T *p, typename ArrayView< T >::size_type size)
Construct a const or non-const view to const or non-const data.
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)
bool operator>(const Array< T > &a1, const Array< T > &a2)
Greater-than operator.
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).
bool operator!=(const Array< T > &a1, const Array< T > &a2)
Non-equality operator.
Array & operator=(const Array< T > &a)
Assignment operator (does a deep copy).
void assign(InputIterator first, InputIterator last)
void insert(iterator position, size_type n, const value_type &x)
void swap(Array &x)
size_type size() const
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.
bool operator<(const Array< T > &a1, const Array< T > &a2)
Less-than operator.
std::vector< T >::const_reference const_reference
The type of a const reference to T; for compatibility with std::vector.
int hashCode(const Array< T > &array)
Return the hash code.
bool operator==(const Array< T > &a1, const Array< T > &a2)
Equality operator.
const_reverse_iterator rend() const
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
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)
std::vector< T > createVector(const Array< T > &a)
Copy conversion to an std::vector.
Array(std::initializer_list< T > list)
Create an array with braced initialization.
const_reference front() const
bool operator>=(const Array< T > &a1, const Array< T > &a2)
Greater-than-or-equal operator.
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
std::ostream & operator<<(std::ostream &os, const Array< T > &array)
Write an Array to an ostream.
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.
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.
void insert(iterator position, InputIterator first, InputIterator last)
reverse_iterator rend()
const T * getRawPtr() const
Return a const raw pointer to beginning of array or NULL if unsized.
reverse_iterator rbegin()
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)
bool operator<=(const Array< T > &a1, const Array< T > &a2)
Less-than-or-equal operator.
void extractDataFromISS(std::istringstream &iss, std::string &data)
Extracts std::string data from an istringstream object.
void swap(Array< T > &a1, Array< T > &a2)
Non-member swap (specializes default std version).
std::string getArrayTypeNameTraitsFormat()
Get the format that is used for the specialization of the TypeName traits class for Array.
std::string toString(const Array< T > &array)
Convert an array to a string representation.
~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.
iterator erase(iterator position)
Dangling reference error exception class.
Null reference error exception class.
Smart reference counting pointer class for automatic garbage collection.
Range error exception class.
Statically sized simple array (tuple) class.
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.
bool operator!=(const any &a, const any &b)
Returns true if two any objects do not have the same value.
#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.