Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_ArrayRCP.hpp
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_RCP_HPP
43#define TEUCHOS_ARRAY_RCP_HPP
44
45
46#include "Teuchos_ArrayRCPDecl.hpp"
47#include "Teuchos_ArrayView.hpp"
48#include "Teuchos_Assert.hpp"
49#include "Teuchos_dyn_cast.hpp"
50#include "Teuchos_as.hpp"
51
52
53namespace Teuchos {
54
55
56// Helper code (not for general clients)
57
58
59template<class T> inline
60RCPNode* ArrayRCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in )
61{
62 return new RCPNodeTmpl<T,DeallocArrayDelete<T> >(
63 p, DeallocArrayDelete<T>(), has_ownership_in
64 );
65}
66
67
68template<class T, class Dealloc_T>
69inline
70RCPNode* ArrayRCP_createNewDeallocRCPNodeRawPtr(
71 T* p, Dealloc_T dealloc, bool has_ownership_in
72 )
73{
74 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in);
75}
76
77
78template<class T2, class T1>
79class ArcpReinterpretCastEmbeddedObj
80{
81public:
82 typedef T2 ptr_t;
83 ArcpReinterpretCastEmbeddedObj()
84 : arcp_pod_(null)
85 {}
86 ArcpReinterpretCastEmbeddedObj(const ArrayRCP<T1> &arcp_pod)
87 : arcp_pod_(arcpCloneNode(arcp_pod)) // Unique reference count!
88 {}
89 // NOTE: The default copy constructor is allowed and does the right thing
90 ~ArcpReinterpretCastEmbeddedObj()
91 { freeMemory(); }
92 ArcpReinterpretCastEmbeddedObj&
93 operator=(const ArcpReinterpretCastEmbeddedObj& arceo)
94 {
95 assert(is_null(arceo.arcp_pod_)); // Can only be a catestrophic programming error!
96 freeMemory();
97 return *this;
98 }
99private:
100 ArrayRCP<T1> arcp_pod_;
101 void freeMemory()
102 {
103 typedef typename ArrayRCP<T2>::iterator itr_t;
104 if (arcp_pod_.strong_count() == 1) {
105 ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(arcp_pod_);
106 for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) {
107 itr->~T2();
108 }
109 arcp_pod_ = null;
110 }
111 }
112};
113
114
115// Constructors/Destructors/Initializers
116
117template<class T> inline
119 : ptr_(NULL), lowerOffset_(0), upperOffset_(-1)
120{}
121
122template<class T> inline
124 : ptr_(NULL), lowerOffset_(0), upperOffset_(-1)
125{}
126
127
128template<class T> inline
130 : ptr_(0), lowerOffset_(0), upperOffset_(-1)
131{
132 *this = arcp<T>(n);
133 std::fill_n(begin(), n, val);
134}
135
136template<class T> inline
137ArrayRCP<const T>::ArrayRCP (size_type n, const T& val)
138 : ptr_(0), lowerOffset_(0), upperOffset_(-1)
139{
140 // We can't call std::fill_n on a const T*, so we have to create a
141 // nonconst array first, fill it, and then convert to const.
144}
145
146
147template<class T> inline
151 )
152 : ptr_(p),
154 node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)),
155#endif // TEUCHOS_DEBUG
156 lowerOffset_(lowerOffset_in),
157 upperOffset_(size_in + lowerOffset_in - 1)
158{
159#ifdef TEUCHOS_DEBUG
160 if (p) {
162 if (!has_ownership_in && rcpNodeLookup==RCP_ENABLE_NODE_LOOKUP) {
164 }
165 if (existing_RCPNode) {
166 // Will not call add_new_RCPNode(...)
167 node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
168 }
169 else {
170 // Will call add_new_RCPNode(...)
171 RCPNodeThrowDeleter nodeDeleter(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in));
172 node_ = RCPNodeHandle(
176 );
178 }
179 }
180#else // NOT TEUCHOS_DEBUG
181 (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
182#endif // TEUCHOS_DEBUG
183}
184
185template<class T> inline
187ArrayRCP (const T* p, size_type lowerOffset_in, size_type size_in,
189 : ptr_(p),
191 node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)),
192#endif // TEUCHOS_DEBUG
193 lowerOffset_(lowerOffset_in),
194 upperOffset_(size_in + lowerOffset_in - 1)
195{
196#ifdef TEUCHOS_DEBUG
197 if (p) {
199 if (! has_ownership_in && rcpNodeLookup == RCP_ENABLE_NODE_LOOKUP) {
201 }
202 if (existing_RCPNode) {
203 // Will not call add_new_RCPNode(...)
204 node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
205 }
206 else {
207 // Will call add_new_RCPNode(...)
208 RCPNodeThrowDeleter nodeDeleter (ArrayRCP_createNewRCPNodeRawPtr (p, has_ownership_in));
209 node_ = RCPNodeHandle(
210 nodeDeleter.get (),
211 p, typeName (*p), concreteTypeName (*p),
213 );
215 }
217#else // NOT TEUCHOS_DEBUG
218 (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
219#endif // TEUCHOS_DEBUG
220}
221
222
223template<class T>
224template<class Dealloc_T>
225inline
229 )
230 : ptr_(p),
232 node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)),
233#endif // TEUCHOS_DEBUG
234 lowerOffset_(lowerOffset_in),
235 upperOffset_(size_in + lowerOffset_in - 1)
236{
237#ifdef TEUCHOS_DEBUG
238 if (p) {
239 node_ = RCPNodeHandle(
240 ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in),
243 //, RCP_STRONG, false
244 );
245 }
246#endif // TEUCHOS_DEBUG
247}
248
249template<class T>
250template<class Dealloc_T>
251inline
253 const T* p, size_type lowerOffset_in, size_type size_in,
254 Dealloc_T dealloc, bool has_ownership_in
255 )
256 : ptr_(p),
257#ifndef TEUCHOS_DEBUG
258 node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)),
259#endif // TEUCHOS_DEBUG
260 lowerOffset_(lowerOffset_in),
261 upperOffset_(size_in + lowerOffset_in - 1)
262{
263#ifdef TEUCHOS_DEBUG
264 if (p) {
265 node_ = RCPNodeHandle(
266 ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in),
269 //, RCP_STRONG, false
270 );
271 }
272#endif // TEUCHOS_DEBUG
273}
274
275
276template<class T> inline
278 :ptr_(r_ptr.ptr_),
279 node_(r_ptr.node_),
280 lowerOffset_(r_ptr.lowerOffset_),
281 upperOffset_(r_ptr.upperOffset_)
282{}
283
284template<class T> inline
286 :ptr_(r_ptr.ptr_),
287 node_(r_ptr.node_),
288 lowerOffset_(r_ptr.lowerOffset_),
289 upperOffset_(r_ptr.upperOffset_)
290{}
291
293template<class T> inline
295
296template<class T> inline
298
299
300template<class T> inline
302{
303 if( this == &r_ptr )
304 return *this; // Assignment to self
305 node_ = r_ptr.access_private_node(); // May throw in debug mode!
306 ptr_ = r_ptr.ptr_;
307 lowerOffset_ = r_ptr.lowerOffset_;
308 upperOffset_ = r_ptr.upperOffset_;
309 return *this;
310 // NOTE: It is critical that the assignment of ptr_ come *after* the
311 // assignment of node_ since node_ might throw an exception!
312}
313
314template<class T> inline
317{
318 if (this == &r_ptr) {
319 return *this; // Assignment to self
320 }
321 node_ = r_ptr.access_private_node (); // May throw in debug mode!
322 ptr_ = r_ptr.ptr_;
323 lowerOffset_ = r_ptr.lowerOffset_;
324 upperOffset_ = r_ptr.upperOffset_;
325 return *this;
326 // NOTE: The assignment of ptr_ MUST come after the assignment of
327 // node_, since that line of code might throw an exception!
329
330
331// Object/Pointer Access Functions
332
333
334template<class T> inline
336 return ptr_ == 0;
338
339template<class T> inline
340bool ArrayRCP<const T>::is_null() const {
341 return ptr_ == 0;
342}
343
344
345template<class T> inline
347{
348 debug_assert_valid_ptr();
349 debug_assert_in_range(0,1);
350 return ptr_;
351}
352
353template<class T> inline
354const T* ArrayRCP<const T>::operator->() const
355{
356 debug_assert_valid_ptr();
357 debug_assert_in_range(0,1);
358 return ptr_;
359}
361
362template<class T> inline
364{
365 debug_assert_valid_ptr();
366 debug_assert_in_range(0,1);
367 return *ptr_;
368}
369
370template<class T> inline
371const T& ArrayRCP<const T>::operator*() const
372{
373 debug_assert_valid_ptr();
374 debug_assert_in_range(0,1);
375 return *ptr_;
376}
377
378
379template<class T> inline
382 if (ptr_) {
383 debug_assert_valid_ptr();
384 debug_assert_in_range(0,1);
385 }
386 return ptr_;
387}
388
389template<class T> inline
390const T* ArrayRCP<const T>::get() const
392 if (ptr_) {
393 debug_assert_valid_ptr();
394 debug_assert_in_range(0,1);
395 }
396 return ptr_;
397}
398
399
400template<class T> inline
402 return this->get();
403}
404
405template<class T> inline
406const T* ArrayRCP<const T>::getRawPtr() const {
407 return this->get();
408}
409
410
411template<class T> inline
413{
414 debug_assert_valid_ptr();
415 debug_assert_in_range(offset,1);
416 return ptr_[offset];
417}
418
419template<class T> inline
420const T& ArrayRCP<const T>::operator[] (size_type offset) const
422 debug_assert_valid_ptr();
423 debug_assert_in_range(offset,1);
424 return ptr_[offset];
425}
426
427
428// Pointer Arithmetic Functions
429
430
431template<class T> inline
433{
434 debug_assert_valid_ptr();
435 ++ptr_;
436 --lowerOffset_;
437 --upperOffset_;
438 return *this;
439}
440
441template<class T> inline
443{
444 debug_assert_valid_ptr();
445 ++ptr_;
446 --lowerOffset_;
447 --upperOffset_;
448 return *this;
449}
450
451
452template<class T> inline
454{
455 debug_assert_valid_ptr();
456 ArrayRCP<T> r_ptr = *this;
457 ++(*this);
458 return r_ptr;
460
461template<class T> inline
463{
464 debug_assert_valid_ptr();
465 ArrayRCP<const T> r_ptr = *this;
466 ++(*this);
467 return r_ptr;
468}
469
470
471template<class T> inline
473{
474 debug_assert_valid_ptr();
475 --ptr_;
476 ++lowerOffset_;
477 ++upperOffset_;
478 return *this;
479}
480
481template<class T> inline
483{
484 debug_assert_valid_ptr();
485 --ptr_;
486 ++lowerOffset_;
487 ++upperOffset_;
488 return *this;
489}
490
491
492template<class T> inline
494{
495 debug_assert_valid_ptr();
496 ArrayRCP<T> r_ptr = *this;
497 --(*this);
498 return r_ptr;
499}
500
501template<class T> inline
503{
504 debug_assert_valid_ptr();
505 ArrayRCP<const T> r_ptr = *this;
506 --(*this);
507 return r_ptr;
508}
509
510
511template<class T> inline
514 debug_assert_valid_ptr();
515 ptr_ += offset;
516 lowerOffset_ -= offset;
517 upperOffset_ -= offset;
518 return *this;
519}
521template<class T> inline
524 debug_assert_valid_ptr();
525 ptr_ += offset;
526 lowerOffset_ -= offset;
527 upperOffset_ -= offset;
528 return *this;
530
531
532template<class T> inline
534{
535 debug_assert_valid_ptr();
536 ptr_ -= offset;
537 lowerOffset_ += offset;
538 upperOffset_ += offset;
539 return *this;
540}
541
542template<class T> inline
544{
545 debug_assert_valid_ptr();
546 ptr_ -= offset;
547 lowerOffset_ += offset;
548 upperOffset_ += offset;
549 return *this;
550}
551
552
553template<class T> inline
555{
556 ArrayRCP<T> r_ptr = *this;
557 r_ptr+=(offset);
558 return r_ptr;
559}
561template<class T> inline
563{
564 ArrayRCP<const T> r_ptr = *this;
565 r_ptr+=(offset);
566 return r_ptr;
567}
568
569
570template<class T> inline
573 ArrayRCP<T> r_ptr = *this;
574 r_ptr-=offset;
575 return r_ptr;
576}
577
578template<class T> inline
580{
581 ArrayRCP<const T> r_ptr = *this;
583 return r_ptr;
584}
585
586
587// Standard Container-Like Functions
588
589
590template<class T> inline
593 debug_assert_valid_ptr();
594#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
595 return *this;
596#else
597 return ptr_;
598#endif
600
601template<class T> inline
603{
604 debug_assert_valid_ptr();
605#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
606 return *this;
607#else
608 return ptr_;
609#endif
610}
611
612
613template<class T> inline
615{
616 debug_assert_valid_ptr();
617#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
618 return *this + (upperOffset_ + 1);
619#else
620 return ptr_ + (upperOffset_ + 1);
621#endif
622}
623
624template<class T> inline
626{
627 debug_assert_valid_ptr();
628#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
629 return *this + (upperOffset_ + 1);
630#else
631 return ptr_ + (upperOffset_ + 1);
632#endif
633}
634
635
636// ArrayRCP Views
637
638
639template<class T> inline
641{
642 if (ptr_) {
643 debug_assert_valid_ptr();
644 const T *cptr = ptr_; // Will not compile if not legal!
645 return ArrayRCP<const T>(cptr, lowerOffset_, size(), node_);
646 }
647 return null;
648}
649
650template<class T> inline
652 // Trivial implementation, since no need for conversion.
653 return *this;
654}
655
656
657template<class T> inline
660{
661 if (size_in == 0) {
662 return null;
663 }
664 debug_assert_valid_ptr();
665 debug_assert_in_range(lowerOffset_in, size_in);
666 ArrayRCP<T> ptr = *this;
667 ptr.ptr_ = ptr.ptr_ + lowerOffset_in;
668 ptr.lowerOffset_ = 0;
669 ptr.upperOffset_ = size_in - 1;
670 return ptr;
671}
673template<class T> inline
676{
677 if (size_in == 0) {
678 return null;
679 }
680 debug_assert_valid_ptr();
681 debug_assert_in_range(lowerOffset_in, size_in);
682 ArrayRCP<const T> ptr = *this;
683 ptr.ptr_ = ptr.ptr_ + lowerOffset_in;
684 ptr.lowerOffset_ = 0;
685 ptr.upperOffset_ = size_in - 1;
686 return ptr;
687}
688
689
690// Size and extent query functions
691
692
693template<class T> inline
696{
697 debug_assert_valid_ptr();
698 return lowerOffset_;
699}
700
701template<class T> inline
704{
705 debug_assert_valid_ptr();
706 return lowerOffset_;
708
709
710template<class T> inline
713{
714 debug_assert_valid_ptr();
715 return upperOffset_;
716}
717
718template<class T> inline
721{
722 debug_assert_valid_ptr();
723 return upperOffset_;
724}
725
726
727template<class T> inline
730{
731 debug_assert_valid_ptr();
732 return upperOffset_ - lowerOffset_ + 1;
733}
734
735template<class T> inline
738{
739 debug_assert_valid_ptr();
740 return upperOffset_ - lowerOffset_ + 1;
741}
742
743
744// ArrayView views
745
746
747template<class T> inline
750 if (size_in == 0) {
751 return null;
752 }
753 debug_assert_valid_ptr();
754 debug_assert_in_range(lowerOffset_in,size_in);
755#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
756 return ArrayView<T>(persistingView(lowerOffset_in, size_in).create_weak());
757#else
758 return arrayView(ptr_ + lowerOffset_in, size_in);
759#endif
760 // ToDo: Implement checks for dangling references!
761}
762
763template<class T> inline
766{
767 if (size_in == 0) {
768 return null;
769 }
770 debug_assert_valid_ptr();
771 debug_assert_in_range(lowerOffset_in,size_in);
772#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
773 return ArrayView<const T>(persistingView(lowerOffset_in, size_in).create_weak());
774#else
775 return arrayView(ptr_ + lowerOffset_in, size_in);
776#endif
777 // ToDo: Implement checks for dangling references!
778}
779
780
781template<class T> inline
786
787template<class T> inline
789ArrayRCP<const T>::operator() (size_type lowerOffset_in, size_type size_in) const
790{
791 return view (lowerOffset_in, size_in);
792}
793
794
795template<class T> inline
797{
798 if (size()) {
799 return view(lowerOffset_, size());
800 }
801 return null;
802}
803
804template<class T> inline
806{
807 if (size()) {
808 return view(lowerOffset_, size());
809 }
810 return null;
811}
812
813
814// Implicit conversions
815
816
817template<class T> inline
819{
820 if (size()) {
821 return ArrayRCP<const T>(ptr_, lowerOffset_, size(), node_);
822 }
823 return null;
824}
825// The above operator does not exist in the partial specialization for
826// const T, because it doesn't make sense in that case. (Many
827// compilers warn if one tries to implement that operator, because
828// that code would never get called.)
829
830
831// std::vector like functions
832//
833// Assignment (deep copy) doesn't make sense for the "const T" partial
834// specialization, so the assignment methods (assign() and deepCopy())
835// are omitted in that case.
836
837
838template<class T> inline
840 *this = arcp<T> (n);
841 std::fill_n (this->begin (), n, val);
842}
843
844
845template<class T>
846template<class Iter>
847inline
849 const size_type new_n = std::distance (first, last);
850 if (new_n != size ()) {
851 *this = arcp<T> (new_n);
852 }
853 std::copy (first, last, begin ());
854}
855
856
857template<class T> inline
858void ArrayRCP<T>::resize(const size_type n, const T &val)
859{
860#ifdef TEUCHOS_DEBUG
861 TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0);
862#endif
863 if (n == 0) {
864 clear();
865 return;
866 }
867 const size_type orig_n = size();
868 if (n != orig_n) {
869 ArrayRCP<T> tmp = *this;
870 *this = arcp<T>(n);
871 const size_type small_n = std::min(n, orig_n);
872 for (size_type i = 0; i < small_n; ++i)
873 (*this)[i] = tmp[i];
874 for (size_type i = orig_n; i < n; ++i)
875 (*this)[i] = val;
876 upperOffset_ = n-1;
877 }
878}
879
880template<class T> inline
881void ArrayRCP<const T>::resize (const size_type n, const T& val)
882{
883#ifdef TEUCHOS_DEBUG
884 TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0);
885#endif
886 if (n == 0) {
887 clear ();
888 return;
889 }
890 const size_type orig_n = size ();
891 if (n != orig_n) {
892 ArrayRCP<const T> tmp = *this;
893 // It's not allowed to assign to the result of operator[] for a
894 // const right-hand side, so we have to assign to a temporary
895 // nonconst ArrayRCP (nonconstThis) first.
896 ArrayRCP<T> nonconstThis = arcp<T> (n);
897 const size_type small_n = std::min (n, orig_n);
898 for (size_type i = 0; i < small_n; ++i) {
899 nonconstThis[i] = tmp[i];
900 }
901 for (size_type i = orig_n; i < n; ++i) {
902 nonconstThis[i] = val;
903 }
904 *this = arcp_const_cast<const T> (nonconstThis);
905 upperOffset_ = n-1;
906 }
907}
908
909
910template<class T> inline
912 *this = null;
913}
914
915template<class T> inline
917 *this = null;
918}
919
920
921// Misc functions
922
923
924template<class T> inline
926{
927 if (av.size() == 0) {
928 *this = null;
929 return;
930 }
931 assign(av.begin(), av.end());
932}
933
934
935// Reference counting
936
937
938template<class T> inline
940 return node_.strength();
941}
942
943template<class T> inline
945 return node_.strength();
946}
947
948
949template<class T> inline
951{
952 if (ptr_)
953 return node_.is_valid_ptr();
954 return true;
955}
956
957template<class T> inline
959{
960 if (ptr_)
961 return node_.is_valid_ptr();
962 return true;
963}
964
965
966template<class T> inline
968{
969 return node_.strong_count();
970}
971
972template<class T> inline
974{
975 return node_.strong_count();
976}
977
978
979template<class T> inline
981{
982 return node_.weak_count();
983}
984
985template<class T> inline
987{
988 return node_.weak_count();
989}
990
991
992template<class T> inline
994{
995 return node_.total_count();
996}
997
998template<class T> inline
1000{
1001 return node_.total_count();
1002}
1003
1004
1005template<class T> inline
1007{
1008 node_.has_ownership(true);
1009}
1010
1011template<class T> inline
1013{
1014 node_.has_ownership(true);
1015}
1016
1017
1018template<class T> inline
1020{
1021 return node_.has_ownership();
1022}
1023
1024template<class T> inline
1026{
1027 return node_.has_ownership();
1028}
1029
1030
1031template<class T> inline
1033{
1034 debug_assert_valid_ptr();
1035 node_.has_ownership(false);
1036 return ptr_;
1037}
1038
1039template<class T> inline
1041{
1042 debug_assert_valid_ptr();
1043 node_.has_ownership(false);
1044 return ptr_;
1045}
1046
1047
1048template<class T> inline
1050 debug_assert_valid_ptr ();
1051 return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_weak ());
1052}
1053
1054template<class T> inline
1056 debug_assert_valid_ptr ();
1057 return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_weak ());
1058}
1059
1060
1061template<class T> inline
1063 debug_assert_valid_ptr ();
1064 return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_strong ());
1065}
1066
1067template<class T> inline
1069 debug_assert_valid_ptr ();
1070 return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_strong ());
1071}
1072
1073
1074template<class T>
1075template <class T2>
1076inline
1078{
1079 return node_.same_node (r_ptr.access_private_node ());
1080 // Note: above, r_ptr is *not* the same class type as *this so we can not
1081 // access its node_ member directly! This is an interesting detail to the
1082 // C++ protected/private protection mechanism!
1083}
1084
1085template<class T>
1086template <class T2>
1087inline
1089{
1090 return node_.same_node (r_ptr.access_private_node ());
1091 // Note: above, r_ptr is *not* the same class type as *this so we can not
1092 // access its node_ member directly! This is an interesting detail to the
1093 // C++ protected/private protection mechanism!
1094}
1095
1096
1097// Assertion Functions
1098
1099
1100template<class T> inline
1101const ArrayRCP<T>&
1103{
1104 if(!ptr_)
1105 throw_null_ptr_error(typeName(*this));
1106 return *this;
1107}
1108
1109template<class T> inline
1110const ArrayRCP<const T>&
1112{
1113 if (! ptr_) {
1114 throw_null_ptr_error (typeName (*this));
1115 }
1116 return *this;
1117}
1118
1119
1120template<class T> inline
1122{
1123 if (ptr_) {
1124 node_.assert_valid_ptr (*this);
1125 }
1126 return *this;
1127}
1128
1129template<class T> inline
1131{
1132 if (ptr_) {
1133 node_.assert_valid_ptr (*this);
1134 }
1135 return *this;
1136}
1137
1138
1139template<class T> inline
1140const ArrayRCP<T>&
1142{
1143 assert_not_null();
1145 !(
1146 (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_)
1147 &&
1148 size_in >= 0
1149 ),
1151 typeName(*this)<<"::assert_in_range:"
1152 " Error, [lowerOffset,lowerOffset+size-1] = ["
1153 <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
1154 " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
1155 );
1156 return *this;
1157}
1158
1159template<class T> inline
1160const ArrayRCP<const T>&
1162assert_in_range (size_type lowerOffset_in, size_type size_in) const
1163{
1164 assert_not_null ();
1166 !(
1167 (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_)
1168 &&
1169 size_in >= 0
1170 ),
1172 typeName (*this) << "::assert_in_range:"
1173 " Error, [lowerOffset,lowerOffset+size-1] = ["
1174 <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
1175 " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
1176 );
1177 return *this;
1178}
1179
1180
1181// very bad public functions
1182
1183
1184template<class T> inline
1185ArrayRCP<T>::ArrayRCP(
1186 T* p, size_type lowerOffset_in, size_type size_in,
1187 const RCPNodeHandle& node
1188 )
1189 :ptr_(p),
1190 node_(node),
1191 lowerOffset_(lowerOffset_in),
1192 upperOffset_(size_in + lowerOffset_in - 1)
1193{}
1194
1195template<class T> inline
1197 const T* p, size_type lowerOffset_in, size_type size_in,
1198 const RCPNodeHandle& node
1199 )
1200 :ptr_(p),
1201 node_(node),
1202 lowerOffset_(lowerOffset_in),
1203 upperOffset_(size_in + lowerOffset_in - 1)
1204{}
1205
1206
1207template<class T> inline
1208T* ArrayRCP<T>::access_private_ptr() const
1209{
1210 return ptr_;
1211}
1212
1213template<class T> inline
1214const T* ArrayRCP<const T>::access_private_ptr () const
1215{
1216 return ptr_;
1217}
1218
1219
1220template<class T> inline
1221RCPNodeHandle& ArrayRCP<T>::nonconst_access_private_node()
1222{
1223 return node_;
1224}
1225
1226template<class T> inline
1227RCPNodeHandle& ArrayRCP<const T>::nonconst_access_private_node()
1228{
1229 return node_;
1230}
1231
1232
1233template<class T> inline
1234const RCPNodeHandle& ArrayRCP<T>::access_private_node() const
1235{
1236 return node_;
1237}
1238
1239template<class T> inline
1240const RCPNodeHandle& ArrayRCP<const T>::access_private_node() const
1241{
1242 return node_;
1243}
1244
1245
1246// Array<void> and Array<const void> specializations
1247
1248
1253
1254
1256{
1258}
1259
1260
1261} // end namespace Teuchos
1262
1263
1264// ///////////////////////////////////////////
1265// Non-member functions for ArrayRCP
1266
1267
1268namespace Teuchos {
1269namespace Utilities {
1270template<class T1, class T2>
1271inline void assert_shares_resource(
1272 const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2
1273 )
1274{
1275#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1277 !p1.shares_resource(p2), IncompatibleIteratorsError,
1278 "Error, these iterators are *not* pointing to the same valid memory!"
1279 );
1280#endif
1281}
1282} // namespace Utilities
1283} // namespace Teuchos
1284
1285
1286template<class T> inline
1288Teuchos::arcp(
1289T* p, typename ArrayRCP<T>::size_type lowerOffset
1290 ,typename ArrayRCP<T>::size_type size_in
1291 ,bool owns_mem
1292 )
1293{
1294 return ArrayRCP<T>(p, lowerOffset, size_in, owns_mem);
1295}
1296
1297
1298template<class T, class Dealloc_T>
1299inline
1301Teuchos::arcp(
1302T* p, typename ArrayRCP<T>::size_type lowerOffset
1303 ,typename ArrayRCP<T>::size_type size_in
1304 ,Dealloc_T dealloc, bool owns_mem
1305 )
1306{
1307 return ArrayRCP<T>(p, lowerOffset, size_in, dealloc, owns_mem);
1308}
1309
1310
1311template<class T> inline
1313Teuchos::arcp( typename ArrayRCP<T>::size_type size )
1314{
1315#ifdef TEUCHOS_DEBUG
1316 TEUCHOS_ASSERT_INEQUALITY( size, >=, 0 );
1317#endif
1318 if (size == 0) {
1319 return null;
1320 }
1321 return ArrayRCP<T>(new T[size], 0, size, true);
1322}
1323
1324
1325template<class T> inline
1327Teuchos::arcpCloneNode(const ArrayRCP<T> &a)
1328{
1329 if (is_null(a)) {
1330 return null;
1331 }
1332 return arcpWithEmbeddedObj(a.getRawPtr(), a.lowerOffset(), a.size(),
1333 a, false);
1334}
1335
1336
1337template<class T> inline
1339Teuchos::arcpClone( const ArrayView<const T> &v )
1340{
1341 const ArrayRCP<T> new_arcp = arcp<T>(v.size());
1342 std::copy( v.begin(), v.end(), new_arcp.begin() );
1343 return new_arcp;
1344}
1345
1346
1347template<class T, class Embedded>
1349Teuchos::arcpWithEmbeddedObjPreDestroy(
1350 T* p,
1351 typename ArrayRCP<T>::size_type lowerOffset,
1352 typename ArrayRCP<T>::size_type size,
1353 const Embedded &embedded,
1354 bool owns_mem
1355 )
1356{
1357 return arcp(
1358 p, lowerOffset, size,
1359 embeddedObjDeallocArrayDelete<T>(embedded, PRE_DESTROY),
1360 owns_mem
1361 );
1362}
1363
1364
1365template<class T, class Embedded>
1367Teuchos::arcpWithEmbeddedObjPostDestroy(
1368 T* p,
1369 typename ArrayRCP<T>::size_type lowerOffset,
1370 typename ArrayRCP<T>::size_type size,
1371 const Embedded &embedded,
1372 bool owns_mem
1373 )
1374{
1375 return arcp(
1376 p, lowerOffset, size,
1377 embeddedObjDeallocArrayDelete<T>(embedded, POST_DESTROY),
1378 owns_mem
1379 );
1380}
1381
1382
1383template<class T, class Embedded>
1385Teuchos::arcpWithEmbeddedObj(
1386 T* p,
1387 typename ArrayRCP<T>::size_type lowerOffset,
1388 typename ArrayRCP<T>::size_type size,
1389 const Embedded &embedded,
1390 bool owns_mem
1391 )
1392{
1393 return arcpWithEmbeddedObjPostDestroy<T,Embedded>(
1394 p, lowerOffset, size, embedded, owns_mem );
1395}
1396
1397
1398template<class T> inline
1400Teuchos::arcp( const RCP<std::vector<T> > &v )
1401{
1402 if ( is_null(v) || !v->size() )
1403 return null;
1404 return arcpWithEmbeddedObjPostDestroy<T,RCP<std::vector<T> > >(
1405 &(*v)[0], 0, v->size(),
1406 v, false
1407 );
1408}
1409
1410
1411template<class T> inline
1413Teuchos::arcp( const RCP<const std::vector<T> > &v )
1414{
1415 if ( is_null(v) || !v->size() )
1416 return null;
1417 return arcpWithEmbeddedObjPostDestroy<const T,RCP<const std::vector<T> > >(
1418 &(*v)[0], 0, v->size(),
1419 v, false
1420 );
1421}
1422
1423
1424template<class T> inline
1426Teuchos::arcpFromArrayView(const ArrayView<T> &av)
1427{
1428#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1429 return av.access_private_arcp();
1430#else
1431 return arcp(av.getRawPtr(), 0, av.size(), false);
1432#endif
1433}
1434
1435
1436template<class T> inline
1438Teuchos::get_std_vector( const ArrayRCP<T> &ptr )
1439{
1440 return getEmbeddedObj<T, RCP<std::vector<T> > >(ptr);
1441}
1442
1443
1444template<class T> inline
1446Teuchos::get_std_vector( const ArrayRCP<const T> &ptr )
1447{
1448 return getEmbeddedObj<const T, RCP<const std::vector<T> > >(ptr);
1449}
1450
1451
1452template<class T> inline
1453bool Teuchos::is_null( const ArrayRCP<T> &p )
1454{
1455 return p.is_null();
1456}
1457
1458
1459template<class T> inline
1460bool Teuchos::nonnull( const ArrayRCP<T> &p )
1461{
1462 return !p.is_null();
1463}
1464
1465
1466template<class T> inline
1467bool Teuchos::operator==( const ArrayRCP<T> &p, ENull )
1468{
1469 return p.is_null();
1470}
1471
1472
1473template<class T> inline
1474bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull )
1475{
1476 return !p.is_null();
1477}
1478
1479
1480template<class T1, class T2>
1481inline
1482bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1483{
1484 return p1.access_private_ptr() == p2.access_private_ptr();
1485}
1486
1487
1488template<class T1, class T2>
1489inline
1490bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1491{
1492 return p1.access_private_ptr() != p2.access_private_ptr();
1493}
1494
1495
1496template<class T1, class T2>
1497inline
1498bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1499{
1500 return p1.access_private_ptr() < p2.access_private_ptr();
1501}
1502
1503
1504template<class T1, class T2>
1505inline
1506bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1507{
1508 Utilities::assert_shares_resource(p1,p2);
1509 return p1.access_private_ptr() <= p2.access_private_ptr();
1510}
1511
1512
1513template<class T1, class T2>
1514inline
1515bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1516{
1517 Utilities::assert_shares_resource(p1,p2);
1518 return p1.access_private_ptr() > p2.access_private_ptr();
1519}
1520
1521
1522template<class T1, class T2>
1523inline
1524bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1525{
1526 Utilities::assert_shares_resource(p1,p2);
1527 return p1.access_private_ptr() >= p2.access_private_ptr();
1528}
1529
1530
1531template<class T>
1533Teuchos::operator-( const ArrayRCP<T> &p1, const ArrayRCP<T> &p2 )
1534{
1535 Utilities::assert_shares_resource(p1,p2);
1536 return p1.access_private_ptr() - p2.access_private_ptr();
1537}
1538
1539
1540template<class T2, class T1>
1541inline
1543Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1)
1544{
1545 typedef typename ArrayRCP<T1>::size_type size_type;
1546 const int sizeOfT1 = sizeof(T1);
1547 const int sizeOfT2 = sizeof(T2);
1548 size_type lowerOffset2 = (p1.lowerOffset()*sizeOfT1) / sizeOfT2;
1549 size_type upperOffset2 = ((p1.upperOffset()+1)*sizeOfT1) / sizeOfT2 - 1;
1550 T2 *ptr2 = reinterpret_cast<T2*>(p1.get());
1551 return ArrayRCP<T2>(
1552 ptr2, lowerOffset2, upperOffset2 - lowerOffset2 + 1,
1553 p1.access_private_node()
1554 );
1555 // Note: Above is just fine even if p1.get()==NULL!
1556}
1557
1558
1559template<class T2, class T1>
1561Teuchos::arcp_reinterpret_cast_nonpod(const ArrayRCP<T1>& p1, const T2& val)
1562{
1563 typedef typename ArrayRCP<T2>::iterator itr_t;
1564 ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(p1);
1565 for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) {
1566 new (&*itr) T2(val);
1567 }
1568 return arcpWithEmbeddedObj(
1569 arcp2.getRawPtr(), 0, arcp2.size(),
1570 ArcpReinterpretCastEmbeddedObj<T2, T1>(p1),
1571 false);
1572 // Above, the ownership of the memory is totally owned by the embedded
1573 // object and the default deallocator policy object does not do anything.
1574 // This is just fine.
1575}
1576
1577
1578template<class T2, class T1>
1579inline
1581Teuchos::arcp_const_cast(const ArrayRCP<T1>& p1)
1582{
1583 T2 *ptr2 = const_cast<T2*>(p1.get());
1584 return ArrayRCP<T2>(
1585 ptr2, p1.lowerOffset(), p1.size(),
1586 p1.access_private_node()
1587 );
1588 // Note: Above is just fine even if p1.get()==NULL!
1589}
1590
1591
1592template<class T2, class T1>
1593inline
1595Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1)
1596{
1597 T2 * raw_ptr2 = p1.get();
1598 return ArrayRCP<T2>(
1599 raw_ptr2, p1.lowerOffset(), p1.size(),
1600 p1.access_private_node()
1601 );
1602 // Note: Above is just fine even if p1.get()==NULL!
1603}
1604
1605
1606template<class T1, class T2>
1607inline
1608void Teuchos::set_extra_data(
1609 const T1 &extra_data, const std::string& name,
1610 const Ptr<ArrayRCP<T2> > &p, EPrePostDestruction destroy_when,
1611 bool force_unique
1612 )
1613{
1614 p->assert_not_null();
1615 p->nonconst_access_private_node().set_extra_data( any(extra_data), name, destroy_when,
1616 force_unique );
1617}
1618
1619
1620template<class T1, class T2>
1621inline
1622T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name )
1623{
1624 p.assert_not_null();
1625 return any_cast<T1>(
1626 p.nonconst_access_private_node().get_extra_data(
1627 TypeNameTraits<T1>::name(), name
1628 )
1629 );
1630}
1631
1632
1633template<class T1, class T2>
1634inline
1635const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name )
1636{
1637 p.assert_not_null();
1638 return any_cast<T1>(
1639 p.access_private_node().get_extra_data(
1640 TypeNameTraits<T1>::name() ,name
1641 )
1642 );
1643}
1644
1645
1646template<class T1, class T2>
1647inline
1648T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name )
1649{
1650 p.assert_not_null();
1651 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
1652 TypeNameTraits<T1>::name(), name);
1653 if( extra_data ) return &any_cast<T1>(*extra_data);
1654 return NULL;
1655}
1656
1657
1658template<class T1, class T2>
1659inline
1660const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name )
1661{
1662 p.assert_not_null();
1663 any *extra_data = p.access_private_node().get_optional_extra_data(
1664 TypeNameTraits<T1>::name(), name);
1665 if( extra_data ) return &any_cast<T1>(*extra_data);
1666 return NULL;
1667}
1668
1669
1670template<class Dealloc_T, class T>
1671inline
1672const Dealloc_T&
1673Teuchos::get_dealloc( const ArrayRCP<T>& p )
1674{
1675 return get_nonconst_dealloc<Dealloc_T>(p);
1676}
1677
1678
1679template<class Dealloc_T, class T>
1680inline
1681Dealloc_T&
1682Teuchos::get_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
1683{
1684 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
1685 p.assert_not_null();
1686 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
1687 *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
1688 p.access_private_node().node_ptr());
1690 dnode==NULL, NullReferenceError
1691 ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
1692 << "," << TypeNameTraits<T>::name() << ">(p): "
1693 << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
1694 << "\' does not match actual type of the node \'"
1695 << typeName(*p.access_private_node().node_ptr()) << "!"
1696 );
1697 return dnode->get_nonconst_dealloc();
1698}
1699
1700
1701template<class Dealloc_T, class T>
1702inline
1703const Dealloc_T*
1704Teuchos::get_optional_dealloc( const ArrayRCP<T>& p )
1705{
1706 return get_optional_dealloc<Dealloc_T>(p);
1707}
1708
1709
1710template<class Dealloc_T, class T>
1711inline
1712Dealloc_T*
1713Teuchos::get_optional_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
1714{
1715 p.assert_not_null();
1716 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
1717 RCPNT;
1718 RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
1719 if (dnode)
1720 return &dnode->get_nonconst_dealloc();
1721 return 0;
1722}
1723
1724
1725template<class TOrig, class Embedded, class T>
1726const Embedded& Teuchos::getEmbeddedObj( const ArrayRCP<T>& p )
1727{
1728 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t;
1729 return get_dealloc<Dealloc_t>(p).getObj();
1730}
1731
1732
1733template<class TOrig, class Embedded, class T>
1734Embedded& Teuchos::getNonconstEmbeddedObj( const ArrayRCP<T>& p )
1735{
1736 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t;
1737 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
1738}
1739
1740
1741template<class T>
1742std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p )
1743{
1744 // mfh 15 Sep 2015: Make sure that NULL pointers print consistently.
1745 // Clang 3.5 likes to print an empty string in that case, while GCC
1746 // prints 0. Thus, we test if the pointer is NULL and print 0 in
1747 // that case. This is important for MueLu tests, which compare
1748 // string print-outs.
1749 out
1750 << TypeNameTraits<ArrayRCP<T> >::name() << "{"
1751 << "ptr=";
1752 if (p.access_private_ptr () == NULL) {
1753 out << "0";
1754 } else {
1755 out << (const void*) (p.access_private_ptr ());
1756 }
1757 out
1758 <<",lowerOffset="<<p.lowerOffset()
1759 <<",upperOffset="<<p.upperOffset()
1760 <<",size="<<p.size()
1761 <<",node=" << p.access_private_node ()
1762 <<",strong_count="<<p.strong_count()
1763 <<",weak_count="<<p.weak_count()
1764 <<"}";
1765 return out;
1766 // NOTES:
1767 // * I can't find any alternative to this C cast (problems with char data)
1768 // * Don't range check the pointer since this code does not dereference it.
1769 // This is needed to allow printing the end() or past end() for debugging.
1770}
1771
1772
1773#endif // TEUCHOS_ARRAY_RCP_HPP
Definition of Teuchos::as, for conversions between types.
Reference-counted smart pointer for managing arrays.
Ordinal size_type
Type representing the number of elements in an ArrayRCP or view thereof.
Ordinal difference_type
Type representing the difference between two size_type values.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to deallocate it.
T * iterator
Nonconstant iterator type used if bounds checking is disabled.
ArrayRCP(ENull null_arg=null)
Default constructor; initialize to an empty array.
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
bool is_valid_ptr() const
Return whether the underlying object pointer is still valid.
iterator begin() const
Return an iterator to beginning of the array of data.
ERCPStrength strength() const
Strength of the pointer.
const ArrayRCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
int total_count() const
Total count (strong_count() + weak_count()).
Handle class that manages the RCPNode's reference counting.
Deletes a (non-owning) RCPNode but not it's underlying object in case of a throw.
static RCPNode * getExistingRCPNode(T *p)
Return a raw pointer to an existing owning RCPNode given the address to the underlying object if it e...
Node class to keep track of address and the reference count for a reference-counted utility class and...
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.
Ptr< T > release()
Release the ownership of the underlying dynamically allocated object.
Dealloc_T & get_nonconst_dealloc(const RCP< T > &p)
Return a non-const reference to the underlying deallocator object.
bool is_null() const
Returns true if the underlying pointer is null.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
RCP< T > create_strong() const
Create a new strong RCP object from another (weak) RCP object.
T * get() const
Get the raw C++ pointer to the underlying object.
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
Range error exception class.
#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.
#define TEUCHOS_ASSERT_INEQUALITY(val1, comp, val2)
This macro is checks that an inequality between two numbers is satisified and if not then throws a go...
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
This macro is checks that to numbers are equal and if not then throws an exception with a good error ...
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool nonnull(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.
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object.
ERCPStrength
Used to specify if the pointer is weak or strong.
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...