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//
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
235 typedef Teuchos_Ordinal Ordinal;
241 typedef typename std::vector<T>::value_type value_type;
243 typedef typename std::vector<T>::pointer pointer;
245 typedef typename std::vector<T>::const_pointer const_pointer;
247 typedef typename std::vector<T>::reference reference;
249 typedef typename std::vector<T>::const_reference const_reference;
251 typedef typename std::vector<T>::allocator_type allocator_type;
252
253#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
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>
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>
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);
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();
367 inline void insert(iterator position, size_type n, const value_type& x);
369 template<typename InputIterator>
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
508 RCP<std::vector<T> > vec_;
511#ifdef USE_MUTEX_LOCK_FOR_ARRAY
512 mutable std::mutex mutex_lock; // this mutex provides thread safe debugging for the vec_, extern_arcp_, extern_carcp_
513#endif
514#else
515 std::vector<T> vec_;
516#endif
517
518 inline std::vector<T>& vec(
519 bool isStructureBeingModified = false,
520 bool activeIter = false
521 );
522
523 inline const std::vector<T>& vec() const;
524
525 inline typename std::vector<T>::iterator
526 raw_position( iterator position );
527
528 inline void assertIndex(size_type i) const;
529
530 inline void assertNotNull() const;
531
532};
533
534
540template<class T>
542{
543 if ( is_null(v) || !v->size() )
544 return null;
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;
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
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>
700
706template<typename T>
707std::istringstream& operator>> (std::istringstream& in, Array<T>& array){
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>
770class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<Array<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);
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
809 vec_(rcp(new std::vector<T>(n,value)))
810#else
811 vec_(n, value)
812#endif
813{}
814
815
816template<typename T> inline
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
829 vec_(rcp(new std::vector<T>(first, last)))
830#else
831 vec_(first, last)
832#endif
833{}
834
835
836template<typename T> inline
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
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
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
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
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 ) :
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
1471
1472
1473template<typename T> inline
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>&
1518{
1519#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
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
1537 return vec_;
1538#endif
1539}
1540
1541
1542template<typename T> inline
1543const std::vector<T>&
1544Array<T>::vec() const
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
1556Array<T>::raw_position( iterator position )
1557{
1558#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1559 const iterator first = this->begin();
1560 const iterator last = this->end();
1562 !(first <= position && position <= last), DanglingReferenceError,
1563 "Error, this iterator is no longer valid for this Aray!"
1564 );
1565 // Note, above operator<=(...) functions will throw
1566 // IncompatibleIteratorsError if the iterators do not share the same
1567 // RCP_node object!
1568 return vec_->begin() + (position - this->begin());
1569#else
1570 return position;
1571#endif
1572}
1573
1574
1575template<typename T> inline
1576void Array<T>::assertIndex(size_type i) const
1577{
1579 !( 0 <= i && i < size() ), RangeError,
1580 "Array<T>::assertIndex(i): i="<<i<<" out of range [0, "<< size() << ")"
1581 );
1582}
1583
1584
1585template<typename T> inline
1586void Array<T>::assertNotNull() const
1587{
1589 !size(), NullReferenceError,
1590 typeName(*this)<<"::assertNotNull(): "
1591 "Error, the array has size zero!"
1592 );
1593}
1594
1595
1596} // namespace Teuchos
1597
1598
1599// Nonmember functions
1600
1601
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.
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)
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.
RCP(ENull null_arg=null)
Initialize RCP<T> to NULL.
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.