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