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 {
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 
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_)
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(
785  TypeNameTraits<T1>::name(), name
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(
798  TypeNameTraits<T1>::name(), name
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 {
844  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
845  p.assert_not_null();
846  RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
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();
867  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
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 {
887  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
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 {
895  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
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 {
904  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
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 {
917  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
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>
928 Teuchos::getInvertedObjOwnershipParent(const RCP<T> &invertedChild)
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
const RCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
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(ENull null_arg=null)
Initialize RCP<T> to NULL.
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
T & get(ParameterList &l, const std::string &name)
A shorter name for getParameter().
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.
int total_count() const
Total count (strong_count() + weak_count()).
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.
TEUCHOS_DEPRECATED int count() const
Returns strong_count() [deprecated].
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
T_To & dyn_cast(T_From &from)
Dynamic casting utility function meant to replace dynamic_cast<T&> by throwing a better documented er...
ERCPStrength strength() const
Strength of the pointer.
void release()
Releaes the RCPNode pointer before the destructor is called.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
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 * get() const
Get the raw C++ pointer to the 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.
void swap(Array< T > &a1, Array< T > &a2)
Non-member swap (specializes default std version).
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...
const Ptr< T > & assert_not_null() const
Throws std::logic_error if this->get()==NULL, otherwise returns reference to *this.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
ERCPStrength
Used to specify if the pointer is weak or strong.
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
Provides std::map class for deficient platforms.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to delete it...
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.
TEUCHOSCORE_LIB_DLL_EXPORT void throw_null_ptr_error(const std::string &type_name)
Throw that a pointer passed into an RCP object is null.
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.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
Defines basic traits returning the name of a type in a portable and readable way. ...
void swap(RCPNodeHandle &node_ref)
Swap the contents of node_ref with *this.
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.