Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
RCP_UnitTests.cpp
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Teuchos: Common Tools Package
6 // Copyright (2004) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 */
43 
45 #include "Teuchos_RCP.hpp"
46 #include "Teuchos_getConst.hpp"
48 #ifdef HAVE_TEUCHOS_BOOST
50 #endif
51 #ifdef HAVE_TEUCHOSCORE_CXX11
53 #endif
54 
55 #include "TestClasses.hpp"
56 
58 
59 
60 namespace {
61 
62 
63 using Teuchos::as;
64 using Teuchos::null;
65 using Teuchos::Ptr;
66 using Teuchos::RCP;
67 using Teuchos::rcp;
68 using Teuchos::rcpFromRef;
69 using Teuchos::rcpFromUndefRef;
70 using Teuchos::outArg;
71 using Teuchos::rcpWithEmbeddedObj;
72 using Teuchos::getEmbeddedObj;
73 using Teuchos::getOptionalEmbeddedObj;
74 using Teuchos::getOptionalNonconstEmbeddedObj;
75 using Teuchos::set_extra_data;
76 using Teuchos::get_optional_nonconst_extra_data;
77 using Teuchos::getConst;
82 using Teuchos::RCP_WEAK;
84 
85 
86 TEUCHOS_UNIT_TEST( DeallocNull, free )
87 {
89  d.free(0);
90 }
91 
92 
93 TEUCHOS_UNIT_TEST( RCP, assignSelf_null )
94 {
95  RCP<A> a_rcp;
96  a_rcp = a_rcp;
97  TEST_ASSERT(is_null(a_rcp));
98 }
99 
100 
101 TEUCHOS_UNIT_TEST( RCP, assignSelf_nonnull )
102 {
103  RCP<A> a_rcp(new A);
104  A *a_raw_ptr = a_rcp.getRawPtr();
105  a_rcp = a_rcp;
106  TEST_ASSERT(nonnull(a_rcp));
107  TEST_EQUALITY(a_rcp.getRawPtr(), a_raw_ptr);
108 }
109 
110 
112 {
113  RCP<A> a_rcp(new A);
114  RCP<const A> ca_rcp = a_rcp.getConst();
115  TEST_EQUALITY(a_rcp.getRawPtr(), ca_rcp.getRawPtr());
116 }
117 
118 
119 TEUCHOS_UNIT_TEST( RCP, explicit_null )
120 {
121  RCP<A> a_rcp(0);
122  TEST_ASSERT(is_null(a_rcp));
123 }
124 
125 
126 TEUCHOS_UNIT_TEST( RCP, explicit_dealloc_null )
127 {
128  RCP<A> a_rcp = rcpWithDealloc(static_cast<A*>(0), Teuchos::DeallocNull<A>(), false);
129  TEST_ASSERT(is_null(a_rcp));
130 }
131 
132 
133 TEUCHOS_UNIT_TEST( RCP, explicit_null_null )
134 {
135  RCP<A> a_rcp(0, null);
136  TEST_ASSERT(is_null(a_rcp));
137 }
138 
139 
140 TEUCHOS_UNIT_TEST( RCP, explicit_null_nonnull )
141 {
142  A *a = new A;
143  RCP<A> a_rcp(a, null);
144  TEST_ASSERT(nonnull(a_rcp));
145  delete a;
146 }
147 
148 
149 TEUCHOS_UNIT_TEST( RCP, rcpFromRef_raw_ref )
150 {
151  A a;
152  RCP<A> a_rcp = rcpFromRef(a);
153  TEST_EQUALITY(a_rcp.getRawPtr(), &a);
154  TEST_ASSERT(nonnull(a_rcp));
155 }
156 
157 
158 TEUCHOS_UNIT_TEST( RCP, rcpFromRef_from_rcp )
159 {
160  RCP<A> a_rcp1 = rcp<A>(new A);
161  RCP<A> a_rcp2 = rcpFromRef(*a_rcp1);
162  TEST_EQUALITY(a_rcp2.getRawPtr(), a_rcp1.getRawPtr());
163  if (RCPNodeTracer::isTracingActiveRCPNodes())
164  {
165  TEST_EQUALITY_CONST(a_rcp2.strong_count(), 1);
166  TEST_EQUALITY_CONST(a_rcp2.weak_count(), 1);
167  TEST_EQUALITY_CONST(a_rcp2.has_ownership(), true);
168  }
169  else {
170  TEST_EQUALITY_CONST(a_rcp2.strong_count(), 1);
171  TEST_EQUALITY_CONST(a_rcp2.weak_count(), 0);
172  TEST_EQUALITY_CONST(a_rcp2.has_ownership(), false);
173  }
174 }
175 
176 
178 {
179  A a;
180  RCP<A> a_rcp = rcpFromUndefRef(a);
181  TEST_ASSERT(nonnull(a_rcp));
182 }
183 
184 
185 //
186 // Test rcpCloneNode(...)
187 //
188 
189 
190 TEUCHOS_UNIT_TEST( RCP, rcpCloneNode_null )
191 {
192  ECHO(RCP<RCP<int> > rcp1 = null);
193  ECHO(RCP<RCP<int> > rcp2 = rcpCloneNode(rcp1));
194  TEST_EQUALITY(rcp2, null);
195 }
196 
197 
198 TEUCHOS_UNIT_TEST( RCP, rcpCloneNode_basic )
199 {
200 
201  ECHO(RCP<int> rcp1 = rcp(new int(0)));
202 
203  ECHO(RCP<int> rcp2 = rcpCloneNode(rcp1));
204  TEST_ASSERT(nonnull(rcp2));
205  TEST_EQUALITY(rcp1.strong_count(), 2);
206  TEST_EQUALITY(rcp2.strong_count(), 1);
207 
208  ECHO(RCP<int> rcp3 = rcp2);
209  TEST_EQUALITY(rcp1.strong_count(), 2);
210  TEST_EQUALITY(rcp2.strong_count(), 2);
211  TEST_EQUALITY(rcp3.strong_count(), 2);
212 
213  ECHO(RCP <int> rcp4 = rcp1);
214  TEST_EQUALITY(rcp1.strong_count(), 3);
215  TEST_EQUALITY(rcp2.strong_count(), 2);
216  TEST_EQUALITY(rcp3.strong_count(), 2);
217 
218  ECHO(rcp4 = null);
219  TEST_EQUALITY(rcp1.strong_count(), 2);
220  TEST_EQUALITY(rcp2.strong_count(), 2);
221  TEST_EQUALITY(rcp3.strong_count(), 2);
222  TEST_EQUALITY(rcp4.strong_count(), 0);
223 
224  ECHO(rcp1 = null);
225  TEST_EQUALITY(rcp1.strong_count(), 0);
226  TEST_EQUALITY(rcp2.strong_count(), 2);
227  TEST_EQUALITY(rcp3.strong_count(), 2);
228  TEST_EQUALITY(rcp4.strong_count(), 0);
229 
230  ECHO(rcp2 = null);
231  TEST_EQUALITY(rcp2.strong_count(), 0);
232  TEST_EQUALITY(rcp3.strong_count(), 1);
233 
234  ECHO(rcp3 = null);
235  TEST_EQUALITY(rcp3.strong_count(), 0);
236 
237 }
238 
239 
240 //
241 // Test duplicate owning RCP objects
242 //
243 
244 
245 // Test that shows that we can detect trying to create two owning RCPs
246 // pointing to the same polymorphic object but having different interfaces
247 // with different addresses. This happens due to virtual base classes. Only
248 // works when we have a working getBaseObjVoidPtr(...) function.
249 TEUCHOS_UNIT_TEST( RCP, duplicate_rcp_owning_polymorphic )
250 {
252  ECHO(C *c_ptr = new C);
253  ECHO(A *a_ptr = c_ptr);
254  ECHO(RCP<C> c_rcp = rcp(c_ptr)); // Okay
255 #if defined(TEUCHOS_DEBUG) && defined(HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR)
256  // With determine they are pointed to the same object!
257  TEST_THROW(RCP<A> a_rcp = rcp(a_ptr), DuplicateOwningRCPError);
258 #else
259  // Will not determine they are point to the same object!
260  ECHO(RCP<A> a_rcp = rcp(a_ptr));
261  TEST_EQUALITY(a_rcp.getRawPtr(), a_ptr);
262  ECHO(a_rcp.release()); // Better or we will get a segfault!
263 #endif
264 }
265 
266 
267 // Test that shows that we can detect trying to create two owning RCPs
268 // pointing to the same polymorphic object with the same type and therefore
269 // the same address. This works even if these use virtual base classes. This
270 // works even without a working getBaseObjVoidPtr(...) function.
271 TEUCHOS_UNIT_TEST( RCP, duplicate_rcp_owning_polymorphic_different_addr )
272 {
274  ECHO(A *a_ptr1 = new C);
275  ECHO(A *a_ptr2 = a_ptr1);
276  ECHO(RCP<A> a_rcp1 = rcp(a_ptr1)); // Okay
277 #if defined(TEUCHOS_DEBUG)
278  // With determine they are pointed to the same object!
279  TEST_THROW(RCP<A> a_rcp2 = rcp(a_ptr2), DuplicateOwningRCPError);
280 #else
281  // Will not determine they are point to the same object!
282  ECHO(RCP<A> a_rcp2 = rcp(a_ptr2));
283  TEST_EQUALITY(a_rcp2.getRawPtr(), a_ptr2);
284  ECHO(a_rcp2.release()); // Better or we will get a segfault!
285 #endif
286 }
287 
288 
289 // Test that shows that we can always detect trying to create two owning RCPs
290 // pointing to the same nonpolymorphic object having different interfaces but
291 // the same address (single non-virtual inheritance). Works just fine without
292 // a working getBaseObjVoidPtr(...) function.
293 TEUCHOS_UNIT_TEST( RCP, duplicate_rcp_owning_nonpolymorphic_same_addr )
294 {
296  ECHO(E *e_ptr = new E);
297  ECHO(E *d_ptr = e_ptr);
298  ECHO(RCP<E> e_rcp = rcp(e_ptr)); // Okay
299 #if defined(TEUCHOS_DEBUG)
300  // With determine they are pointed to the same object even without support
301  // for getBaseObjVoidPtr(...) because no dynamic_cast is needed.
302  TEST_THROW(RCP<D> d_rcp = rcp(d_ptr), DuplicateOwningRCPError);
303 #else
304  // Will not determine they are point to the same object!
305  ECHO(RCP<D> d_rcp = rcp(d_ptr));
306  TEST_EQUALITY(d_rcp.getRawPtr(), d_ptr);
307  ECHO(d_rcp.release()); // Better or we will get a segfault!
308 #endif
309 }
310 
311 
312 //
313 // These next tests shows that we can detect when two RCPs are create to the same
314 // object, one owning and the other non-owning. When we have a working
315 // getBaseObjVoidPtr(...) function, the new non-owning RCP will actually be a
316 // weak RCP that can be used to detect circular dependencies.
317 //
318 
319 
320 // rcp
321 
322 
323 TEUCHOS_UNIT_TEST( RCP, rcp_duplicate_rcp_nonowning_polymorphic_different_addr )
324 {
326  ECHO(RCP<C> c_rcp(new C));
327  ECHO(A &a_ref = *c_rcp);
328  ECHO(RCP<A> a_rcp = rcp(&a_ref, false));
329  ECHO(c_rcp = null);
330 #if defined(TEUCHOS_DEBUG) && defined(HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR)
331  TEST_THROW(a_rcp->A_g(), DanglingReferenceError);
332 #else
333  TEST_NOTHROW(a_rcp.getRawPtr());
334 #endif
335 }
336 
337 
338 TEUCHOS_UNIT_TEST( RCP, rcp_duplicate_rcp_nonowning_polymorphic_same_addr )
339 {
341  ECHO(RCP<A> a_rcp1(new C));
342  ECHO(A &a_ref = *a_rcp1);
343  ECHO(RCP<A> a_rcp2 = rcp(&a_ref, false));
344  ECHO(a_rcp1 = null);
345 #if defined(TEUCHOS_DEBUG)
346  TEST_THROW(a_rcp2->A_g(), DanglingReferenceError);
347 #else
348  TEST_NOTHROW(a_rcp2.getRawPtr());
349 #endif
350 }
351 
352 
353 TEUCHOS_UNIT_TEST( RCP, rcp_duplicate_rcp_nonowning_nonpolymorphic )
354 {
356  ECHO(RCP<E> e_rcp(new E));
357  ECHO(D &d_ref = *e_rcp);
358  ECHO(RCP<D> d_rcp = rcp(&d_ref, false));
359  ECHO(e_rcp = null);
360 #if defined(TEUCHOS_DEBUG)
361  TEST_THROW(d_rcp->D_g(), DanglingReferenceError);
362 #else
363  TEST_NOTHROW(d_rcp.getRawPtr());
364 #endif
365 }
366 
367 
368 // rcpFromRef
369 
370 
371 TEUCHOS_UNIT_TEST( RCP, rcpFromRef_duplicate_rcp_nonowning_polymorphic_different_addr )
372 {
374  ECHO(RCP<C> c_rcp(new C));
375  ECHO(A &a_ref = *c_rcp);
376  ECHO(RCP<A> a_rcp = rcpFromRef(a_ref));
377  ECHO(c_rcp = null);
378 #if defined(TEUCHOS_DEBUG) && defined(HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR)
379  TEST_THROW(a_rcp->A_g(), DanglingReferenceError);
380 #else
381  TEST_NOTHROW(a_rcp.getRawPtr());
382 #endif
383 }
384 
385 
386 TEUCHOS_UNIT_TEST( RCP, rcpFromRef_duplicate_rcp_nonowning_polymorphic_same_addr )
387 {
389  ECHO(RCP<A> a_rcp1(new C));
390  ECHO(A &a_ref = *a_rcp1);
391  ECHO(RCP<A> a_rcp2 = rcpFromRef(a_ref));
392  ECHO(a_rcp1 = null);
393 #if defined(TEUCHOS_DEBUG)
394  TEST_THROW(a_rcp2->A_g(), DanglingReferenceError);
395 #else
396  TEST_NOTHROW(a_rcp2.getRawPtr());
397 #endif
398 }
399 
400 
401 TEUCHOS_UNIT_TEST( RCP, rcpFromRef_duplicate_rcp_nonowning_nonpolymorphic )
402 {
404  ECHO(RCP<E> e_rcp(new E));
405  ECHO(D &d_ref = *e_rcp);
406  ECHO(RCP<D> d_rcp = rcpFromRef(d_ref));
407  ECHO(e_rcp = null);
408 #if defined(TEUCHOS_DEBUG)
409  TEST_THROW(d_rcp->D_g(), DanglingReferenceError);
410 #else
411  TEST_NOTHROW(d_rcp.getRawPtr());
412 #endif
413 }
414 
415 
416 // rcpFromUndefRef (Can never detect dangling references)
417 
418 
419 TEUCHOS_UNIT_TEST( RCP, rcpFromUndefRef_duplicate_rcp_nonowning_polymorphic_same_addr )
420 {
422  ECHO(RCP<A> a_rcp1(new C));
423  ECHO(A &a_ref = *a_rcp1);
424  ECHO(RCP<A> a_rcp2 = rcpFromUndefRef(a_ref));
425  ECHO(a_rcp1 = null);
426  TEST_NOTHROW(a_rcp2.getRawPtr());
427 }
428 
429 
430 //
431 // extra data and embedded objects tests
432 //
433 
434 
436 {
437  RCP<A> a_rcp = rcp(new A);
438  set_extra_data( as<int>(1), "blob", outArg(a_rcp) );
439  TEST_EQUALITY_CONST(*get_optional_nonconst_extra_data<int>(a_rcp, "blob"), as<int>(1));
440 }
441 
442 
443 TEUCHOS_UNIT_TEST( RCP, getOptionalEmbeddedObj_null )
444 {
445  ECHO(RCP<A> a_rcp = rcp(new A));
446  const Ptr<const RCP<C> > c_ptr_rcp_1 =
447  getOptionalEmbeddedObj<A, RCP<C> >(a_rcp);
448  TEST_EQUALITY_CONST( c_ptr_rcp_1, null );
449  const Ptr<RCP<C> > c_ptr_rcp_2 =
450  getOptionalNonconstEmbeddedObj<A, RCP<C> >(a_rcp);
451  TEST_EQUALITY_CONST( c_ptr_rcp_2, null );
452 }
453 
454 
455 TEUCHOS_UNIT_TEST( RCP, getOptionalEmbeddedObj_default )
456 {
457 
458  ECHO(RCP<C> c_rcp = rcp(new C));
459  ECHO(RCP<A> a_rcp = rcpWithEmbeddedObj(new A, c_rcp));
460 
461  Ptr<const RCP<C> > c_ptr_rcp_1 =
462  getOptionalEmbeddedObj<A, RCP<C> >(a_rcp);
463  TEST_EQUALITY_CONST( is_null(c_ptr_rcp_1), false );
464  TEST_EQUALITY( (*c_ptr_rcp_1).getRawPtr(), c_rcp.getRawPtr() );
465  TEST_EQUALITY( (*c_ptr_rcp_1)->C_g(), C_g_return );
466 
467  Ptr<RCP<C> > c_ptr_rcp_2 =
468  getOptionalNonconstEmbeddedObj<A, RCP<C> >(a_rcp);
469  TEST_EQUALITY_CONST( is_null(c_ptr_rcp_2), false );
470  TEST_EQUALITY( (*c_ptr_rcp_2).getRawPtr(), c_rcp.getRawPtr() );
471  TEST_EQUALITY( (*c_ptr_rcp_2)->C_f(), C_f_return );
472 
473 }
474 
475 
476 TEUCHOS_UNIT_TEST( RCP, reset_null )
477 {
478  RCP<A> a_rcp = rcp(new A);
479  a_rcp.reset();
480  TEST_ASSERT(is_null(a_rcp));
481 }
482 
483 
484 TEUCHOS_UNIT_TEST( RCP, reset_nonnull )
485 {
486  RCP<A> a_rcp = rcp(new A);
487  C* c_rawp = new C;
488  a_rcp.reset(c_rawp);
489  A* a_rawp = c_rawp;
490  TEST_EQUALITY( a_rcp.getRawPtr(), a_rawp );
491 }
492 
493 
495 {
496  ECHO(RCP<A> a_rcp = rcp(new A));
497  TEST_EQUALITY_CONST(is_null(a_rcp), false);
498  TEST_EQUALITY_CONST(nonnull(a_rcp), true);
499  ECHO(a_rcp = null);
500  TEST_EQUALITY_CONST(is_null(a_rcp), true);
501  TEST_EQUALITY_CONST(nonnull(a_rcp), false);
502 }
503 
504 
505 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCP, weakDelete, T )
506 {
507 
508  ECHO(RCP<T> rcp_strong = rcp(new T));
509 
510  TEST_EQUALITY_CONST( rcp_strong.strength(), RCP_STRONG );
511  TEST_EQUALITY_CONST( rcp_strong.is_null(), false );
512  TEST_EQUALITY_CONST( rcp_strong.strong_count(), 1 );
513  TEST_EQUALITY_CONST( rcp_strong.weak_count(), 0 );
514  TEST_EQUALITY_CONST( rcp_strong.total_count(), 1 );
515 
516  ECHO(RCP<T> rcp_weak1 = rcp_strong.create_weak());
517 
518  TEST_EQUALITY_CONST( rcp_weak1.strength(), RCP_WEAK );
519  TEST_EQUALITY_CONST( rcp_weak1.is_null(), false );
520  TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 1 );
521  TEST_EQUALITY_CONST( rcp_weak1.weak_count(), 1 );
522  TEST_EQUALITY_CONST( rcp_weak1.total_count(), 2 );
523 
524  TEST_EQUALITY_CONST( rcp_strong.strong_count(), 1 );
525  TEST_EQUALITY_CONST( rcp_strong.is_null(), false );
526  TEST_EQUALITY_CONST( rcp_strong.weak_count(), 1 );
527  TEST_EQUALITY_CONST( rcp_strong.total_count(), 2 );
528 
529  TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_strong), true );
530 
531  TEST_EQUALITY( rcp_weak1.get(), rcp_weak1.getRawPtr() );
532  TEST_EQUALITY( rcp_weak1.get(), rcp_strong.get() );
533  TEST_EQUALITY( rcp_weak1.getRawPtr(), rcp_strong.getRawPtr() );
534 
535  ECHO(RCP<T> rcp_weak2 = rcp_weak1);
536 
537  TEST_EQUALITY_CONST( rcp_weak2.strength(), RCP_WEAK );
538  TEST_EQUALITY_CONST( rcp_weak2.is_null(), false );
539  TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 1 );
540  TEST_EQUALITY_CONST( rcp_weak2.weak_count(), 2 );
541  TEST_EQUALITY_CONST( rcp_weak2.total_count(), 3 );
542 
543  TEST_EQUALITY_CONST( rcp_strong.strong_count(), 1 );
544  TEST_EQUALITY_CONST( rcp_strong.is_null(), false );
545  TEST_EQUALITY_CONST( rcp_strong.weak_count(), 2 );
546  TEST_EQUALITY_CONST( rcp_strong.total_count(), 3 );
547 
548  TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_strong), true );
549  TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_weak2), true );
550  TEST_EQUALITY_CONST( rcp_weak2.shares_resource(rcp_strong), true );
551 
552  TEST_EQUALITY( rcp_weak2.get(), rcp_strong.get() );
553  TEST_EQUALITY( rcp_weak2.getRawPtr(), rcp_strong.getRawPtr() );
554 
555  ECHO(rcp_strong = null); // This deletes the underlying object of type T!
556 
557  TEST_EQUALITY_CONST( rcp_strong.strength(), RCP_STRONG );
558  TEST_EQUALITY_CONST( rcp_strong.is_null(), true );
559  TEST_EQUALITY_CONST( rcp_strong.strong_count(), 0 );
560  TEST_EQUALITY_CONST( rcp_strong.strong_count(), 0 );
561  TEST_EQUALITY_CONST( rcp_strong.weak_count(), 0 );
562  TEST_EQUALITY_CONST( rcp_strong.total_count(), 0 );
563  TEST_EQUALITY_CONST( rcp_strong.is_valid_ptr(), true );
564 
565  TEST_EQUALITY_CONST( rcp_strong.shares_resource(rcp_weak1), false );
566  TEST_EQUALITY_CONST( rcp_strong.shares_resource(rcp_weak2), false );
567 
568  TEST_EQUALITY_CONST( rcp_weak1.has_ownership(), true );
569  TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
570  TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
571  TEST_EQUALITY_CONST( rcp_weak1.weak_count(), 2 );
572  TEST_EQUALITY_CONST( rcp_weak1.total_count(), 2 );
573  TEST_EQUALITY_CONST( rcp_weak1.is_valid_ptr(), false );
574 
575  TEST_EQUALITY_CONST( rcp_weak2.has_ownership(), true );
576  TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
577  TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
578  TEST_EQUALITY_CONST( rcp_weak2.weak_count(), 2 );
579  TEST_EQUALITY_CONST( rcp_weak2.total_count(), 2 );
580  TEST_EQUALITY_CONST( rcp_weak2.is_valid_ptr(), false );
581 
582  TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_weak2), true );
583 
584  ECHO(rcp_weak1.assert_not_null()); // Does not throw!
585  ECHO(rcp_weak2.assert_not_null()); // Does not throw!
586 
587  TEST_THROW( rcp_weak1.assert_valid_ptr(), DanglingReferenceError );
588 #ifdef TEUCHOS_DEBUG
589  TEST_THROW( rcp_weak1.operator->(), DanglingReferenceError );
590  TEST_THROW( *rcp_weak1, DanglingReferenceError );
591  TEST_THROW( rcp_weak1.create_weak(), DanglingReferenceError );
592  TEST_THROW( rcp_weak1.get(), DanglingReferenceError );
593  TEST_THROW( rcp_weak1.getRawPtr(), DanglingReferenceError );
594  TEST_THROW( rcp_weak1(), DanglingReferenceError );
595  TEST_THROW( rcp_weak1.release(), DanglingReferenceError );
596 #endif // TEUCHOS_DEBUG
597 
598  ECHO(rcp_weak1 = null); // Just deicrements weak count!
599 
600  TEST_EQUALITY_CONST( rcp_weak1.strength(), RCP_STRONG );
601  TEST_EQUALITY_CONST( rcp_weak1.is_null(), true );
602  TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
603  TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
604  TEST_EQUALITY_CONST( rcp_weak1.weak_count(), 0 );
605  TEST_EQUALITY_CONST( rcp_weak1.total_count(), 0 );
606  TEST_EQUALITY_CONST( rcp_weak1.is_valid_ptr(), true );
607 
608  TEST_EQUALITY_CONST( rcp_weak2.has_ownership(), true );
609  TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
610  TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
611  TEST_EQUALITY_CONST( rcp_weak2.weak_count(), 1 );
612  TEST_EQUALITY_CONST( rcp_weak2.total_count(), 1 );
613  TEST_EQUALITY_CONST( rcp_weak2.is_valid_ptr(), false );
614 
615  TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_weak2), false );
616 
617  TEST_THROW( rcp_weak2.assert_valid_ptr(), DanglingReferenceError );
618 #ifdef TEUCHOS_DEBUG
619  TEST_THROW( rcp_weak2.operator->(), DanglingReferenceError );
620  TEST_THROW( *rcp_weak2, DanglingReferenceError );
621  TEST_THROW( rcp_weak2.create_weak(), DanglingReferenceError );
622  TEST_THROW( rcp_weak2.get(), DanglingReferenceError );
623  TEST_THROW( rcp_weak2.getRawPtr(), DanglingReferenceError );
624  TEST_THROW( rcp_weak2(), DanglingReferenceError );
625  TEST_THROW( rcp_weak2.release(), DanglingReferenceError );
626 #endif // TEUCHOS_DEBUG
627 
628 }
629 
630 
631 TEUCHOS_UNIT_TEST( RCP, weak_strong )
632 {
633 
634  ECHO(RCP<A> rcp1(rcp(new A)));
635  TEST_EQUALITY_CONST( rcp1.strength(), RCP_STRONG );
636 
637  ECHO(RCP<A> rcp2 = rcp1.create_weak());
638 
639  TEST_EQUALITY_CONST( rcp2.strength(), RCP_WEAK );
640  TEST_EQUALITY_CONST( rcp1.strong_count(), 1 );
641  TEST_EQUALITY_CONST( rcp1.weak_count(), 1 );
642  TEST_EQUALITY_CONST( rcp2.strong_count(), 1 );
643  TEST_EQUALITY_CONST( rcp2.weak_count(), 1 );
644 
645  ECHO(RCP<A> rcp3 = rcp2.create_strong());
646 
647  TEST_EQUALITY_CONST( rcp3.strength(), RCP_STRONG );
648  TEST_EQUALITY_CONST( rcp1.strong_count(), 2 );
649  TEST_EQUALITY_CONST( rcp1.weak_count(), 1 );
650  TEST_EQUALITY_CONST( rcp2.strong_count(), 2 );
651  TEST_EQUALITY_CONST( rcp2.weak_count(), 1 );
652 
653  // This will make the underlying object A gets deleted!
654  ECHO(rcp1 = null);
655  ECHO(rcp3 = null);
656 
657  ECHO(rcp2 = null); // Should make the underlying node go away
658 
659 }
660 
661 
662 //
663 // circularReference
664 //
665 
666 
667 TEUCHOS_UNIT_TEST( RCP, circularReference_a_then_c )
668 {
669 
670  //TEST_EQUALITY_CONST(Teuchos::numActiveRCPNodes(), 0);
671 
672  {
673 
674  // Create objects a and c
675 
676  ECHO(RCP<A> a = rcp(new A));
677  ECHO(RCP<C> c = rcp(new C));
678 
679  // Create a circular reference where 'a' owns 'c' strongly but 'c' only
680  // owns 'a' weakly.
681 
682  ECHO(a->set_C(c));
683  ECHO(c->set_A(a.create_weak()));
684 
685 #ifdef TEUCHOS_DEBUG
686  ECHO(c->call_A_on_delete(true));
687  // Here, we set 'c' to call 'a' when it is deleted which will result in an
688  // exception being thrown in a call to delete. NOTE: It is *very* bad
689  // practice to allow exceptions to be thrown from destructors but I am
690  // allowing it so that I can detect such bad bahavior below!
691 #endif
692 
694  TEST_EQUALITY( c->call_A_g(), A_g_return );
695 
696  // Remove 'a' first and then remove 'c'. Since 'a' is only weakly held by
697  // 'c', this will result in 'a' being deleted right away. In this case,
698  // if anyone tries to access 'a' after this (like 'c' in its destructor),
699  // then an exception will get thrown in debug mode!
700 
701  ECHO(a = null);
702 
703  // Now, remove 'c'. In this case, since 'a' has already been deleted and
704  // 'c' is going to try to call 'a' on its way out, this will thrown an
705  // exception.
706 
707 #ifdef TEUCHOS_DEBUG
708 
709  TEST_THROW(c = null, DanglingReferenceError);
710  // NOTE: Above, operator==(...) exhibits the 'strong' guarantee!
711 
712  // Since an exception was thrown, the 'c' object never got deleted.
713  // Therefore, we need to disable 'c' calling 'a' on delete and the object
714  // will get cleaned up correctly when this function exists (I hope).
715  ECHO(c->call_A_on_delete(false));
716 
717  ECHO(c = null); // All memory should be cleaned up here!
718 
719 #endif // TEUCHOS_DEBUG
720 
721  }
722 
723 }
724 
725 
726 TEUCHOS_UNIT_TEST( RCP, circularReference_c_then_a )
727 {
728 
729  {
730 
731  // Create objects a and c
732 
733  ECHO(RCP<A> a = rcp(new A));
734  ECHO(RCP<C> c = rcp(new C));
735 
736  // Create a circular reference where 'a' owns 'c' strongly but 'c' only
737  // owns 'a' weakly.
738 
739  ECHO(a->set_C(c));
740  ECHO(c->set_A(a.create_weak()));
741 
742  ECHO(c->call_A_on_delete(false));
743  // Here, we set 'c' to not call 'a' when it is deleted. It turns out that
744  // the set of calls to delete and destructors that takes place is very
745  // complex and in order to avoid trouble, an object that holds an RCP to
746  // another object weakly should *never* try to call any members on the
747  // wrapped object as it gets deleted!
748 
750  TEST_EQUALITY( c->call_A_g(), A_g_return );
751 
752  // Remove 'c' first and then remove 'a' implicitly at the end of the
753  // block. Since 'c' is held strongly by 'a' and since we are keeping the
754  // strong pointer for 'a' alive, we can call functions on 'a' all we want
755  // with no fear of accessing dead memory.
756 
757  ECHO(c = null);
758 
759  TEST_EQUALITY( a->call_C_f(), C_f_return ); // C is still alive!
760 
761  // Finally, when 'a' goes away implicitly, it will take 'c' with it. In
762  // the complex set of nested calls that take place due to the circular
763  // reference, everything will get cleaned up correctly. Also, if any
764  // client code where to try to access an object as it is being deleted, an
765  // exception will get thrown and no memory error will occur (unless an
766  // abort(...) is called when an exception gets thrown from a destructor
767  // when an exception is already active).
768 
769  }
770 
771 }
772 
773 
774 TEUCHOS_UNIT_TEST( RCP, circularReference_self )
775 {
776  {
777  // Create one 'c' object
778  ECHO(RCP<C> c = rcp(new C));
779  // Create a weak circular reference where 'c' points back to itself
780  ECHO(c->set_A(c.create_weak()));
781  // Now, try to set 'c' to null.
782  ECHO(c = null); // All memory should be cleaned up here!
783  }
784 }
785 
786 
787 TEUCHOS_UNIT_TEST( RCP, danglingPtr1 )
788 {
789  ECHO(RCP<A> a_rcp = rcp(new A));
790  ECHO(Ptr<A> a_ptr = a_rcp());
791  ECHO(A *badPtr = a_rcp.getRawPtr());
792  ECHO(a_rcp = null);
793 #ifdef TEUCHOS_DEBUG
794  TEST_THROW( *a_ptr, DanglingReferenceError );
795  (void)badPtr;
796 #else
797  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
798 #endif
799 }
800 
801 
802 TEUCHOS_UNIT_TEST( RCP, danglingPtr2 )
803 {
804  ECHO(Ptr<A> a_ptr);
805  ECHO(A *badPtr = 0);
806  {
807  ECHO(RCP<A> a_rcp = rcp(new A));
808  ECHO(badPtr = a_rcp.getRawPtr());
809  ECHO(a_ptr = a_rcp.ptr());
810  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
811  }
812 #ifdef TEUCHOS_DEBUG
813  TEST_THROW( *a_ptr, DanglingReferenceError );
814  (void)badPtr;
815 #else
816  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
817 #endif
818 }
819 
820 
821 TEUCHOS_UNIT_TEST( RCP, danglingPtr3 )
822 {
823  ECHO(Ptr<A> a_ptr);
824  ECHO(A *badPtr = 0);
825  {
826  ECHO(RCP<A> a_rcp = rcp(new A));
827  ECHO(badPtr = a_rcp.getRawPtr());
828  ECHO(Ptr<A> a_ptr2(a_rcp.ptr()));
829  ECHO(Ptr<A> a_ptr3(a_ptr2));
830  ECHO(a_ptr = a_ptr3);
831  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
832  }
833 #ifdef TEUCHOS_DEBUG
834  TEST_THROW( *a_ptr, DanglingReferenceError );
835  (void)badPtr;
836 #else
837  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
838 #endif
839 }
840 
841 
842 TEUCHOS_UNIT_TEST( RCP, danglingPtr4 )
843 {
844  ECHO(Ptr<A> a_ptr);
845  ECHO(A *badPtr = 0);
846  {
847  ECHO(RCP<C> c_rcp = rcp(new C));
848  ECHO(badPtr = c_rcp.getRawPtr());
849  ECHO(Ptr<A> a_ptr2(c_rcp.ptr()));
850  ECHO(a_ptr = a_ptr2);
851  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
852  }
853 #ifdef TEUCHOS_DEBUG
854  TEST_THROW( *a_ptr, DanglingReferenceError );
855  (void)badPtr;
856 #else
857  TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
858 #endif
859 }
860 
861 
862 #ifdef TEUCHOS_DEBUG
863 
864 /* ToDo: Comment this back in once I have everything working
865 
866 // Test that the RCPNode tracing machinary can detect if an owning RCPNode is
867 // being created that would result in a double delete.
868 TEUCHOS_UNIT_TEST( RCP, multiRcpCreateError )
869 {
870  C *c_ptr = new C;
871 #if !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
872  Teuchos::setTracingActiveRCPNodes(true);
873 #endif
874  RCP<C> c_rcp = rcp(c_ptr); // Okay
875  RCP<C> c_rcp2;
876  TEST_THROW(c_rcp2 = rcp(c_ptr), DuplicateOwningRCPError);
877 #if !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
878  Teuchos::setTracingActiveRCPNodes(false);
879 #endif
880  // Clean up memory so no leaks and not double deletes no matter what.
881  c_rcp.release();
882  c_rcp2.release();
883  delete c_ptr;
884 }
885 
886 */
887 
888 #endif // TEUCHOS_DEBUG
889 
890 
891 //
892 // invertObjectOwnership
893 //
894 
895 
896 RCP<C> createCAFactory()
897 {
898  RCP<C> c = rcp(new C);
899  c->set_A(rcp(new A));
900  return c;
901 }
902 
903 
904 RCP<A> createACFactory()
905 {
906  RCP<C> c = createCAFactory();
907  return Teuchos::rcpWithInvertedObjOwnership(c->get_A(), c);
908 }
909 
910 
911 RCP<C> extractCFromA(const RCP<A> &a)
912 {
913  return Teuchos::getInvertedObjOwnershipParent<C>(a);
914 }
915 
916 
917 TEUCHOS_UNIT_TEST( RCP, invertObjectOwnership_basic )
918 {
919  RCP<A> a = createACFactory();
920  RCP<C> c = extractCFromA(a);
921  TEST_EQUALITY_CONST( a.strong_count(), 1 );
922  TEST_EQUALITY_CONST( c->get_A().strong_count(), 3 );
923  TEST_ASSERT( !a.shares_resource(c->get_A()) );
924  TEST_EQUALITY( a.getRawPtr(), c->get_A().getRawPtr() );
925  TEST_EQUALITY( a->A_g(), A_g_return );
926  TEST_EQUALITY( c->C_g(), C_g_return );
927 }
928 
929 
930 // This unit test shows that you can remove the RCP in the C object
931 // and the A object will still live on.
932 TEUCHOS_UNIT_TEST( RCP, invertObjectOwnership_remove_A )
933 {
934  RCP<A> a = createACFactory();
935  extractCFromA(a)->set_A(null);
936  RCP<C> c = extractCFromA(a);
937  TEST_EQUALITY_CONST( a.strong_count(), 1 );
938  TEST_EQUALITY_CONST( c->get_A(), null );
939  TEST_EQUALITY( a->A_g(), A_g_return );
940  TEST_EQUALITY( c->C_g(), C_g_return );
941 }
942 
943 
944 //
945 // createRCPWithBadDealloc
946 //
947 
948 
949 RCP<A> createRCPWithBadDealloc()
950 {
951  return rcp(new A[1]); // Will use delete but should use delete []!
952 }
953 
954 
955 template<typename T>
956 class DeallocArrayDeleteExtraData {
957 public:
958  static RCP<DeallocArrayDeleteExtraData<T> > create(T *ptr)
959  { return rcp(new DeallocArrayDeleteExtraData(ptr)); }
960  ~DeallocArrayDeleteExtraData() { delete [] ptr_; }
961 private:
962  T *ptr_;
963  DeallocArrayDeleteExtraData(T *ptr) : ptr_(ptr) {}
964  // Not defined!
965  DeallocArrayDeleteExtraData();
966  DeallocArrayDeleteExtraData(const DeallocArrayDeleteExtraData&);
967  DeallocArrayDeleteExtraData& operator=(const DeallocArrayDeleteExtraData&);
968 };
969 
970 
971 // This unit test shows how you can use extra data to fix a bad deallocation
972 // policy
973 TEUCHOS_UNIT_TEST( RCP, Fix_createRCPWithBadDealloc )
974 {
975  using Teuchos::inOutArg;
976  using Teuchos::set_extra_data;
977  // Create object with bad deallocator
978  RCP<A> a = createRCPWithBadDealloc();
979  TEST_ASSERT(nonnull(a));
980  // Disable default (incorrect) dealloc and set a new deallocation policy as extra data!
981  a.release();
982  set_extra_data( DeallocArrayDeleteExtraData<A>::create(a.getRawPtr()), "dealloc",
983  inOutArg(a));
984 }
985 
986 
987 //
988 // Test RCP/boost::shared_ptr covnersions
989 //
990 
991 
992 #ifdef HAVE_TEUCHOS_BOOST
993 
994 
995 TEUCHOS_UNIT_TEST( boost_shared_ptr, nonnull_is_null )
996 {
997  using boost::shared_ptr;
998  ECHO(shared_ptr<A> a_sptr(new A));
999  TEST_EQUALITY_CONST(is_null(a_sptr), false);
1000  TEST_EQUALITY_CONST(nonnull(a_sptr), true);
1001  ECHO(a_sptr = shared_ptr<A>());
1002  TEST_EQUALITY_CONST(is_null(a_sptr), true);
1003  TEST_EQUALITY_CONST(nonnull(a_sptr), false);
1004 }
1005 
1006 
1007 #endif // HAVE_TEUCHOS_BOOST
1008 
1009 
1010 //
1011 // Test RCP/std::shared_ptr covnersions
1012 //
1013 
1014 
1015 #ifdef HAVE_TEUCHOSCORE_CXX11
1016 
1017 
1018 TEUCHOS_UNIT_TEST( std_shared_ptr, nonnull_is_null )
1019 {
1020  using std::shared_ptr;
1021  ECHO(shared_ptr<A> a_sptr(new A));
1022  TEST_EQUALITY_CONST(Teuchos::is_null(a_sptr), false);
1023  TEST_EQUALITY_CONST(Teuchos::nonnull(a_sptr), true);
1024  ECHO(a_sptr = shared_ptr<A>());
1025  TEST_EQUALITY_CONST(Teuchos::is_null(a_sptr), true);
1026  TEST_EQUALITY_CONST(Teuchos::nonnull(a_sptr), false);
1027 }
1028 
1029 
1030 TEUCHOS_UNIT_TEST( std_shared_ptr, convert_to_RCP_null )
1031 {
1032  const std::shared_ptr<A> a_sptr1;
1033  const RCP<A> a_rsptr1 = rcp(a_sptr1);
1034  TEST_EQUALITY( a_rsptr1.get(), a_sptr1.get() );
1035  TEST_ASSERT(is_null(a_rsptr1));
1036 
1037  const std::shared_ptr<A> a_sptr2 = get_shared_ptr(a_rsptr1);
1038  TEST_EQUALITY( a_sptr1.get(), a_sptr1.get() );
1039  TEST_ASSERT(Teuchos::is_null(a_sptr2));
1040 }
1041 
1042 
1043 TEUCHOS_UNIT_TEST( std_shared_ptr, convert_to_RCP )
1044 {
1045  const std::shared_ptr<A> a_sptr1(new C());
1046  const RCP<A> a_rsptr1 = rcp(a_sptr1);
1047  TEST_EQUALITY( a_rsptr1.get(), a_sptr1.get() );
1048  TEST_EQUALITY( a_rsptr1.getRawPtr(), a_sptr1.get() );
1049  TEST_EQUALITY( a_rsptr1.get(), a_rsptr1.getRawPtr() );
1050 
1051  const std::shared_ptr<A> a_sptr2 = get_shared_ptr(a_rsptr1);
1052  TEST_EQUALITY( a_sptr1.get(), a_sptr1.get() );
1053  // NOTE: There is no portable way to check that two std::shared_ptr objects
1054  // share the same underlying shared node :-(
1055 }
1056 
1057 
1058 TEUCHOS_UNIT_TEST( std_shared_ptr, convert_from_RCP_null )
1059 {
1060  const RCP<A> a_rcp1;
1061  const std::shared_ptr<A> a_sptr1(get_shared_ptr(a_rcp1));
1062  TEST_EQUALITY( a_rcp1.get(), a_sptr1.get() );
1063  TEST_ASSERT(Teuchos::is_null(a_sptr1));
1064 
1065  const RCP<A> a_rcp2 = rcp(a_sptr1);
1066  TEST_EQUALITY(a_rcp2.get(), a_sptr1.get());
1067  TEST_ASSERT(is_null(a_rcp2));
1068 }
1069 
1070 
1071 TEUCHOS_UNIT_TEST( std_shared_ptr, convert_from_RCP )
1072 {
1073  const RCP<A> a_rcp1(new C());
1074  const std::shared_ptr<A> a_sptr1(get_shared_ptr(a_rcp1));
1075  TEST_EQUALITY( a_rcp1.get(), a_sptr1.get() );
1076  TEST_EQUALITY( a_rcp1.getRawPtr(), a_sptr1.get() );
1077  TEST_EQUALITY( a_sptr1.get(), a_rcp1.getRawPtr() );
1078 
1079  const RCP<A> a_rcp2 = rcp(a_sptr1);
1080  TEST_EQUALITY( a_rcp2.get(), a_sptr1.get() );
1081  TEST_EQUALITY( a_rcp2.get(), a_rcp1.get() );
1082  TEST_ASSERT( a_rcp1.shares_resource(a_rcp2) );
1083 }
1084 
1085 
1086 #ifdef TEUCHOS_DEBUG
1087 
1088 
1089 TEUCHOS_UNIT_TEST( std_shared_ptr, convert_from_RCP_lookup_node )
1090 {
1091  const RCP<A> a_rcp1(new C());
1092  const std::shared_ptr<A> a_sptr1(get_shared_ptr(a_rcp1));
1093  TEST_EQUALITY( a_sptr1.get(), a_rcp1.get() );
1094 
1095  const RCP<C> c_rcp1 = rcp(std::dynamic_pointer_cast<C>(a_sptr1));
1096  TEST_EQUALITY( c_rcp1.get(), a_rcp1.get() );
1097  TEST_ASSERT( c_rcp1.shares_resource(a_rcp1) );
1098  // NOTE: The above test shows how Teuchos::RCP machinery will automatically
1099  // look up the underlying RCPNode object and use it!
1100 }
1101 
1102 
1103 #endif // TEUCHOS_DEBUG
1104 
1105 
1106 #endif // HAVE_TEUCHOSCORE_CXX11
1107 
1108 
1109 
1110 //
1111 // Template Instantiations
1112 //
1113 
1114 
1115 #ifdef TEUCHOS_DEBUG
1116 
1117 # define DEBUG_UNIT_TEST_GROUP( T ) \
1118 
1119 #else
1120 
1121 # define DEBUG_UNIT_TEST_GROUP( T )
1122 
1123 #endif
1124 
1125 
1126 #define UNIT_TEST_GROUP( T ) \
1127  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCP, weakDelete, T ) \
1128  DEBUG_UNIT_TEST_GROUP(T)
1129 
1130 
1135 
1136 
1137 } // namespace
Dangling reference error exception class.
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...
void set_extra_data(const T1 &extra_data, const std::string &name, const Ptr< ArrayRCP< T2 > > &p, EPrePostDestruction destroy_when=POST_DESTROY, bool force_unique=true)
Set extra data associated with a ArrayRCP object.
void set_C(const Teuchos::RCP< C > &c)
#define TEST_ASSERT(v1)
Assert the given statement is true.
Ptr< T > inOutArg(T &arg)
create a non-persisting (required or optional) input/output argument for a function call...
Ptr< T1 > get_optional_nonconst_extra_data(RCP< T2 > &p, const std::string &name)
Get a pointer to non-const extra data (if it exists) associated with a RCP object.
#define TEST_NOTHROW(code)
Asserr that the statement &#39;code&#39; does not thrown any excpetions.
int call_C_f()
#define ECHO(statement)
Echo the given statement before it is executed.
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_UNIT_TEST_TEMPLATE_1_DECL(TEST_GROUP, TEST_NAME, TYPE)
Macro for defining a templated unit test with one template parameter.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_THROW(code, ExceptType)
Assert that the statement &#39;code&#39; throws the exception &#39;ExceptType&#39; (otherwise the test fails)...
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
const int C_g_return
Definition: TestClasses.hpp:56
const int C_f_return
Definition: TestClasses.hpp:57
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
Definition: PackageA.cpp:3
RCP< T > rcpWithEmbeddedObj(T *p, const Embedded &embedded, bool owns_mem=true)
Create an RCP with and also put in an embedded object.
void free(T *ptr)
Deallocates a pointer ptr using delete ptr (required).
Debug-mode RCPNode tracing class.
RCP< T > rcpCloneNode(const RCP< T > &p)
Allocate a new RCP object with a new RCPNode with memory pointing to the initial node.
#define SET_RCPNODE_TRACING()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
Unit testing support.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
Definition: PackageC.cpp:3
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
RCP< T > rcpFromUndefRef(T &r)
Return a non-owning weak RCP object from a raw object reference for an undefined type.
std::shared_ptr< T > get_shared_ptr(const RCP< T > &rcp)
Conversion function that takes in a Teuchos::RCP object and spits out a std::shared_ptr object...
RCP< T > rcpFromRef(T &r)
Return a non-owning weak RCP object from a raw object reference for a defined type.
Policy class for deallocator for non-owned RCPs.
Smart reference counting pointer class for automatic garbage collection.
RCP< T > rcpWithDealloc(T *p, Dealloc_T dealloc, bool owns_mem=true)
Initialize from a raw pointer with a deallocation policy.
Ptr< T > outArg(T &arg)
create a non-persisting (required or optional) output argument for a function call.
Thrown if a duplicate owning RCP is creatd the the same object.
Reference-counted pointer class and non-member templated function implementations.
const int A_g_return
Definition: TestClasses.hpp:50
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...
bool nonnull(const ArrayRCP< T > &p)
Returns true if p.get()!=NULL.
#define UNIT_TEST_GROUP(T)