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 template<class T2>
286 inline
287 RCP<T>::RCP(const RCP<T2>& r_ptr)
288  : ptr_(r_ptr.get()), // will not compile if T is not base class of T2
289  node_(r_ptr.access_private_node())
290 {}
291 
292 
293 template<class T>
294 inline
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  RCP<T>(r_ptr).swap(*this);
309  return *this;
310 }
311 
312 
313 template<class T>
314 inline
316 {
317  reset();
318  return *this;
319 }
320 
321 
322 template<class T>
323 inline
324 void RCP<T>::swap(RCP<T> &r_ptr)
325 {
326  std::swap(r_ptr.ptr_, ptr_);
327  node_.swap(r_ptr.node_);
328 }
329 
330 
331 // Object query and access functions
332 
333 
334 template<class T>
335 inline
336 bool RCP<T>::is_null() const
337 {
338  return ptr_ == 0;
339 }
340 
341 
342 template<class T>
343 inline
345 {
346  debug_assert_not_null();
347  debug_assert_valid_ptr();
348  return ptr_;
349 }
350 
351 
352 template<class T>
353 inline
355 {
356  debug_assert_not_null();
357  debug_assert_valid_ptr();
358  return *ptr_;
359 }
360 
361 template<class T>
362 inline
363 T* RCP<T>::get() const
364 {
365  debug_assert_valid_ptr();
366  return ptr_;
367 }
368 
369 
370 template<class T>
371 inline
373 {
374  return this->get();
375 }
376 
377 
378 template<class T>
379 inline
381 {
382 #ifdef TEUCHOS_DEBUG
383  return Ptr<T>(this->create_weak());
384 #else
385  return Ptr<T>(getRawPtr());
386 #endif
387 }
388 
389 
390 template<class T>
391 inline
393 {
394  return ptr();
395 }
396 
397 
398 template<class T>
399 inline
401 {
402  return rcp_implicit_cast<const T>(*this);
403 }
404 
405 
406 // Reference counting
407 
408 
409 template<class T>
410 inline
412 {
413  return node_.strength();
414 }
415 
416 
417 template<class T>
418 inline
420 {
421  if (ptr_)
422  return node_.is_valid_ptr();
423  return true;
424 }
425 
426 
427 template<class T>
428 inline
430 {
431  return node_.strong_count();
432 }
433 
434 
435 template<class T>
436 inline
438 {
439  return node_.weak_count();
440 }
441 
442 
443 template<class T>
444 inline
446 {
447  return node_.total_count();
448 }
449 
450 
451 template<class T>
452 inline
454 {
455  node_.has_ownership(true);
456 }
457 
458 
459 template<class T>
460 inline
462 {
463  return node_.has_ownership();
464 }
465 
466 
467 template<class T>
468 inline
470 {
471  debug_assert_valid_ptr();
472  node_.has_ownership(false);
473  return Ptr<T>(ptr_);
474 }
475 
476 
477 template<class T>
478 inline
480 {
481  debug_assert_valid_ptr();
482  return RCP<T>(ptr_, node_.create_weak());
483 }
484 
485 
486 template<class T>
487 inline
489 {
490  debug_assert_valid_ptr();
491  return RCP<T>(ptr_, node_.create_strong());
492 }
493 
494 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
495 template<class T>
496 inline
498 {
499  if (strength() == RCP_STRONG) {
500  return create_strong(); // it's already thread safe
501  }
502  // we don't check for debug_assert_valid_ptr()
503  // probably doesn't hurt anything if we do but using it would be confusing
504  // because ptr could become invalid immediately after
505  RCPNodeHandle attemptStrong = node_.create_strong_lock();
506  return RCP<T>( attemptStrong.is_node_null() ? 0 : ptr_, attemptStrong);
507 }
508 #endif
509 
510 
511 template<class T>
512 template <class T2>
513 inline
514 bool RCP<T>::shares_resource(const RCP<T2>& r_ptr) const
515 {
516  return node_.same_node(r_ptr.access_private_node());
517  // Note: above, r_ptr is *not* the same class type as *this so we can not
518  // access its node_ member directly! This is an interesting detail to the
519  // C++ protected/private protection mechanism!
520 }
521 
522 
523 // Assertions
524 
525 
526 template<class T>
527 inline
529 {
530  if (!ptr_)
531  throw_null_ptr_error(typeName(*this));
532  return *this;
533 }
534 
535 
536 template<class T>
537 inline
539 {
540  if (ptr_)
541  node_.assert_valid_ptr(*this);
542  return *this;
543 }
544 
545 
546 // boost::shared_ptr compatiblity funtions
547 
548 
549 template<class T>
550 inline
552 {
553 #ifdef TEUCHOS_DEBUG
554  node_ = RCPNodeHandle();
555 #else
556  RCPNodeHandle().swap(node_);
557 #endif
558  ptr_ = 0;
559 }
560 
561 
562 template<class T>
563 template<class T2>
564 inline
565 void RCP<T>::reset(T2* p, bool has_ownership_in)
566 {
567  *this = rcp(p, has_ownership_in);
568 }
569 
570 
571 template<class T>
572 inline
573 int RCP<T>::count() const
574 {
575  return node_.count();
576 }
577 
578 } // end namespace Teuchos
579 
580 
581 // /////////////////////////////////////////////////////////////////////////////////
582 // Inline non-member functions for RCP
583 
584 
585 template<class T>
586 inline
588 Teuchos::rcp( T* p, bool owns_mem )
589 {
590  return RCP<T>(p, owns_mem);
591 }
592 
593 
594 template<class T, class Dealloc_T>
595 inline
597 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc, bool owns_mem )
598 {
599  return RCP<T>(p, dealloc, owns_mem);
600 }
601 
602 
603 template<class T, class Dealloc_T>
604 inline
606 Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc, bool owns_mem )
607 {
608  return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
609 }
610 
611 
612 template<class T>
614 Teuchos::rcpFromRef( T& r )
615 {
616  return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
617 }
618 
619 
620 template<class T>
622 Teuchos::rcpFromUndefRef( T& r )
623 {
624  return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
625 }
626 
627 
628 template<class T, class Embedded>
630 Teuchos::rcpWithEmbeddedObjPreDestroy(
631  T* p, const Embedded &embedded, bool owns_mem
632  )
633 {
634  return rcpWithDealloc(
635  p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
636  );
637 }
638 
639 
640 template<class T, class Embedded>
642 Teuchos::rcpWithEmbeddedObjPostDestroy(
643  T* p, const Embedded &embedded, bool owns_mem
644  )
645 {
646  return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
647 }
648 
649 
650 template<class T, class Embedded>
652 Teuchos::rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem )
653 {
654  return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
655 }
656 
657 
658 template<class T, class ParentT>
660 Teuchos::rcpWithInvertedObjOwnership(const RCP<T> &child,
661  const RCP<ParentT> &parent)
662 {
663  using std::make_pair;
664  return rcpWithEmbeddedObj(child.getRawPtr(), make_pair(child, parent), false);
665 }
666 
667 
668 template<class T>
670 Teuchos::rcpCloneNode(const RCP<T> &p)
671 {
672  if (is_null(p)) {
673  return p;
674  }
675  return rcpWithEmbeddedObj(&*p, p, false);
676 }
677 
678 
679 template<class T>
680 inline
681 bool Teuchos::is_null( const RCP<T> &p )
682 {
683  return p.is_null();
684 }
685 
686 
687 template<class T>
688 inline
689 bool Teuchos::nonnull( const RCP<T> &p )
690 {
691  return !p.is_null();
692 }
693 
694 
695 template<class T>
696 inline
697 bool Teuchos::operator==( const RCP<T> &p, ENull )
698 {
699  return p.get() == NULL;
700 }
701 
702 
703 template<class T>
704 inline
705 bool Teuchos::operator!=( const RCP<T> &p, ENull )
706 {
707  return p.get() != NULL;
708 }
709 
710 
711 template<class T1, class T2>
712 inline
713 bool Teuchos::operator==( const RCP<T1> &p1, const RCP<T2> &p2 )
714 {
715  return p1.access_private_node().same_node(p2.access_private_node());
716 }
717 
718 
719 template<class T1, class T2>
720 inline
721 bool Teuchos::operator!=( const RCP<T1> &p1, const RCP<T2> &p2 )
722 {
723  return !p1.access_private_node().same_node(p2.access_private_node());
724 }
725 
726 
727 template<class T2, class T1>
728 inline
730 Teuchos::rcp_implicit_cast(const RCP<T1>& p1)
731 {
732  // Make the compiler check if the conversion is legal
733  T2 *check = p1.get();
734  return RCP<T2>(check, p1.access_private_node());
735 }
736 
737 
738 template<class T2, class T1>
739 inline
741 Teuchos::rcp_static_cast(const RCP<T1>& p1)
742 {
743  // Make the compiler check if the conversion is legal
744  T2 *check = static_cast<T2*>(p1.get());
745  return RCP<T2>(check, p1.access_private_node());
746 }
747 
748 
749 template<class T2, class T1>
750 inline
752 Teuchos::rcp_const_cast(const RCP<T1>& p1)
753 {
754  // Make the compiler check if the conversion is legal
755  T2 *check = const_cast<T2*>(p1.get());
756  return RCP<T2>(check, p1.access_private_node());
757 }
758 
759 
760 template<class T2, class T1>
761 inline
763 Teuchos::rcp_dynamic_cast(const RCP<T1>& p1, bool throw_on_fail)
764 {
765  if (!is_null(p1)) {
766  T2 *p = NULL;
767  if (throw_on_fail) {
768  p = &dyn_cast<T2>(*p1);
769  }
770  else {
771  // Make the compiler check if the conversion is legal
772  p = dynamic_cast<T2*>(p1.get());
773  }
774  if (p) {
775  return RCP<T2>(p, p1.access_private_node());
776  }
777  }
778  return null;
779 }
780 
781 
782 template<class T1, class T2>
783 inline
784 void Teuchos::set_extra_data( const T1 &extra_data, const std::string& name,
785  const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when, bool force_unique )
786 {
787  p->assert_not_null();
788  p->nonconst_access_private_node().set_extra_data(
789  any(extra_data), name, destroy_when,
790  force_unique );
791 }
792 
793 
794 template<class T1, class T2>
795 inline
796 const T1& Teuchos::get_extra_data( const RCP<T2>& p, const std::string& name )
797 {
798  p.assert_not_null();
799  return any_cast<T1>(
800  p.access_private_node().get_extra_data(
801  TypeNameTraits<T1>::name(), name
802  )
803  );
804 }
805 
806 
807 template<class T1, class T2>
808 inline
809 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p, const std::string& name )
810 {
811  p.assert_not_null();
812  return any_cast<T1>(
813  p.nonconst_access_private_node().get_extra_data(
814  TypeNameTraits<T1>::name(), name
815  )
816  );
817 }
818 
819 
820 template<class T1, class T2>
821 inline
823 Teuchos::get_optional_extra_data( const RCP<T2>& p, const std::string& name )
824 {
825  p.assert_not_null();
826  const any *extra_data = p.access_private_node().get_optional_extra_data(
827  TypeNameTraits<T1>::name(), name);
828  if (extra_data)
829  return Ptr<const T1>(&any_cast<T1>(*extra_data));
830  return null;
831 }
832 
833 
834 template<class T1, class T2>
835 inline
837 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
838 {
839  p.assert_not_null();
840  any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
841  TypeNameTraits<T1>::name(), name);
842  if (extra_data)
843  return Ptr<T1>(&any_cast<T1>(*extra_data));
844  return null;
845 }
846 
847 
848 template<class Dealloc_T, class T>
849 inline
850 const Dealloc_T& Teuchos::get_dealloc( const RCP<T>& p )
851 {
852  return get_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
853 }
854 
855 
856 template<class Dealloc_T, class T>
857 inline
858 Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
859 {
860  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
861  p.assert_not_null();
862  RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
863  *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
864  p.access_private_node().node_ptr());
866  dnode==NULL, NullReferenceError
867  ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
868  << "," << TypeNameTraits<T>::name() << ">(p): "
869  << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
870  << "\' does not match actual type of the node \'"
871  << typeName(*p.access_private_node().node_ptr()) << "!"
872  );
873  return dnode->get_nonconst_dealloc();
874 }
875 
876 
877 template<class Dealloc_T, class T>
878 inline
880 Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
881 {
882  p.assert_not_null();
883  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
884  RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
885  if(dnode)
886  return ptr(&dnode->get_nonconst_dealloc());
887  return null;
888 }
889 
890 
891 template<class Dealloc_T, class T>
892 inline
894 Teuchos::get_optional_dealloc( const RCP<T>& p )
895 {
896  return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
897 }
898 
899 
900 template<class TOrig, class Embedded, class T>
901 const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
902 {
903  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
904  return get_dealloc<Dealloc_t>(p).getObj();
905 }
906 
907 
908 template<class TOrig, class Embedded, class T>
909 Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
910 {
911  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
912  return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
913 }
914 
915 
916 template<class TOrig, class Embedded, class T>
918 Teuchos::getOptionalEmbeddedObj( const RCP<T>& p )
919 {
920  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
921  const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
922  if (!is_null(dealloc)) {
923  return ptr(&dealloc->getObj());
924  }
925  return null;
926 }
927 
928 
929 template<class TOrig, class Embedded, class T>
931 Teuchos::getOptionalNonconstEmbeddedObj( const RCP<T>& p )
932 {
933  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
934  const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
935  if (!is_null(dealloc)) {
936  return ptr(&dealloc->getNonconstObj());
937  }
938  return null;
939 }
940 
941 
942 template<class ParentT, class T>
944 Teuchos::getInvertedObjOwnershipParent(const RCP<T> &invertedChild)
945 {
946  typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
947  Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
948  return pair.second;
949 }
950 
951 
952 template<class T>
953 std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
954 {
955  out
956  << typeName(p) << "{"
957  << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
958  <<",node="<<p.access_private_node()
959  <<",strong_count="<<p.strong_count()
960  <<",weak_count="<<p.weak_count()
961  <<"}";
962  return out;
963 }
964 
965 
966 #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.
TEUCHOS_DEPRECATED int count() const
Returns strong_count() [deprecated].
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.