Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_RCP.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_RCP_HPP
43 #define TEUCHOS_RCP_HPP
44 
45 
58 #include "Teuchos_RCPDecl.hpp"
59 #include "Teuchos_Ptr.hpp"
60 #include "Teuchos_Assert.hpp"
61 #include "Teuchos_Exceptions.hpp"
62 #include "Teuchos_dyn_cast.hpp"
63 #include "Teuchos_map.hpp"
65 
66 
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 {
348  return ptr_;
349 }
350 
351 
352 template<class T>
353 inline
355 {
358  return *ptr_;
359 }
360 
361 template<class T>
362 inline
363 T* RCP<T>::get() const
364 {
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 {
472  node_.has_ownership(false);
473  return Ptr<T>(ptr_);
474 }
475 
476 
477 template<class T>
478 inline
480 {
482  return RCP<T>(ptr_, node_.create_weak());
483 }
484 
485 
486 template<class T>
487 inline
489 {
491  return RCP<T>(ptr_, node_.create_strong());
492 }
493 
494 
495 template<class T>
496 template <class T2>
497 inline
498 bool RCP<T>::shares_resource(const RCP<T2>& r_ptr) const
499 {
500  return node_.same_node(r_ptr.access_private_node());
501  // Note: above, r_ptr is *not* the same class type as *this so we can not
502  // access its node_ member directly! This is an interesting detail to the
503  // C++ protected/private protection mechanism!
504 }
505 
506 
507 // Assertions
508 
509 
510 template<class T>
511 inline
513 {
514  if (!ptr_)
515  throw_null_ptr_error(typeName(*this));
516  return *this;
517 }
518 
519 
520 template<class T>
521 inline
523 {
524  if (ptr_)
525  node_.assert_valid_ptr(*this);
526  return *this;
527 }
528 
529 
530 // boost::shared_ptr compatiblity funtions
531 
532 
533 template<class T>
534 inline
536 {
537 #ifdef TEUCHOS_DEBUG
538  node_ = RCPNodeHandle();
539 #else
540  RCPNodeHandle().swap(node_);
541 #endif
542  ptr_ = 0;
543 }
544 
545 
546 template<class T>
547 template<class T2>
548 inline
549 void RCP<T>::reset(T2* p, bool has_ownership_in)
550 {
551  *this = rcp(p, has_ownership_in);
552 }
553 
554 
555 template<class T>
556 inline
557 int RCP<T>::count() const
558 {
559  return node_.count();
560 }
561 
562 } // end namespace Teuchos
563 
564 
565 // /////////////////////////////////////////////////////////////////////////////////
566 // Inline non-member functions for RCP
567 
568 
569 template<class T>
570 inline
572 Teuchos::rcp( T* p, bool owns_mem )
573 {
574  return RCP<T>(p, owns_mem);
575 }
576 
577 
578 template<class T, class Dealloc_T>
579 inline
581 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc, bool owns_mem )
582 {
583  return RCP<T>(p, dealloc, owns_mem);
584 }
585 
586 
587 template<class T, class Dealloc_T>
588 inline
590 Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc, bool owns_mem )
591 {
592  return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
593 }
594 
595 
596 template<class T>
598 Teuchos::rcpFromRef( T& r )
599 {
600  return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
601 }
602 
603 
604 template<class T>
606 Teuchos::rcpFromUndefRef( T& r )
607 {
608  return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
609 }
610 
611 
612 template<class T, class Embedded>
614 Teuchos::rcpWithEmbeddedObjPreDestroy(
615  T* p, const Embedded &embedded, bool owns_mem
616  )
617 {
618  return rcpWithDealloc(
619  p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
620  );
621 }
622 
623 
624 template<class T, class Embedded>
626 Teuchos::rcpWithEmbeddedObjPostDestroy(
627  T* p, const Embedded &embedded, bool owns_mem
628  )
629 {
630  return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
631 }
632 
633 
634 template<class T, class Embedded>
636 Teuchos::rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem )
637 {
638  return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
639 }
640 
641 
642 template<class T, class ParentT>
644 Teuchos::rcpWithInvertedObjOwnership(const RCP<T> &child,
645  const RCP<ParentT> &parent)
646 {
647  using std::make_pair;
648  return rcpWithEmbeddedObj(child.getRawPtr(), make_pair(child, parent), false);
649 }
650 
651 
652 template<class T>
654 Teuchos::rcpCloneNode(const RCP<T> &p)
655 {
656  if (is_null(p)) {
657  return p;
658  }
659  return rcpWithEmbeddedObj(&*p, p, false);
660 }
661 
662 
663 template<class T>
664 inline
665 bool Teuchos::is_null( const RCP<T> &p )
666 {
667  return p.is_null();
668 }
669 
670 
671 template<class T>
672 inline
673 bool Teuchos::nonnull( const RCP<T> &p )
674 {
675  return !p.is_null();
676 }
677 
678 
679 template<class T>
680 inline
681 bool Teuchos::operator==( const RCP<T> &p, ENull )
682 {
683  return p.get() == NULL;
684 }
685 
686 
687 template<class T>
688 inline
689 bool Teuchos::operator!=( const RCP<T> &p, ENull )
690 {
691  return p.get() != NULL;
692 }
693 
694 
695 template<class T1, class T2>
696 inline
697 bool Teuchos::operator==( const RCP<T1> &p1, const RCP<T2> &p2 )
698 {
699  return p1.access_private_node().same_node(p2.access_private_node());
700 }
701 
702 
703 template<class T1, class T2>
704 inline
705 bool Teuchos::operator!=( const RCP<T1> &p1, const RCP<T2> &p2 )
706 {
707  return !p1.access_private_node().same_node(p2.access_private_node());
708 }
709 
710 
711 template<class T2, class T1>
712 inline
714 Teuchos::rcp_implicit_cast(const RCP<T1>& p1)
715 {
716  // Make the compiler check if the conversion is legal
717  T2 *check = p1.get();
718  return RCP<T2>(check, p1.access_private_node());
719 }
720 
721 
722 template<class T2, class T1>
723 inline
725 Teuchos::rcp_static_cast(const RCP<T1>& p1)
726 {
727  // Make the compiler check if the conversion is legal
728  T2 *check = static_cast<T2*>(p1.get());
729  return RCP<T2>(check, p1.access_private_node());
730 }
731 
732 
733 template<class T2, class T1>
734 inline
736 Teuchos::rcp_const_cast(const RCP<T1>& p1)
737 {
738  // Make the compiler check if the conversion is legal
739  T2 *check = const_cast<T2*>(p1.get());
740  return RCP<T2>(check, p1.access_private_node());
741 }
742 
743 
744 template<class T2, class T1>
745 inline
747 Teuchos::rcp_dynamic_cast(const RCP<T1>& p1, bool throw_on_fail)
748 {
749  if (!is_null(p1)) {
750  T2 *p = NULL;
751  if (throw_on_fail) {
752  p = &dyn_cast<T2>(*p1);
753  }
754  else {
755  // Make the compiler check if the conversion is legal
756  p = dynamic_cast<T2*>(p1.get());
757  }
758  if (p) {
759  return RCP<T2>(p, p1.access_private_node());
760  }
761  }
762  return null;
763 }
764 
765 
766 template<class T1, class T2>
767 inline
768 void Teuchos::set_extra_data( const T1 &extra_data, const std::string& name,
769  const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when, bool force_unique )
770 {
771  p->assert_not_null();
772  p->nonconst_access_private_node().set_extra_data(
773  any(extra_data), name, destroy_when,
774  force_unique );
775 }
776 
777 
778 template<class T1, class T2>
779 inline
780 const T1& Teuchos::get_extra_data( const RCP<T2>& p, const std::string& name )
781 {
782  p.assert_not_null();
783  return any_cast<T1>(
784  p.access_private_node().get_extra_data(
786  )
787  );
788 }
789 
790 
791 template<class T1, class T2>
792 inline
793 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p, const std::string& name )
794 {
795  p.assert_not_null();
796  return any_cast<T1>(
797  p.nonconst_access_private_node().get_extra_data(
799  )
800  );
801 }
802 
803 
804 template<class T1, class T2>
805 inline
807 Teuchos::get_optional_extra_data( const RCP<T2>& p, const std::string& name )
808 {
809  p.assert_not_null();
810  const any *extra_data = p.access_private_node().get_optional_extra_data(
811  TypeNameTraits<T1>::name(), name);
812  if (extra_data)
813  return Ptr<const T1>(&any_cast<T1>(*extra_data));
814  return null;
815 }
816 
817 
818 template<class T1, class T2>
819 inline
821 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
822 {
823  p.assert_not_null();
824  any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
825  TypeNameTraits<T1>::name(), name);
826  if (extra_data)
827  return Ptr<T1>(&any_cast<T1>(*extra_data));
828  return null;
829 }
830 
831 
832 template<class Dealloc_T, class T>
833 inline
834 const Dealloc_T& Teuchos::get_dealloc( const RCP<T>& p )
835 {
836  return get_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
837 }
838 
839 
840 template<class Dealloc_T, class T>
841 inline
842 Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
843 {
845  p.assert_not_null();
847  *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
848  p.access_private_node().node_ptr());
850  dnode==NULL, NullReferenceError
851  ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
852  << "," << TypeNameTraits<T>::name() << ">(p): "
853  << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
854  << "\' does not match actual type of the node \'"
855  << typeName(*p.access_private_node().node_ptr()) << "!"
856  );
857  return dnode->get_nonconst_dealloc();
858 }
859 
860 
861 template<class Dealloc_T, class T>
862 inline
864 Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
865 {
866  p.assert_not_null();
868  RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
869  if(dnode)
870  return ptr(&dnode->get_nonconst_dealloc());
871  return null;
872 }
873 
874 
875 template<class Dealloc_T, class T>
876 inline
878 Teuchos::get_optional_dealloc( const RCP<T>& p )
879 {
880  return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
881 }
882 
883 
884 template<class TOrig, class Embedded, class T>
885 const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
886 {
888  return get_dealloc<Dealloc_t>(p).getObj();
889 }
890 
891 
892 template<class TOrig, class Embedded, class T>
893 Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
894 {
896  return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
897 }
898 
899 
900 template<class TOrig, class Embedded, class T>
902 Teuchos::getOptionalEmbeddedObj( const RCP<T>& p )
903 {
905  const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
906  if (!is_null(dealloc)) {
907  return ptr(&dealloc->getObj());
908  }
909  return null;
910 }
911 
912 
913 template<class TOrig, class Embedded, class T>
915 Teuchos::getOptionalNonconstEmbeddedObj( const RCP<T>& p )
916 {
918  const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
919  if (!is_null(dealloc)) {
920  return ptr(&dealloc->getNonconstObj());
921  }
922  return null;
923 }
924 
925 
926 template<class ParentT, class T>
929 {
930  typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
931  Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
932  return pair.second;
933 }
934 
935 
936 template<class T>
937 std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
938 {
939  out
940  << typeName(p) << "{"
941  << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
942  <<",node="<<p.access_private_node()
943  <<",strong_count="<<p.strong_count()
944  <<",weak_count="<<p.weak_count()
945  <<"}";
946  return out;
947 }
948 
949 
950 #endif // TEUCHOS_RCP_HPP
Null reference error exception class.
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object...
~RCP()
Removes a reference to a dynamically allocated object and possibly deletes the object if owned...
RCP< const T > getConst() const
Return an RCP<const T> version of *this.
int weak_count() const
The weak count for this RCPNode, or 0 if the node is NULL.
RCP(ENull null_arg=null)
Initialize RCP<T> to NULL.
const RCP< T > & debug_assert_not_null() const
Calls assert_not_null() in a debug build.
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->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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Dealloc_T & get_nonconst_dealloc()
Ptr< const T1 > get_optional_extra_data(const RCP< T2 > &p, const std::string &name)
Get a pointer to const extra data (if it exists) associated with a RCP object.
T_To & dyn_cast(T_From &from)
Dynamic casting utility function meant to replace dynamic_cast<T&> 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 set_extra_data(const T1 &extra_data, const std::string &name, const Ptr< RCP< T2 > > &p, EPrePostDestruction destroy_when=POST_DESTROY, bool force_unique=true)
Set extra data associated with a RCP object.
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...
A deallocator class that wraps a simple value object and delegates to another deallocator object...
Modified boost::any class, which is a container for a templated value.
Definition: Teuchos_any.hpp:86
T * operator->() const
Pointer (->) 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.
RCP< T2 > rcp_implicit_cast(const RCP< T1 > &p1)
Implicit cast of underlying RCP type from T1* to T2*.
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.
Templated implementation class of RCPNode that has the responsibility for deleting the reference-coun...
void set_has_ownership()
Give this and other RCP<> objects ownership of the referenced object this->get(). ...
void reset()
Reset to null.
void assert_valid_ptr(const RCPType &rcp_obj) const
const RCP< T > & debug_assert_valid_ptr() const
Calls assert_valid_ptr() in a debug build.
RCPNodeHandle create_strong() const
Return a strong handle.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
Ptr< T > operator()() const
Shorthand for ptr().
ERCPStrength strength() const
The strength of this handle.
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 RCP< T > & assert_not_null() const
Throws NullReferenceError if this->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.
Provides std::map class for deficient platforms.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
Default traits class that just returns typeid(T).name().
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
Handle class that manages the RCPNode&#39;s reference counting.
int strong_count() const
The strong count for this RCPNode, or 0 if the node is NULL.
void has_ownership(bool has_ownership_in)
RCP< ParentT > getInvertedObjOwnershipParent(const RCP< T > &invertedChild)
Get the parent back from an inverted ownership RCP.
int total_count() const
The sum of the weak and string counts.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
Reference-counted pointer class and non-member templated function implementations.
bool is_valid_ptr() const
Whether the underlying pointer is valid.
const T1 & get_extra_data(const RCP< T2 > &p, const std::string &name)
Get a const reference to extra data associated with a RCP object.
Smart reference counting pointer class for automatic garbage collection.
bool same_node(const RCPNodeHandle &node2) const
Whether the RCPNode for which node2 is a handle is the same RCPNode as this object&#39;s RCPNode...
Deletes a (non-owning) RCPNode but not it&#39;s underlying object in case of a throw. ...
RCPNodeHandle create_weak() const
Return a weak handle.
int count() const
The strong count; retained for backwards compatibility.
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<> objects that have a "strong" 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<> objects that have a "weak" 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.