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 inline
305 {}
306 
307 
308 template<class T>
309 inline
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 
322 template<class T>
323 inline
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 
338 template<class T>
339 inline
341 {
342  reset();
343  return *this;
344 }
345 
346 
347 template<class T>
348 inline
349 void RCP<T>::swap(RCP<T> &r_ptr)
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 
359 template<class T>
360 inline
361 bool RCP<T>::is_null() const
362 {
363  return ptr_ == 0;
364 }
365 
366 
367 template<class T>
368 inline
370 {
371  debug_assert_not_null();
372  debug_assert_valid_ptr();
373  return ptr_;
374 }
375 
376 
377 template<class T>
378 inline
380 {
381  debug_assert_not_null();
382  debug_assert_valid_ptr();
383  return *ptr_;
384 }
385 
386 template<class T>
387 inline
388 T* RCP<T>::get() const
389 {
390  debug_assert_valid_ptr();
391  return ptr_;
392 }
393 
394 
395 template<class T>
396 inline
398 {
399  return this->get();
400 }
401 
402 
403 template<class T>
404 inline
406 {
407 #ifdef TEUCHOS_DEBUG
408  return Ptr<T>(this->create_weak());
409 #else
410  return Ptr<T>(getRawPtr());
411 #endif
412 }
413 
414 
415 template<class T>
416 inline
418 {
419  return ptr();
420 }
421 
422 
423 template<class T>
424 inline
426 {
427  return rcp_implicit_cast<const T>(*this);
428 }
429 
430 
431 template<class T>
432 inline
433 RCP<T>::operator bool() const
434 {
435  return (get() != 0);
436 }
437 
438 
439 // Reference counting
440 
441 
442 template<class T>
443 inline
445 {
446  return node_.strength();
447 }
448 
449 
450 template<class T>
451 inline
453 {
454  if (ptr_)
455  return node_.is_valid_ptr();
456  return true;
457 }
458 
459 
460 template<class T>
461 inline
463 {
464  return node_.strong_count();
465 }
466 
467 
468 template<class T>
469 inline
471 {
472  return node_.weak_count();
473 }
474 
475 
476 template<class T>
477 inline
479 {
480  return node_.total_count();
481 }
482 
483 
484 template<class T>
485 inline
487 {
488  node_.has_ownership(true);
489 }
490 
491 
492 template<class T>
493 inline
495 {
496  return node_.has_ownership();
497 }
498 
499 
500 template<class T>
501 inline
503 {
504  debug_assert_valid_ptr();
505  node_.has_ownership(false);
506  return Ptr<T>(ptr_);
507 }
508 
509 
510 template<class T>
511 inline
513 {
514  debug_assert_valid_ptr();
515  return RCP<T>(ptr_, node_.create_weak());
516 }
517 
518 
519 template<class T>
520 inline
522 {
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)
528 template<class T>
529 inline
531 {
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 
544 template<class T>
545 template <class T2>
546 inline
547 bool 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 
559 template<class T>
560 inline
562 {
563  if (!ptr_)
564  throw_null_ptr_error(typeName(*this));
565  return *this;
566 }
567 
568 
569 template<class T>
570 inline
572 {
573  if (ptr_)
574  node_.assert_valid_ptr(*this);
575  return *this;
576 }
577 
578 
579 // boost::shared_ptr compatiblity funtions
580 
581 
582 template<class T>
583 inline
585 {
586 #ifdef TEUCHOS_DEBUG
587  node_ = RCPNodeHandle();
588 #else
589  RCPNodeHandle().swap(node_);
590 #endif
591  ptr_ = 0;
592 }
593 
594 
595 template<class T>
596 template<class T2>
597 inline
598 void 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 
609 
610 template<class T>
611 inline
613 Teuchos::rcp( T* p, bool owns_mem )
614 {
615  return RCP<T>(p, owns_mem);
616 }
617 
618 
619 template<class T, class Dealloc_T>
620 inline
622 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc, bool owns_mem )
623 {
624  return RCP<T>(p, dealloc, owns_mem);
625 }
626 
627 
628 template<class T, class Dealloc_T>
629 inline
631 Teuchos::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 
637 template<class T>
639 Teuchos::rcpFromRef( T& r )
640 {
641  return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
642 }
643 
644 
645 template<class T>
647 Teuchos::rcpFromUndefRef( T& r )
648 {
649  return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
650 }
651 
652 
653 template<class T, class Embedded>
655 Teuchos::rcpWithEmbeddedObjPreDestroy(
656  T* p, const Embedded &embedded, bool owns_mem
657  )
658 {
659  return rcpWithDealloc(
660  p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
661  );
662 }
663 
664 
665 template<class T, class Embedded>
667 Teuchos::rcpWithEmbeddedObjPostDestroy(
668  T* p, const Embedded &embedded, bool owns_mem
669  )
670 {
671  return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
672 }
673 
674 
675 template<class T, class Embedded>
677 Teuchos::rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem )
678 {
679  return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
680 }
681 
682 
683 template<class T, class ParentT>
685 Teuchos::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 }
691 
692 
693 template<class T>
695 Teuchos::rcpCloneNode(const RCP<T> &p)
696 {
697  if (is_null(p)) {
698  return p;
699  }
700  return rcpWithEmbeddedObj(&*p, p, false);
701 }
702 
703 
704 template<class T>
705 inline
706 bool Teuchos::is_null( const RCP<T> &p )
707 {
708  return p.is_null();
709 }
710 
711 
712 template<class T>
713 inline
714 bool Teuchos::nonnull( const RCP<T> &p )
715 {
716  return !p.is_null();
717 }
718 
719 
720 template<class T>
721 inline
722 bool Teuchos::operator==( const RCP<T> &p, ENull )
723 {
724  return p.get() == NULL;
725 }
726 
727 
728 template<class T>
729 inline
730 bool Teuchos::operator!=( const RCP<T> &p, ENull )
731 {
732  return p.get() != NULL;
733 }
734 
735 
736 template<class T1, class T2>
737 inline
738 bool 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 
744 template<class T1, class T2>
745 inline
746 bool 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 
752 template<class T2, class T1>
753 inline
755 Teuchos::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 
763 template<class T2, class T1>
764 inline
766 Teuchos::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 
774 template<class T2, class T1>
775 inline
777 Teuchos::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 
784 
785 template<class T2, class T1>
786 inline
788 Teuchos::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  }
802  }
803  return null;
804 }
805 
806 
807 template<class T1, class T2>
808 inline
809 void 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 }
817 
818 
819 template<class T1, class T2>
820 inline
821 const 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(
826  TypeNameTraits<T1>::name(), name
827  )
828  );
829 }
830 
831 
832 template<class T1, class T2>
833 inline
834 T1& 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(
839  TypeNameTraits<T1>::name(), name
840  )
841  );
842 }
843 
844 
845 template<class T1, class T2>
846 inline
848 Teuchos::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(
852  TypeNameTraits<T1>::name(), name);
853  if (extra_data)
854  return Ptr<const T1>(&any_cast<T1>(*extra_data));
855  return null;
856 }
857 
858 
859 template<class T1, class T2>
860 inline
862 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
863 {
864  p.assert_not_null();
865  any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
866  TypeNameTraits<T1>::name(), name);
867  if (extra_data)
868  return Ptr<T1>(&any_cast<T1>(*extra_data));
869  return null;
870 }
871 
872 
873 template<class Dealloc_T, class T>
874 inline
875 const 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 
881 template<class Dealloc_T, class T>
882 inline
883 Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
884 {
885  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
886  p.assert_not_null();
887  RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
888  *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
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 
902 template<class Dealloc_T, class T>
903 inline
905 Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
906 {
907  p.assert_not_null();
908  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
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 
916 template<class Dealloc_T, class T>
917 inline
919 Teuchos::get_optional_dealloc( const RCP<T>& p )
920 {
921  return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
922 }
923 
924 
925 template<class TOrig, class Embedded, class T>
926 const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
927 {
928  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
929  return get_dealloc<Dealloc_t>(p).getObj();
930 }
931 
932 
933 template<class TOrig, class Embedded, class T>
934 Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
935 {
936  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
937  return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
938 }
939 
940 
941 template<class TOrig, class Embedded, class T>
943 Teuchos::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 
954 template<class TOrig, class Embedded, class T>
956 Teuchos::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 
967 template<class ParentT, class T>
969 Teuchos::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 
977 template<class T>
978 std::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
~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.