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 //
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 
67 namespace Teuchos {
68 
69 
70 // very bad public functions
71 
72 
73 template<class T>
74 inline
75 RCPNode* RCP_createNewRCPNodeRawPtrNonowned( T* p )
76 {
77  return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(), false);
78 }
79 
80 
81 template<class T>
82 inline
83 RCPNode* RCP_createNewRCPNodeRawPtrNonownedUndefined( T* p )
84 {
85  return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(), false, null);
86 }
87 
88 
89 template<class T>
90 inline
91 RCPNode* 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 
97 template<class T, class Dealloc_T>
98 inline
99 RCPNode* 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 
107 template<class T, class Dealloc_T>
108 inline
109 RCPNode* 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 
117 template<class T>
118 inline
119 RCP<T>::RCP( T* p, const RCPNodeHandle& node)
120  : ptr_(p), node_(node)
121 {}
122 
123 
124 template<class T>
125 inline
126 T* RCP<T>::access_private_ptr() const
127 { return ptr_; }
128 
129 
130 template<class T>
131 inline
132 RCPNodeHandle& RCP<T>::nonconst_access_private_node()
133 { return node_; }
134 
135 
136 template<class T>
137 inline
138 const RCPNodeHandle& RCP<T>::access_private_node() const
139 { return node_; }
140 
141 
142 
143 
144 // Constructors/destructors/initializers
145 
146 
147 template<class T>
148 inline
150  : ptr_(NULL)
151 {}
152 
153 
154 template<class T>
155 inline
156 RCP<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 
182 template<class T>
183 inline
184 RCP<T>::RCP( T* p, ERCPUndefinedWeakNoDealloc )
185  : ptr_(p),
186  node_(RCP_createNewRCPNodeRawPtrNonownedUndefined(p))
187 {}
188 
189 
190 template<class T>
191 inline
192 RCP<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 
223 template<class T>
224 template<class Dealloc_T>
225 inline
226 RCP<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 
249 template<class T>
250 template<class Dealloc_T>
251 inline
252 RCP<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 
277 template<class T>
278 inline
279 RCP<T>::RCP(const RCP<T>& r_ptr)
280  : ptr_(r_ptr.ptr_), node_(r_ptr.node_)
281 {}
282 
283 
284 template<class T>
285 inline
287  : ptr_(r_ptr.ptr_), node_(std::move(r_ptr.node_))
288 {
289  r_ptr.ptr_ = 0;
290 }
291 
292 
293 template<class T>
294 template<class T2>
295 inline
296 RCP<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 
302 template<class T>
303 template<class T2>
304 inline
305 RCP<T>::RCP(const RCP<T2>& r_ptr, T* ptr)
306  : ptr_(ptr),
307  node_(r_ptr.access_private_node())
308 {}
309 
310 
311 template<class T>
312 inline
314 {}
315 
316 
317 template<class T>
318 inline
320 {
321 #ifdef TEUCHOS_DEBUG
322  if (this == &r_ptr)
323  return *this;
324  reset(); // Force delete first in debug mode!
325 #endif
326  RCP<T>(r_ptr).swap(*this);
327  return *this;
328 }
329 
330 
331 template<class T>
332 inline
334 {
335 #ifdef TEUCHOS_DEBUG
336  if (this == &r_ptr)
337  return *this;
338  reset(); // Force delete first in debug mode!
339 #endif
340  ptr_ = r_ptr.ptr_;
341  node_ = std::move(r_ptr.node_);
342  r_ptr.ptr_ = 0;
343  return *this;
344 }
345 
346 
347 template<class T>
348 inline
350 {
351  reset();
352  return *this;
353 }
354 
355 
356 template<class T>
357 inline
358 void RCP<T>::swap(RCP<T> &r_ptr)
359 {
360  std::swap(r_ptr.ptr_, ptr_);
361  node_.swap(r_ptr.node_);
362 }
363 
364 
365 // Object query and access functions
366 
367 
368 template<class T>
369 inline
370 bool RCP<T>::is_null() const
371 {
372  return ptr_ == 0;
373 }
374 
375 
376 template<class T>
377 inline
379 {
380  debug_assert_not_null();
381  debug_assert_valid_ptr();
382  return ptr_;
383 }
384 
385 
386 template<class T>
387 inline
389 {
390  debug_assert_not_null();
391  debug_assert_valid_ptr();
392  return *ptr_;
393 }
394 
395 template<class T>
396 inline
397 T* RCP<T>::get() const
398 {
399  debug_assert_valid_ptr();
400  return ptr_;
401 }
402 
403 
404 template<class T>
405 inline
407 {
408  return this->get();
409 }
410 
411 
412 template<class T>
413 inline
415 {
416 #ifdef TEUCHOS_DEBUG
417  return Ptr<T>(this->create_weak());
418 #else
419  return Ptr<T>(getRawPtr());
420 #endif
421 }
422 
423 
424 template<class T>
425 inline
427 {
428  return ptr();
429 }
430 
431 
432 template<class T>
433 inline
435 {
436  return rcp_implicit_cast<const T>(*this);
437 }
438 
439 
440 template<class T>
441 inline
442 RCP<T>::operator bool() const
443 {
444  return (get() != 0);
445 }
446 
447 
448 // Reference counting
449 
450 
451 template<class T>
452 inline
454 {
455  return node_.strength();
456 }
457 
458 
459 template<class T>
460 inline
462 {
463  if (ptr_)
464  return node_.is_valid_ptr();
465  return true;
466 }
467 
468 
469 template<class T>
470 inline
472 {
473  return node_.strong_count();
474 }
475 
476 
477 template<class T>
478 inline
480 {
481  return node_.weak_count();
482 }
483 
484 
485 template<class T>
486 inline
488 {
489  return node_.total_count();
490 }
491 
492 
493 template<class T>
494 inline
496 {
497  node_.has_ownership(true);
498 }
499 
500 
501 template<class T>
502 inline
504 {
505  return node_.has_ownership();
506 }
507 
508 
509 template<class T>
510 inline
512 {
513  debug_assert_valid_ptr();
514  node_.has_ownership(false);
515  return Ptr<T>(ptr_);
516 }
517 
518 
519 template<class T>
520 inline
522 {
523  debug_assert_valid_ptr();
524  return RCP<T>(ptr_, node_.create_weak());
525 }
526 
527 
528 template<class T>
529 inline
531 {
532  debug_assert_valid_ptr();
533  return RCP<T>(ptr_, node_.create_strong());
534 }
535 
536 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
537 template<class T>
538 inline
540 {
541  if (strength() == RCP_STRONG) {
542  return create_strong(); // it's already thread safe
543  }
544  // we don't check for debug_assert_valid_ptr()
545  // probably doesn't hurt anything if we do but using it would be confusing
546  // because ptr could become invalid immediately after
547  RCPNodeHandle attemptStrong = node_.create_strong_lock();
548  return RCP<T>( attemptStrong.is_node_null() ? 0 : ptr_, attemptStrong);
549 }
550 #endif
551 
552 
553 template<class T>
554 template <class T2>
555 inline
556 bool RCP<T>::shares_resource(const RCP<T2>& r_ptr) const
557 {
558  return node_.same_node(r_ptr.access_private_node());
559  // Note: above, r_ptr is *not* the same class type as *this so we can not
560  // access its node_ member directly! This is an interesting detail to the
561  // C++ protected/private protection mechanism!
562 }
563 
564 
565 // Assertions
566 
567 
568 template<class T>
569 inline
571 {
572  if (!ptr_)
573  throw_null_ptr_error(typeName(*this));
574  return *this;
575 }
576 
577 
578 template<class T>
579 inline
581 {
582  if (ptr_)
583  node_.assert_valid_ptr(*this);
584  return *this;
585 }
586 
587 
588 // boost::shared_ptr compatiblity funtions
589 
590 
591 template<class T>
592 inline
594 {
595 #ifdef TEUCHOS_DEBUG
596  node_ = RCPNodeHandle();
597 #else
598  RCPNodeHandle().swap(node_);
599 #endif
600  ptr_ = 0;
601 }
602 
603 
604 template<class T>
605 template<class T2>
606 inline
607 void RCP<T>::reset(T2* p, bool has_ownership_in)
608 {
609  *this = rcp(p, has_ownership_in);
610 }
611 
612 } // end namespace Teuchos
613 
614 
615 // /////////////////////////////////////////////////////////////////////////////////
616 // Inline non-member functions for RCP
617 
618 
619 template<class T>
620 inline
622 Teuchos::rcp( T* p, bool owns_mem )
623 {
624  return RCP<T>(p, owns_mem);
625 }
626 
627 
628 template<class T, class Dealloc_T>
629 inline
631 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc, bool owns_mem )
632 {
633  return RCP<T>(p, dealloc, owns_mem);
634 }
635 
636 
637 template<class T, class Dealloc_T>
638 inline
640 Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc, bool owns_mem )
641 {
642  return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
643 }
644 
645 
646 template<class T>
648 Teuchos::rcpFromRef( T& r )
649 {
650  return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
651 }
652 
653 
654 template<class T>
656 Teuchos::rcpFromUndefRef( T& r )
657 {
658  return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
659 }
660 
661 
662 template<class T, class Embedded>
664 Teuchos::rcpWithEmbeddedObjPreDestroy(
665  T* p, const Embedded &embedded, bool owns_mem
666  )
667 {
668  return rcpWithDealloc(
669  p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
670  );
671 }
672 
673 
674 template<class T, class Embedded>
676 Teuchos::rcpWithEmbeddedObjPostDestroy(
677  T* p, const Embedded &embedded, bool owns_mem
678  )
679 {
680  return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
681 }
682 
683 
684 template<class T, class Embedded>
686 Teuchos::rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem )
687 {
688  return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
689 }
690 
691 
692 template<class T, class ParentT>
694 Teuchos::rcpWithInvertedObjOwnership(const RCP<T> &child,
695  const RCP<ParentT> &parent)
696 {
697  using std::make_pair;
698  return rcpWithEmbeddedObj(child.getRawPtr(), make_pair(child, parent), false);
699 }
700 
701 
702 template<class T>
704 Teuchos::rcpCloneNode(const RCP<T> &p)
705 {
706  if (is_null(p)) {
707  return p;
708  }
709  return rcpWithEmbeddedObj(&*p, p, false);
710 }
711 
712 
713 template<class T>
714 inline
715 bool Teuchos::is_null( const RCP<T> &p )
716 {
717  return p.is_null();
718 }
719 
720 
721 template<class T>
722 inline
723 bool Teuchos::nonnull( const RCP<T> &p )
724 {
725  return !p.is_null();
726 }
727 
728 
729 template<class T>
730 inline
731 bool Teuchos::operator==( const RCP<T> &p, ENull )
732 {
733  return p.get() == NULL;
734 }
735 
736 
737 template<class T>
738 inline
739 bool Teuchos::operator!=( const RCP<T> &p, ENull )
740 {
741  return p.get() != NULL;
742 }
743 
744 
745 template<class T1, class T2>
746 inline
747 bool Teuchos::operator==( const RCP<T1> &p1, const RCP<T2> &p2 )
748 {
749  return p1.access_private_node().same_node(p2.access_private_node());
750 }
751 
752 
753 template<class T1, class T2>
754 inline
755 bool Teuchos::operator!=( const RCP<T1> &p1, const RCP<T2> &p2 )
756 {
757  return !p1.access_private_node().same_node(p2.access_private_node());
758 }
759 
760 
761 template<class T2, class T1>
762 inline
764 Teuchos::rcp_implicit_cast(const RCP<T1>& p1)
765 {
766  // Make the compiler check if the conversion is legal
767  T2 *check = p1.get();
768  return RCP<T2>(check, p1.access_private_node());
769 }
770 
771 
772 template<class T2, class T1>
773 inline
775 Teuchos::rcp_static_cast(const RCP<T1>& p1)
776 {
777  // Make the compiler check if the conversion is legal
778  T2 *check = static_cast<T2*>(p1.get());
779  return RCP<T2>(check, p1.access_private_node());
780 }
781 
782 
783 template<class T2, class T1>
784 inline
786 Teuchos::rcp_const_cast(const RCP<T1>& p1)
787 {
788  // Make the compiler check if the conversion is legal
789  T2 *check = const_cast<T2*>(p1.get());
790  return RCP<T2>(check, p1.access_private_node());
791 }
792 
793 
794 template<class T2, class T1>
795 inline
797 Teuchos::rcp_dynamic_cast(const RCP<T1>& p1, bool throw_on_fail)
798 {
799  if (!is_null(p1)) {
800  T2 *p = NULL;
801  if (throw_on_fail) {
802  p = &dyn_cast<T2>(*p1);
803  }
804  else {
805  // Make the compiler check if the conversion is legal
806  p = dynamic_cast<T2*>(p1.get());
807  }
808  if (p) {
809  return RCP<T2>(p, p1.access_private_node());
810  }
811  }
812  return null;
813 }
814 
815 
816 template<class T1, class T2>
817 inline
818 void Teuchos::set_extra_data( const T1 &extra_data, const std::string& name,
819  const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when, bool force_unique )
820 {
821  p->assert_not_null();
822  p->nonconst_access_private_node().set_extra_data(
823  any(extra_data), name, destroy_when,
824  force_unique );
825 }
826 
827 
828 template<class T1, class T2>
829 inline
830 const T1& Teuchos::get_extra_data( const RCP<T2>& p, const std::string& name )
831 {
832  p.assert_not_null();
833  return any_cast<T1>(
834  p.access_private_node().get_extra_data(
835  TypeNameTraits<T1>::name(), name
836  )
837  );
838 }
839 
840 
841 template<class T1, class T2>
842 inline
843 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p, const std::string& name )
844 {
845  p.assert_not_null();
846  return any_cast<T1>(
847  p.nonconst_access_private_node().get_extra_data(
848  TypeNameTraits<T1>::name(), name
849  )
850  );
851 }
852 
853 
854 template<class T1, class T2>
855 inline
857 Teuchos::get_optional_extra_data( const RCP<T2>& p, const std::string& name )
858 {
859  p.assert_not_null();
860  const any *extra_data = p.access_private_node().get_optional_extra_data(
861  TypeNameTraits<T1>::name(), name);
862  if (extra_data)
863  return Ptr<const T1>(&any_cast<T1>(*extra_data));
864  return null;
865 }
866 
867 
868 template<class T1, class T2>
869 inline
871 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
872 {
873  p.assert_not_null();
874  any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
875  TypeNameTraits<T1>::name(), name);
876  if (extra_data)
877  return Ptr<T1>(&any_cast<T1>(*extra_data));
878  return null;
879 }
880 
881 
882 template<class Dealloc_T, class T>
883 inline
884 const Dealloc_T& Teuchos::get_dealloc( const RCP<T>& p )
885 {
886  return get_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
887 }
888 
889 
890 template<class Dealloc_T, class T>
891 inline
892 Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
893 {
894  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
895  p.assert_not_null();
896  RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
897  *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
898  p.access_private_node().node_ptr());
900  dnode==NULL, NullReferenceError
901  ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
902  << "," << TypeNameTraits<T>::name() << ">(p): "
903  << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
904  << "\' does not match actual type of the node \'"
905  << typeName(*p.access_private_node().node_ptr()) << "!"
906  );
907  return dnode->get_nonconst_dealloc();
908 }
909 
910 
911 template<class Dealloc_T, class T>
912 inline
914 Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
915 {
916  p.assert_not_null();
917  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
918  RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
919  if(dnode)
920  return ptr(&dnode->get_nonconst_dealloc());
921  return null;
922 }
923 
924 
925 template<class Dealloc_T, class T>
926 inline
928 Teuchos::get_optional_dealloc( const RCP<T>& p )
929 {
930  return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
931 }
932 
933 
934 template<class TOrig, class Embedded, class T>
935 const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
936 {
937  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
938  return get_dealloc<Dealloc_t>(p).getObj();
939 }
940 
941 
942 template<class TOrig, class Embedded, class T>
943 Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
944 {
945  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
946  return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
947 }
948 
949 
950 template<class TOrig, class Embedded, class T>
952 Teuchos::getOptionalEmbeddedObj( const RCP<T>& p )
953 {
954  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
955  const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
956  if (!is_null(dealloc)) {
957  return ptr(&dealloc->getObj());
958  }
959  return null;
960 }
961 
962 
963 template<class TOrig, class Embedded, class T>
965 Teuchos::getOptionalNonconstEmbeddedObj( const RCP<T>& p )
966 {
967  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
968  const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
969  if (!is_null(dealloc)) {
970  return ptr(&dealloc->getNonconstObj());
971  }
972  return null;
973 }
974 
975 
976 template<class ParentT, class T>
978 Teuchos::getInvertedObjOwnershipParent(const RCP<T> &invertedChild)
979 {
980  typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
981  Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
982  return pair.second;
983 }
984 
985 
986 template<class T>
987 std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
988 {
989  out
990  << typeName(p) << "{"
991  << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
992  <<",node="<<p.access_private_node()
993  <<",strong_count="<<p.strong_count()
994  <<",weak_count="<<p.weak_count()
995  <<"}";
996  return out;
997 }
998 
999 
1000 #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.