Teuchos - Trilinos Tools Package Version of the Day
Teuchos_RCP.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_RCP_HPP
43#define TEUCHOS_RCP_HPP
44
45
58#include "Teuchos_RCPDecl.hpp"
59#include "Teuchos_Ptr.hpp"
60#include "Teuchos_Assert.hpp"
61#include "Teuchos_Exceptions.hpp"
62#include "Teuchos_dyn_cast.hpp"
63#include "Teuchos_map.hpp"
65
66
67namespace Teuchos {
68
69
70// very bad public functions
71
72
73template<class T>
74inline
75RCPNode* RCP_createNewRCPNodeRawPtrNonowned( T* p )
76{
77 return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(), false);
78}
79
80
81template<class T>
82inline
83RCPNode* RCP_createNewRCPNodeRawPtrNonownedUndefined( T* p )
84{
85 return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(), false, null);
86}
87
88
89template<class T>
90inline
91RCPNode* RCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in )
92{
93 return new RCPNodeTmpl<T,DeallocDelete<T> >(p, DeallocDelete<T>(), has_ownership_in);
94}
95
96
97template<class T, class Dealloc_T>
98inline
99RCPNode* RCP_createNewDeallocRCPNodeRawPtr(
100 T* p, Dealloc_T dealloc, bool has_ownership_in
101 )
102{
103 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in);
104}
105
106
107template<class T, class Dealloc_T>
108inline
109RCPNode* RCP_createNewDeallocRCPNodeRawPtrUndefined(
110 T* p, Dealloc_T dealloc, bool has_ownership_in
111 )
112{
113 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in, null);
114}
115
116
117template<class T>
118inline
119RCP<T>::RCP( T* p, const RCPNodeHandle& node)
120 : ptr_(p), node_(node)
121{}
122
123
124template<class T>
125inline
126T* RCP<T>::access_private_ptr() const
127{ return ptr_; }
128
129
130template<class T>
131inline
132RCPNodeHandle& RCP<T>::nonconst_access_private_node()
133{ return node_; }
134
135
136template<class T>
137inline
138const RCPNodeHandle& RCP<T>::access_private_node() const
139{ return node_; }
140
141
142
143
144// Constructors/destructors/initializers
145
146
147template<class T>
148inline
150 : ptr_(NULL)
151{}
152
153
154template<class T>
155inline
156RCP<T>::RCP( T* p, ERCPWeakNoDealloc )
157 : ptr_(p)
158#ifndef TEUCHOS_DEBUG
159 , node_(RCP_createNewRCPNodeRawPtrNonowned(p))
160#endif // TEUCHOS_DEBUG
161{
162#ifdef TEUCHOS_DEBUG
163 if (p) {
164 RCPNode* existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
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 node_ = RCPNodeHandle(
172 RCP_createNewRCPNodeRawPtrNonowned(p),
173 p, typeName(*p), concreteTypeName(*p),
174 false
175 );
176 }
177 }
178#endif // TEUCHOS_DEBUG
179}
180
181
182template<class T>
183inline
184RCP<T>::RCP( T* p, ERCPUndefinedWeakNoDealloc )
185 : ptr_(p),
186 node_(RCP_createNewRCPNodeRawPtrNonownedUndefined(p))
187{}
188
189
190template<class T>
191inline
192RCP<T>::RCP( T* p, bool has_ownership_in )
193 : ptr_(p)
194#ifndef TEUCHOS_DEBUG
195 , node_(RCP_createNewRCPNodeRawPtr(p, has_ownership_in))
196#endif // TEUCHOS_DEBUG
197{
198#ifdef TEUCHOS_DEBUG
199 if (p) {
200 RCPNode* existing_RCPNode = 0;
201 if (!has_ownership_in) {
202 existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
203 }
204 if (existing_RCPNode) {
205 // Will not call add_new_RCPNode(...)
206 node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
207 }
208 else {
209 // Will call add_new_RCPNode(...)
210 RCPNodeThrowDeleter nodeDeleter(RCP_createNewRCPNodeRawPtr(p, has_ownership_in));
211 node_ = RCPNodeHandle(
212 nodeDeleter.get(),
213 p, typeName(*p), concreteTypeName(*p),
214 has_ownership_in
215 );
216 nodeDeleter.release();
217 }
218 }
219#endif // TEUCHOS_DEBUG
220}
221
222
223template<class T>
224template<class Dealloc_T>
225inline
226RCP<T>::RCP( T* p, Dealloc_T dealloc, bool has_ownership_in )
227 : ptr_(p)
228#ifndef TEUCHOS_DEBUG
229 , node_(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in))
230#endif // TEUCHOS_DEBUG
231{
232#ifdef TEUCHOS_DEBUG
233 if (p) {
234 // Here we are assuming that if the user passed in a custom deallocator
235 // then they will want to have ownership (otherwise it will throw if it is
236 // the same object).
237 RCPNodeThrowDeleter nodeDeleter(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in));
238 node_ = RCPNodeHandle(
239 nodeDeleter.get(),
240 p, typeName(*p), concreteTypeName(*p),
241 has_ownership_in
242 );
243 nodeDeleter.release();
244 }
245#endif // TEUCHOS_DEBUG
246}
247
248
249template<class T>
250template<class Dealloc_T>
251inline
252RCP<T>::RCP( T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc, bool has_ownership_in )
253 : ptr_(p)
254#ifndef TEUCHOS_DEBUG
255 , node_(RCP_createNewDeallocRCPNodeRawPtrUndefined(p, dealloc, has_ownership_in))
256#endif // TEUCHOS_DEBUG
257{
258#ifdef TEUCHOS_DEBUG
259 if (p) {
260 // Here we are assuming that if the user passed in a custom deallocator
261 // then they will want to have ownership (otherwise it will throw if it is
262 // the same object).
263 // Use auto_ptr to ensure we don't leak if a throw occurs
264 RCPNodeThrowDeleter nodeDeleter(RCP_createNewDeallocRCPNodeRawPtrUndefined(
265 p, dealloc, has_ownership_in));
266 node_ = RCPNodeHandle(
267 nodeDeleter.get(),
268 p, typeName(*p), concreteTypeName(*p),
269 has_ownership_in
270 );
271 nodeDeleter.release();
272 }
273#endif // TEUCHOS_DEBUG
274}
275
276
277template<class T>
278inline
279RCP<T>::RCP(const RCP<T>& r_ptr)
280 : ptr_(r_ptr.ptr_), node_(r_ptr.node_)
281{}
282
283
284template<class T>
285inline
287 : ptr_(r_ptr.ptr_), node_(std::move(r_ptr.node_))
288{
289 r_ptr.ptr_ = 0;
290}
291
292
293template<class T>
294template<class T2>
295inline
296RCP<T>::RCP(const RCP<T2>& r_ptr)
297 : ptr_(r_ptr.get()), // will not compile if T is not base class of T2
298 node_(r_ptr.access_private_node())
299{}
300
301
302template<class T>
303inline
305{}
306
307
308template<class T>
309inline
311{
312#ifdef TEUCHOS_DEBUG
313 if (this == &r_ptr)
314 return *this;
315 reset(); // Force delete first in debug mode!
316#endif
317 RCP<T>(r_ptr).swap(*this);
318 return *this;
319}
320
321
322template<class T>
323inline
325{
326#ifdef TEUCHOS_DEBUG
327 if (this == &r_ptr)
328 return *this;
329 reset(); // Force delete first in debug mode!
330#endif
331 ptr_ = r_ptr.ptr_;
332 node_ = std::move(r_ptr.node_);
333 r_ptr.ptr_ = 0;
334 return *this;
335}
336
337
338template<class T>
339inline
341{
342 reset();
343 return *this;
344}
345
346
347template<class T>
348inline
350{
351 std::swap(r_ptr.ptr_, ptr_);
352 node_.swap(r_ptr.node_);
353}
354
355
356// Object query and access functions
357
358
359template<class T>
360inline
361bool RCP<T>::is_null() const
362{
363 return ptr_ == 0;
364}
365
366
367template<class T>
368inline
370{
371 debug_assert_not_null();
372 debug_assert_valid_ptr();
373 return ptr_;
374}
375
376
377template<class T>
378inline
380{
381 debug_assert_not_null();
382 debug_assert_valid_ptr();
383 return *ptr_;
384}
385
386template<class T>
387inline
388T* RCP<T>::get() const
389{
390 debug_assert_valid_ptr();
391 return ptr_;
392}
393
394
395template<class T>
396inline
398{
399 return this->get();
400}
401
402
403template<class T>
404inline
406{
407#ifdef TEUCHOS_DEBUG
408 return Ptr<T>(this->create_weak());
409#else
410 return Ptr<T>(getRawPtr());
411#endif
412}
413
414
415template<class T>
416inline
418{
419 return ptr();
420}
421
422
423template<class T>
424inline
426{
427 return rcp_implicit_cast<const T>(*this);
428}
429
430
431template<class T>
432inline
434{
435 return (get() != 0);
436}
437
438
439// Reference counting
440
441
442template<class T>
443inline
445{
446 return node_.strength();
447}
448
449
450template<class T>
451inline
453{
454 if (ptr_)
455 return node_.is_valid_ptr();
456 return true;
457}
458
460template<class T>
461inline
463{
464 return node_.strong_count();
465}
466
467
468template<class T>
469inline
471{
472 return node_.weak_count();
473}
474
475
476template<class T>
477inline
479{
480 return node_.total_count();
482
483
484template<class T>
485inline
487{
488 node_.has_ownership(true);
489}
490
491
492template<class T>
493inline
495{
496 return node_.has_ownership();
497}
498
499
500template<class T>
501inline
504 debug_assert_valid_ptr();
505 node_.has_ownership(false);
506 return Ptr<T>(ptr_);
507}
508
509
510template<class T>
511inline
513{
514 debug_assert_valid_ptr();
515 return RCP<T>(ptr_, node_.create_weak());
516}
517
518
519template<class T>
520inline
523 debug_assert_valid_ptr();
524 return RCP<T>(ptr_, node_.create_strong());
525}
526
527#if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
528template<class T>
529inline
532 if (strength() == RCP_STRONG) {
533 return create_strong(); // it's already thread safe
534 }
535 // we don't check for debug_assert_valid_ptr()
536 // probably doesn't hurt anything if we do but using it would be confusing
537 // because ptr could become invalid immediately after
538 RCPNodeHandle attemptStrong = node_.create_strong_lock();
539 return RCP<T>( attemptStrong.is_node_null() ? 0 : ptr_, attemptStrong);
540}
541#endif
542
543
544template<class T>
545template <class T2>
546inline
547bool RCP<T>::shares_resource(const RCP<T2>& r_ptr) const
548{
549 return node_.same_node(r_ptr.access_private_node());
550 // Note: above, r_ptr is *not* the same class type as *this so we can not
551 // access its node_ member directly! This is an interesting detail to the
552 // C++ protected/private protection mechanism!
553}
554
555
556// Assertions
557
558
559template<class T>
560inline
562{
563 if (!ptr_)
564 throw_null_ptr_error(typeName(*this));
565 return *this;
566}
567
568
569template<class T>
570inline
572{
573 if (ptr_)
574 node_.assert_valid_ptr(*this);
575 return *this;
576}
577
578
579// boost::shared_ptr compatiblity funtions
580
582template<class T>
583inline
585{
586#ifdef TEUCHOS_DEBUG
587 node_ = RCPNodeHandle();
588#else
589 RCPNodeHandle().swap(node_);
590#endif
591 ptr_ = 0;
593
594
595template<class T>
596template<class T2>
597inline
598void RCP<T>::reset(T2* p, bool has_ownership_in)
599{
600 *this = rcp(p, has_ownership_in);
601}
602
603} // end namespace Teuchos
604
605
606// /////////////////////////////////////////////////////////////////////////////////
607// Inline non-member functions for RCP
608
610template<class T>
611inline
613Teuchos::rcp( T* p, bool owns_mem )
614{
615 return RCP<T>(p, owns_mem);
616}
618
619template<class T, class Dealloc_T>
620inline
622Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc, bool owns_mem )
623{
624 return RCP<T>(p, dealloc, owns_mem);
626
627
628template<class T, class Dealloc_T>
629inline
631Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc, bool owns_mem )
632{
633 return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
634}
635
636
637template<class T>
639Teuchos::rcpFromRef( T& r )
640{
641 return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
642}
643
644
645template<class T>
647Teuchos::rcpFromUndefRef( T& r )
649 return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
650}
652
653template<class T, class Embedded>
655Teuchos::rcpWithEmbeddedObjPreDestroy(
656 T* p, const Embedded &embedded, bool owns_mem
658{
659 return rcpWithDealloc(
660 p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
661 );
662}
663
664
665template<class T, class Embedded>
667Teuchos::rcpWithEmbeddedObjPostDestroy(
668 T* p, const Embedded &embedded, bool owns_mem
669 )
670{
671 return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
672}
674
675template<class T, class Embedded>
677Teuchos::rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem )
678{
679 return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
680}
681
682
683template<class T, class ParentT>
685Teuchos::rcpWithInvertedObjOwnership(const RCP<T> &child,
686 const RCP<ParentT> &parent)
687{
688 using std::make_pair;
689 return rcpWithEmbeddedObj(child.getRawPtr(), make_pair(child, parent), false);
690}
692
693template<class T>
695Teuchos::rcpCloneNode(const RCP<T> &p)
696{
697 if (is_null(p)) {
698 return p;
699 }
700 return rcpWithEmbeddedObj(&*p, p, false);
702
703
704template<class T>
705inline
706bool Teuchos::is_null( const RCP<T> &p )
707{
708 return p.is_null();
709}
710
711
712template<class T>
713inline
714bool Teuchos::nonnull( const RCP<T> &p )
715{
716 return !p.is_null();
717}
718
719
720template<class T>
721inline
722bool Teuchos::operator==( const RCP<T> &p, ENull )
723{
724 return p.get() == NULL;
725}
726
727
728template<class T>
729inline
730bool Teuchos::operator!=( const RCP<T> &p, ENull )
731{
732 return p.get() != NULL;
734
735
736template<class T1, class T2>
737inline
738bool Teuchos::operator==( const RCP<T1> &p1, const RCP<T2> &p2 )
739{
740 return p1.access_private_node().same_node(p2.access_private_node());
741}
742
743
744template<class T1, class T2>
745inline
746bool Teuchos::operator!=( const RCP<T1> &p1, const RCP<T2> &p2 )
747{
748 return !p1.access_private_node().same_node(p2.access_private_node());
749}
750
751
752template<class T2, class T1>
753inline
755Teuchos::rcp_implicit_cast(const RCP<T1>& p1)
756{
757 // Make the compiler check if the conversion is legal
758 T2 *check = p1.get();
759 return RCP<T2>(check, p1.access_private_node());
760}
761
762
763template<class T2, class T1>
764inline
766Teuchos::rcp_static_cast(const RCP<T1>& p1)
767{
768 // Make the compiler check if the conversion is legal
769 T2 *check = static_cast<T2*>(p1.get());
770 return RCP<T2>(check, p1.access_private_node());
771}
772
773
774template<class T2, class T1>
775inline
777Teuchos::rcp_const_cast(const RCP<T1>& p1)
778{
779 // Make the compiler check if the conversion is legal
780 T2 *check = const_cast<T2*>(p1.get());
781 return RCP<T2>(check, p1.access_private_node());
782}
783
785template<class T2, class T1>
786inline
788Teuchos::rcp_dynamic_cast(const RCP<T1>& p1, bool throw_on_fail)
789{
790 if (!is_null(p1)) {
791 T2 *p = NULL;
792 if (throw_on_fail) {
793 p = &dyn_cast<T2>(*p1);
794 }
795 else {
796 // Make the compiler check if the conversion is legal
797 p = dynamic_cast<T2*>(p1.get());
798 }
799 if (p) {
800 return RCP<T2>(p, p1.access_private_node());
801 }
803 return null;
804}
805
806
807template<class T1, class T2>
808inline
809void Teuchos::set_extra_data( const T1 &extra_data, const std::string& name,
810 const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when, bool force_unique )
811{
812 p->assert_not_null();
813 p->nonconst_access_private_node().set_extra_data(
814 any(extra_data), name, destroy_when,
815 force_unique );
816}
818
819template<class T1, class T2>
820inline
821const T1& Teuchos::get_extra_data( const RCP<T2>& p, const std::string& name )
822{
823 p.assert_not_null();
824 return any_cast<T1>(
825 p.access_private_node().get_extra_data(
828 );
829}
830
831
832template<class T1, class T2>
833inline
834T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p, const std::string& name )
835{
836 p.assert_not_null();
837 return any_cast<T1>(
838 p.nonconst_access_private_node().get_extra_data(
840 )
841 );
842}
843
844
845template<class T1, class T2>
846inline
848Teuchos::get_optional_extra_data( const RCP<T2>& p, const std::string& name )
849{
850 p.assert_not_null();
851 const any *extra_data = p.access_private_node().get_optional_extra_data(
853 if (extra_data)
854 return Ptr<const T1>(&any_cast<T1>(*extra_data));
855 return null;
856}
857
858
859template<class T1, class T2>
860inline
862Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
863{
865 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
867 if (extra_data)
868 return Ptr<T1>(&any_cast<T1>(*extra_data));
869 return null;
870}
871
872
873template<class Dealloc_T, class T>
874inline
875const Dealloc_T& Teuchos::get_dealloc( const RCP<T>& p )
876{
877 return get_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
878}
879
880
881template<class Dealloc_T, class T>
882inline
883Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
884{
886 p.assert_not_null();
889 p.access_private_node().node_ptr());
891 dnode==NULL, NullReferenceError
892 ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
893 << "," << TypeNameTraits<T>::name() << ">(p): "
894 << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
895 << "\' does not match actual type of the node \'"
896 << typeName(*p.access_private_node().node_ptr()) << "!"
897 );
898 return dnode->get_nonconst_dealloc();
899}
900
901
902template<class Dealloc_T, class T>
903inline
905Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
906{
907 p.assert_not_null();
909 RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
910 if(dnode)
911 return ptr(&dnode->get_nonconst_dealloc());
912 return null;
913}
914
915
916template<class Dealloc_T, class T>
917inline
919Teuchos::get_optional_dealloc( const RCP<T>& p )
920{
921 return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
922}
923
924
925template<class TOrig, class Embedded, class T>
926const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
927{
929 return get_dealloc<Dealloc_t>(p).getObj();
930}
931
932
933template<class TOrig, class Embedded, class T>
934Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
935{
937 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
938}
939
940
941template<class TOrig, class Embedded, class T>
943Teuchos::getOptionalEmbeddedObj( const RCP<T>& p )
944{
945 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
946 const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
947 if (!is_null(dealloc)) {
948 return ptr(&dealloc->getObj());
949 }
950 return null;
951}
952
953
954template<class TOrig, class Embedded, class T>
956Teuchos::getOptionalNonconstEmbeddedObj( const RCP<T>& p )
957{
958 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
959 const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
960 if (!is_null(dealloc)) {
961 return ptr(&dealloc->getNonconstObj());
962 }
963 return null;
964}
965
966
967template<class ParentT, class T>
969Teuchos::getInvertedObjOwnershipParent(const RCP<T> &invertedChild)
970{
971 typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
972 Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
973 return pair.second;
974}
975
976
977template<class T>
978std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
979{
980 out
981 << typeName(p) << "{"
982 << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
983 <<",node="<<p.access_private_node()
984 <<",strong_count="<<p.strong_count()
985 <<",weak_count="<<p.weak_count()
986 <<"}";
987 return out;
988}
989
990
991#endif // TEUCHOS_RCP_HPP
Reference-counted pointer class and non-member templated function implementations.
Defines basic traits returning the name of a type in a portable and readable way.
Provides std::map class for deficient platforms.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
A deallocator class that wraps a simple value object and delegates to another deallocator object.
Null reference error exception class.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
const Ptr< T > & assert_not_null() const
Throws std::logic_error if this->get()==NULL, otherwise returns reference to *this.
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
Handle class that manages the RCPNode's reference counting.
RCPNodeHandle create_strong_lock() const
Return a strong handle if possible using thread safe atomics.
bool is_node_null() const
Whether the underlying RCPNode is NULL.
void swap(RCPNodeHandle &node_ref)
Swap the contents of node_ref with *this.
Deletes a (non-owning) RCPNode but not it's underlying object in case of a throw.
void release()
Releaes the RCPNode pointer before the destructor is called.
Templated implementation class of RCPNode that has the responsibility for deleting the reference-coun...
Dealloc_T & get_nonconst_dealloc()
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< const T > getConst() const
Return an RCP<const T> version of *this.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
RCP< T > rcpWithDealloc(T *p, Dealloc_T dealloc, bool owns_mem=true)
Initialize from a raw pointer with a deallocation policy.
Ptr< T > release()
Release the ownership of the underlying dynamically allocated object.
void reset()
Reset to null.
void set_has_ownership()
Give this and other RCP<> objects ownership of the referenced object this->get().
~RCP()
Removes a reference to a dynamically allocated object and possibly deletes the object if owned.
const RCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
bool shares_resource(const RCP< T2 > &r_ptr) const
Returns true if the smart pointers share the same underlying reference-counted object.
RCP< T > rcpWithEmbeddedObj(T *p, const Embedded &embedded, bool owns_mem=true)
Create an RCP with and also put in an embedded 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.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
Ptr< const T1 > get_optional_extra_data(const RCP< T2 > &p, const std::string &name)
Get a pointer to const extra data (if it exists) associated with a RCP object.
T * operator->() const
Pointer (->) access to members of underlying object.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
const T1 & get_extra_data(const RCP< T2 > &p, const std::string &name)
Get a const reference to extra data associated with a RCP object.
RCP< T > create_strong() const
Create a new strong RCP object from another (weak) RCP object.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to delete it.
T * get() const
Get the raw C++ pointer to the underlying object.
ERCPStrength strength() const
Strength of the pointer.
void set_extra_data(const T1 &extra_data, const std::string &name, const Ptr< RCP< T2 > > &p, EPrePostDestruction destroy_when=POST_DESTROY, bool force_unique=true)
Set extra data associated with a RCP object.
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
RCP< T > & operator=(const RCP< T > &r_ptr)
Copy the pointer to the referenced object and increment the reference count.
int total_count() const
Total count (strong_count() + weak_count()).
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
Ptr< T > operator()() const
Shorthand for ptr().
T & operator*() const
Dereference the underlying object.
Default traits class that just returns typeid(T).name().
Modified boost::any class, which is a container for a templated value.
#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.
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.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
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.
RCP< ParentT > getInvertedObjOwnershipParent(const RCP< T > &invertedChild)
Get the parent back from an inverted ownership RCP.