Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
60namespace {
61
62
63using Teuchos::as;
64using Teuchos::null;
65using Teuchos::Ptr;
66using Teuchos::RCP;
67using Teuchos::rcp;
68using Teuchos::rcpFromRef;
69using Teuchos::rcpFromUndefRef;
70using Teuchos::outArg;
71using Teuchos::rcpWithEmbeddedObj;
72using Teuchos::getEmbeddedObj;
73using Teuchos::getOptionalEmbeddedObj;
74using Teuchos::getOptionalNonconstEmbeddedObj;
75using Teuchos::set_extra_data;
76using Teuchos::get_optional_nonconst_extra_data;
84
85
86TEUCHOS_UNIT_TEST( DeallocNull, free )
87{
89 d.free(0);
90}
91
92
93TEUCHOS_UNIT_TEST( RCP, construct_default )
94{
95 RCP<A> a_rcp;
96 TEST_EQUALITY_CONST(a_rcp.get(), 0);
97 TEST_EQUALITY_CONST(a_rcp.getRawPtr(), 0);
98 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
99 TEST_EQUALITY_CONST(a_rcp.strong_count(), 0);
100 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
101 TEST_EQUALITY_CONST(a_rcp.has_ownership(), false);
102}
103
104
105TEUCHOS_UNIT_TEST( RCP, construct_nonull )
106{
107 RCP<A> a_rcp(new A);
108 TEST_INEQUALITY_CONST(a_rcp.get(), 0);
109 TEST_INEQUALITY_CONST(a_rcp.getRawPtr(), 0);
110 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
111 TEST_EQUALITY_CONST(a_rcp.strong_count(), 1);
112 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
113 TEST_EQUALITY_CONST(a_rcp.has_ownership(), true);
114}
115
116
117TEUCHOS_UNIT_TEST( RCP, copy_construct_null )
118{
119 RCP<A> a_rcp;
120 RCP<A> b_rcp(a_rcp);
121 TEST_EQUALITY_CONST(a_rcp.get(), 0);
122 TEST_EQUALITY_CONST(a_rcp.getRawPtr(), 0);
123 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
124 TEST_EQUALITY_CONST(a_rcp.strong_count(), 0);
125 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
126 TEST_EQUALITY_CONST(a_rcp.has_ownership(), false);
127 TEST_EQUALITY_CONST(b_rcp.get(), 0);
128 TEST_EQUALITY_CONST(b_rcp.getRawPtr(), 0);
129 TEST_EQUALITY_CONST(b_rcp.strength(), RCP_STRONG);
130 TEST_EQUALITY_CONST(b_rcp.strong_count(), 0);
131 TEST_EQUALITY_CONST(b_rcp.weak_count(), 0);
132 TEST_EQUALITY_CONST(b_rcp.has_ownership(), false);
133}
134
135
136TEUCHOS_UNIT_TEST( RCP, copy_construct_nonnull )
137{
138 RCP<A> a_rcp(new A);
139 RCP<A> b_rcp(a_rcp);
140 TEST_EQUALITY(b_rcp.get(), a_rcp.get());
141 TEST_EQUALITY(b_rcp.getRawPtr(), a_rcp.getRawPtr());
142 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
143 TEST_EQUALITY_CONST(b_rcp.strength(), RCP_STRONG);
144 TEST_EQUALITY_CONST(a_rcp.strong_count(), 2);
145 TEST_EQUALITY_CONST(b_rcp.strong_count(), 2);
146 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
147 TEST_EQUALITY_CONST(b_rcp.weak_count(), 0);
148 TEST_EQUALITY_CONST(a_rcp.has_ownership(), true);
149 TEST_EQUALITY_CONST(b_rcp.has_ownership(), true);
150}
151
152
153TEUCHOS_UNIT_TEST( RCP, move_construct_nonnull )
154{
155 RCP<A> a_rcp(new A);
156 RCP<A> b_rcp(std::move(a_rcp));
157 TEST_EQUALITY_CONST(a_rcp.get(), 0);
158 TEST_EQUALITY_CONST(a_rcp.getRawPtr(), 0);
159 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
160 TEST_EQUALITY_CONST(a_rcp.strong_count(), 0);
161 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
162 TEST_EQUALITY_CONST(a_rcp.has_ownership(), false);
163 TEST_INEQUALITY_CONST(b_rcp.get(), 0);
164 TEST_INEQUALITY_CONST(b_rcp.getRawPtr(), 0);
165 TEST_EQUALITY_CONST(b_rcp.strength(), RCP_STRONG);
166 TEST_EQUALITY_CONST(b_rcp.strong_count(), 1);
167 TEST_EQUALITY_CONST(b_rcp.weak_count(), 0);
168 TEST_EQUALITY_CONST(b_rcp.has_ownership(), true);
169}
170
171
172TEUCHOS_UNIT_TEST( RCP, assign_self_null )
173{
174 RCP<A> a_rcp;
175 a_rcp = a_rcp;
176 TEST_ASSERT(is_null(a_rcp));
177}
178
179
180TEUCHOS_UNIT_TEST( RCP, copy_assign_self_nonnull )
181{
182 RCP<A> a_rcp(new A);
183 A *a_raw_ptr = a_rcp.getRawPtr();
184 a_rcp = a_rcp;
185 TEST_ASSERT(nonnull(a_rcp));
186 TEST_EQUALITY(a_rcp.getRawPtr(), a_raw_ptr);
187}
188
189
190TEUCHOS_UNIT_TEST( RCP, copy_assign_nonnull )
191{
192 RCP<A> a_rcp(new A);
193 RCP<A> b_rcp;
194 b_rcp = a_rcp;
195 TEST_EQUALITY(b_rcp.get(), a_rcp.get());
196 TEST_EQUALITY(b_rcp.getRawPtr(), a_rcp.getRawPtr());
197 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
198 TEST_EQUALITY_CONST(b_rcp.strength(), RCP_STRONG);
199 TEST_EQUALITY_CONST(a_rcp.strong_count(), 2);
200 TEST_EQUALITY_CONST(b_rcp.strong_count(), 2);
201 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
202 TEST_EQUALITY_CONST(b_rcp.weak_count(), 0);
203 TEST_EQUALITY_CONST(a_rcp.has_ownership(), true);
204 TEST_EQUALITY_CONST(b_rcp.has_ownership(), true);
205}
206
207
208TEUCHOS_UNIT_TEST( RCP, move_assign_nonnull )
209{
210 RCP<A> a_rcp(new A);
211 RCP<A> b_rcp;
212 b_rcp = std::move(a_rcp);
213 TEST_EQUALITY_CONST(a_rcp.get(), 0);
214 TEST_EQUALITY_CONST(a_rcp.getRawPtr(), 0);
215 TEST_EQUALITY_CONST(a_rcp.strength(), RCP_STRONG);
216 TEST_EQUALITY_CONST(a_rcp.strong_count(), 0);
217 TEST_EQUALITY_CONST(a_rcp.weak_count(), 0);
218 TEST_EQUALITY_CONST(a_rcp.has_ownership(), false);
219 TEST_INEQUALITY_CONST(b_rcp.get(), 0);
220 TEST_INEQUALITY_CONST(b_rcp.getRawPtr(), 0);
221 TEST_EQUALITY_CONST(b_rcp.strength(), RCP_STRONG);
222 TEST_EQUALITY_CONST(b_rcp.strong_count(), 1);
223 TEST_EQUALITY_CONST(b_rcp.weak_count(), 0);
224 TEST_EQUALITY_CONST(b_rcp.has_ownership(), true);
225}
226
227
228TEUCHOS_UNIT_TEST( RCP, operator_bool_null )
229{
230 RCP<A> a_rcp;
231 TEST_EQUALITY_CONST(bool(a_rcp), false);
232}
233
234
235TEUCHOS_UNIT_TEST( RCP, operator_bool_nonnull )
236{
237 RCP<A> a_rcp(new A);
238 TEST_EQUALITY_CONST(bool(a_rcp), true);
239}
240
241
242TEUCHOS_UNIT_TEST( RCP, operator_bool_if )
243{
244 RCP<A> a_rcp(new A);
245 RCP<A> b_rcp;
246 bool a_is_null;
247 bool b_is_null;
248
249 if (a_rcp)
250 a_is_null = false;
251 else
252 a_is_null = true;
253 if (b_rcp)
254 b_is_null = false;
255 else
256 b_is_null = true;
257
258 TEST_EQUALITY_CONST(a_is_null, false);
259 TEST_EQUALITY_CONST(b_is_null, true );
260}
261
262
263TEUCHOS_UNIT_TEST( RCP, getConst )
264{
265 RCP<A> a_rcp(new A);
266 RCP<const A> ca_rcp = a_rcp.getConst();
267 TEST_EQUALITY(a_rcp.getRawPtr(), ca_rcp.getRawPtr());
268}
269
270
271TEUCHOS_UNIT_TEST( RCP, explicit_null )
272{
273 RCP<A> a_rcp(0);
274 TEST_ASSERT(is_null(a_rcp));
275}
276
277
278TEUCHOS_UNIT_TEST( RCP, explicit_dealloc_null )
279{
280 RCP<A> a_rcp = rcpWithDealloc(static_cast<A*>(0), Teuchos::DeallocNull<A>(), false);
281 TEST_ASSERT(is_null(a_rcp));
282}
283
284
285TEUCHOS_UNIT_TEST( RCP, explicit_null_null )
286{
287 RCP<A> a_rcp(0, null);
288 TEST_ASSERT(is_null(a_rcp));
289}
290
291
292TEUCHOS_UNIT_TEST( RCP, explicit_null_nonnull )
293{
294 A *a = new A;
295 RCP<A> a_rcp(a, null);
296 TEST_ASSERT(nonnull(a_rcp));
297 delete a;
298}
299
300
301TEUCHOS_UNIT_TEST( RCP, rcpFromRef_raw_ref )
302{
303 A a;
304 RCP<A> a_rcp = rcpFromRef(a);
305 TEST_EQUALITY(a_rcp.getRawPtr(), &a);
306 TEST_ASSERT(nonnull(a_rcp));
307}
308
309
310TEUCHOS_UNIT_TEST( RCP, rcpFromRef_from_rcp )
311{
312 RCP<A> a_rcp1 = rcp<A>(new A);
313 RCP<A> a_rcp2 = rcpFromRef(*a_rcp1);
314 TEST_EQUALITY(a_rcp2.getRawPtr(), a_rcp1.getRawPtr());
315 if (RCPNodeTracer::isTracingActiveRCPNodes())
316 {
317 TEST_EQUALITY_CONST(a_rcp2.strong_count(), 1);
318 TEST_EQUALITY_CONST(a_rcp2.weak_count(), 1);
319 TEST_EQUALITY_CONST(a_rcp2.has_ownership(), true);
320 }
321 else {
322 TEST_EQUALITY_CONST(a_rcp2.strong_count(), 1);
323 TEST_EQUALITY_CONST(a_rcp2.weak_count(), 0);
324 TEST_EQUALITY_CONST(a_rcp2.has_ownership(), false);
325 }
326}
327
328
329TEUCHOS_UNIT_TEST( RCP, rcpFromUndefRef )
330{
331 A a;
332 RCP<A> a_rcp = rcpFromUndefRef(a);
333 TEST_ASSERT(nonnull(a_rcp));
334}
335
339TEUCHOS_UNIT_TEST( RCP, make_rcp_no_constructor_arg )
340{
343}
344
348TEUCHOS_UNIT_TEST( RCP, make_rcp )
349{
352 TEST_EQUALITY(a_rcp->A_g(),1);
353 TEST_EQUALITY(a_rcp->A_f(),2);
354}
355
356
357//
358// Test rcpCloneNode(...)
359//
360
361
362TEUCHOS_UNIT_TEST( RCP, rcpCloneNode_null )
363{
364 ECHO(RCP<RCP<int> > rcp1 = null);
365 ECHO(RCP<RCP<int> > rcp2 = rcpCloneNode(rcp1));
366 TEST_EQUALITY(rcp2, null);
367}
368
369
370TEUCHOS_UNIT_TEST( RCP, rcpCloneNode_basic )
371{
372
373 ECHO(RCP<int> rcp1 = rcp(new int(0)));
374
375 ECHO(RCP<int> rcp2 = rcpCloneNode(rcp1));
376 TEST_ASSERT(nonnull(rcp2));
377 TEST_EQUALITY(rcp1.strong_count(), 2);
378 TEST_EQUALITY(rcp2.strong_count(), 1);
379
380 ECHO(RCP<int> rcp3 = rcp2);
381 TEST_EQUALITY(rcp1.strong_count(), 2);
382 TEST_EQUALITY(rcp2.strong_count(), 2);
383 TEST_EQUALITY(rcp3.strong_count(), 2);
384
385 ECHO(RCP <int> rcp4 = rcp1);
386 TEST_EQUALITY(rcp1.strong_count(), 3);
387 TEST_EQUALITY(rcp2.strong_count(), 2);
388 TEST_EQUALITY(rcp3.strong_count(), 2);
389
390 ECHO(rcp4 = null);
391 TEST_EQUALITY(rcp1.strong_count(), 2);
392 TEST_EQUALITY(rcp2.strong_count(), 2);
393 TEST_EQUALITY(rcp3.strong_count(), 2);
394 TEST_EQUALITY(rcp4.strong_count(), 0);
395
396 ECHO(rcp1 = null);
397 TEST_EQUALITY(rcp1.strong_count(), 0);
398 TEST_EQUALITY(rcp2.strong_count(), 2);
399 TEST_EQUALITY(rcp3.strong_count(), 2);
400 TEST_EQUALITY(rcp4.strong_count(), 0);
401
402 ECHO(rcp2 = null);
403 TEST_EQUALITY(rcp2.strong_count(), 0);
404 TEST_EQUALITY(rcp3.strong_count(), 1);
405
406 ECHO(rcp3 = null);
407 TEST_EQUALITY(rcp3.strong_count(), 0);
408
409}
410
411
412//
413// Test duplicate owning RCP objects
414//
415
416
417// Test that shows that we can detect trying to create two owning RCPs
418// pointing to the same polymorphic object but having different interfaces
419// with different addresses. This happens due to virtual base classes. Only
420// works when we have a working getBaseObjVoidPtr(...) function.
421TEUCHOS_UNIT_TEST( RCP, duplicate_rcp_owning_polymorphic )
422{
424 ECHO(C *c_ptr = new C);
425 ECHO(A *a_ptr = c_ptr);
426 ECHO(RCP<C> c_rcp = rcp(c_ptr)); // Okay
427#if defined(TEUCHOS_DEBUG) && defined(HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR)
428 // With determine they are pointed to the same object!
429 TEST_THROW(RCP<A> a_rcp = rcp(a_ptr), DuplicateOwningRCPError);
430#else
431 // Will not determine they are point to the same object!
432 ECHO(RCP<A> a_rcp = rcp(a_ptr));
433 TEST_EQUALITY(a_rcp.getRawPtr(), a_ptr);
434 ECHO(a_rcp.release()); // Better or we will get a segfault!
435#endif
436}
437
438
439// Test that shows that we can detect trying to create two owning RCPs
440// pointing to the same polymorphic object with the same type and therefore
441// the same address. This works even if these use virtual base classes. This
442// works even without a working getBaseObjVoidPtr(...) function.
443TEUCHOS_UNIT_TEST( RCP, duplicate_rcp_owning_polymorphic_different_addr )
444{
446 ECHO(A *a_ptr1 = new C);
447 ECHO(A *a_ptr2 = a_ptr1);
448 ECHO(RCP<A> a_rcp1 = rcp(a_ptr1)); // Okay
449#if defined(TEUCHOS_DEBUG)
450 // With determine they are pointed to the same object!
451 TEST_THROW(RCP<A> a_rcp2 = rcp(a_ptr2), DuplicateOwningRCPError);
452#else
453 // Will not determine they are point to the same object!
454 ECHO(RCP<A> a_rcp2 = rcp(a_ptr2));
455 TEST_EQUALITY(a_rcp2.getRawPtr(), a_ptr2);
456 ECHO(a_rcp2.release()); // Better or we will get a segfault!
457#endif
458}
459
460
461// Test that shows that we can always detect trying to create two owning RCPs
462// pointing to the same nonpolymorphic object having different interfaces but
463// the same address (single non-virtual inheritance). Works just fine without
464// a working getBaseObjVoidPtr(...) function.
465TEUCHOS_UNIT_TEST( RCP, duplicate_rcp_owning_nonpolymorphic_same_addr )
466{
468 ECHO(E *e_ptr = new E);
469 ECHO(E *d_ptr = e_ptr);
470 ECHO(RCP<E> e_rcp = rcp(e_ptr)); // Okay
471#if defined(TEUCHOS_DEBUG)
472 // With determine they are pointed to the same object even without support
473 // for getBaseObjVoidPtr(...) because no dynamic_cast is needed.
474 TEST_THROW(RCP<D> d_rcp = rcp(d_ptr), DuplicateOwningRCPError);
475#else
476 // Will not determine they are point to the same object!
477 ECHO(RCP<D> d_rcp = rcp(d_ptr));
478 TEST_EQUALITY(d_rcp.getRawPtr(), d_ptr);
479 ECHO(d_rcp.release()); // Better or we will get a segfault!
480#endif
481}
482
483
484//
485// These next tests shows that we can detect when two RCPs are create to the same
486// object, one owning and the other non-owning. When we have a working
487// getBaseObjVoidPtr(...) function, the new non-owning RCP will actually be a
488// weak RCP that can be used to detect circular dependencies.
489//
490
491
492// rcp
493
494
495TEUCHOS_UNIT_TEST( RCP, rcp_duplicate_rcp_nonowning_polymorphic_different_addr )
496{
498 ECHO(RCP<C> c_rcp(new C));
499 ECHO(A &a_ref = *c_rcp);
500 ECHO(RCP<A> a_rcp = rcp(&a_ref, false));
501 ECHO(c_rcp = null);
502#if defined(TEUCHOS_DEBUG) && defined(HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR)
503 TEST_THROW(a_rcp->A_g(), DanglingReferenceError);
504#else
505 TEST_NOTHROW(a_rcp.getRawPtr());
506#endif
507}
508
509
510TEUCHOS_UNIT_TEST( RCP, rcp_duplicate_rcp_nonowning_polymorphic_same_addr )
511{
513 ECHO(RCP<A> a_rcp1(new C));
514 ECHO(A &a_ref = *a_rcp1);
515 ECHO(RCP<A> a_rcp2 = rcp(&a_ref, false));
516 ECHO(a_rcp1 = null);
517#if defined(TEUCHOS_DEBUG)
518 TEST_THROW(a_rcp2->A_g(), DanglingReferenceError);
519#else
520 TEST_NOTHROW(a_rcp2.getRawPtr());
521#endif
522}
523
524
525TEUCHOS_UNIT_TEST( RCP, rcp_duplicate_rcp_nonowning_nonpolymorphic )
526{
528 ECHO(RCP<E> e_rcp(new E));
529 ECHO(D &d_ref = *e_rcp);
530 ECHO(RCP<D> d_rcp = rcp(&d_ref, false));
531 ECHO(e_rcp = null);
532#if defined(TEUCHOS_DEBUG)
533 TEST_THROW(d_rcp->D_g(), DanglingReferenceError);
534#else
535 TEST_NOTHROW(d_rcp.getRawPtr());
536#endif
537}
538
539
540// rcpFromRef
541
542
543TEUCHOS_UNIT_TEST( RCP, rcpFromRef_duplicate_rcp_nonowning_polymorphic_different_addr )
544{
546 ECHO(RCP<C> c_rcp(new C));
547 ECHO(A &a_ref = *c_rcp);
548 ECHO(RCP<A> a_rcp = rcpFromRef(a_ref));
549 ECHO(c_rcp = null);
550#if defined(TEUCHOS_DEBUG) && defined(HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR)
551 TEST_THROW(a_rcp->A_g(), DanglingReferenceError);
552#else
553 TEST_NOTHROW(a_rcp.getRawPtr());
554#endif
555}
556
557
558TEUCHOS_UNIT_TEST( RCP, rcpFromRef_duplicate_rcp_nonowning_polymorphic_same_addr )
559{
561 ECHO(RCP<A> a_rcp1(new C));
562 ECHO(A &a_ref = *a_rcp1);
563 ECHO(RCP<A> a_rcp2 = rcpFromRef(a_ref));
564 ECHO(a_rcp1 = null);
565#if defined(TEUCHOS_DEBUG)
566 TEST_THROW(a_rcp2->A_g(), DanglingReferenceError);
567#else
568 TEST_NOTHROW(a_rcp2.getRawPtr());
569#endif
570}
571
572
573TEUCHOS_UNIT_TEST( RCP, rcpFromRef_duplicate_rcp_nonowning_nonpolymorphic )
574{
576 ECHO(RCP<E> e_rcp(new E));
577 ECHO(D &d_ref = *e_rcp);
578 ECHO(RCP<D> d_rcp = rcpFromRef(d_ref));
579 ECHO(e_rcp = null);
580#if defined(TEUCHOS_DEBUG)
581 TEST_THROW(d_rcp->D_g(), DanglingReferenceError);
582#else
583 TEST_NOTHROW(d_rcp.getRawPtr());
584#endif
585}
586
587
588// rcpFromUndefRef (Can never detect dangling references)
589
590
591TEUCHOS_UNIT_TEST( RCP, rcpFromUndefRef_duplicate_rcp_nonowning_polymorphic_same_addr )
592{
594 ECHO(RCP<A> a_rcp1(new C));
595 ECHO(A &a_ref = *a_rcp1);
596 ECHO(RCP<A> a_rcp2 = rcpFromUndefRef(a_ref));
597 ECHO(a_rcp1 = null);
598 TEST_NOTHROW(a_rcp2.getRawPtr());
599}
600
601
602//
603// extra data and embedded objects tests
604//
605
606
607TEUCHOS_UNIT_TEST( RCP, get_optional_nonconst_extra_data )
608{
609 RCP<A> a_rcp = rcp(new A);
610 set_extra_data( as<int>(1), "blob", outArg(a_rcp) );
611 TEST_EQUALITY_CONST(*get_optional_nonconst_extra_data<int>(a_rcp, "blob"), as<int>(1));
612}
613
614
615TEUCHOS_UNIT_TEST( RCP, getOptionalEmbeddedObj_null )
616{
617 ECHO(RCP<A> a_rcp = rcp(new A));
618 const Ptr<const RCP<C> > c_ptr_rcp_1 =
619 getOptionalEmbeddedObj<A, RCP<C> >(a_rcp);
620 TEST_EQUALITY_CONST( c_ptr_rcp_1, null );
621 const Ptr<RCP<C> > c_ptr_rcp_2 =
622 getOptionalNonconstEmbeddedObj<A, RCP<C> >(a_rcp);
623 TEST_EQUALITY_CONST( c_ptr_rcp_2, null );
624}
625
626
627TEUCHOS_UNIT_TEST( RCP, getOptionalEmbeddedObj_default )
628{
629
630 ECHO(RCP<C> c_rcp = rcp(new C));
631 ECHO(RCP<A> a_rcp = rcpWithEmbeddedObj(new A, c_rcp));
632
633 Ptr<const RCP<C> > c_ptr_rcp_1 =
634 getOptionalEmbeddedObj<A, RCP<C> >(a_rcp);
635 TEST_EQUALITY_CONST( is_null(c_ptr_rcp_1), false );
636 TEST_EQUALITY( (*c_ptr_rcp_1).getRawPtr(), c_rcp.getRawPtr() );
637 TEST_EQUALITY( (*c_ptr_rcp_1)->C_g(), C_g_return );
638
639 Ptr<RCP<C> > c_ptr_rcp_2 =
640 getOptionalNonconstEmbeddedObj<A, RCP<C> >(a_rcp);
641 TEST_EQUALITY_CONST( is_null(c_ptr_rcp_2), false );
642 TEST_EQUALITY( (*c_ptr_rcp_2).getRawPtr(), c_rcp.getRawPtr() );
643 TEST_EQUALITY( (*c_ptr_rcp_2)->C_f(), C_f_return );
644
645}
646
647
648TEUCHOS_UNIT_TEST( RCP, reset_null )
649{
650 RCP<A> a_rcp = rcp(new A);
651 a_rcp.reset();
652 TEST_ASSERT(is_null(a_rcp));
653}
654
655
656TEUCHOS_UNIT_TEST( RCP, reset_nonnull )
657{
658 RCP<A> a_rcp = rcp(new A);
659 C* c_rawp = new C;
660 a_rcp.reset(c_rawp);
661 A* a_rawp = c_rawp;
662 TEST_EQUALITY( a_rcp.getRawPtr(), a_rawp );
663}
664
665
666TEUCHOS_UNIT_TEST( RCP, nonnull )
667{
668 ECHO(RCP<A> a_rcp = rcp(new A));
669 TEST_EQUALITY_CONST(is_null(a_rcp), false);
670 TEST_EQUALITY_CONST(nonnull(a_rcp), true);
671 ECHO(a_rcp = null);
672 TEST_EQUALITY_CONST(is_null(a_rcp), true);
673 TEST_EQUALITY_CONST(nonnull(a_rcp), false);
674}
675
676
677TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCP, weakDelete, T )
678{
679
680 ECHO(RCP<T> rcp_strong = rcp(new T));
681
682 TEST_EQUALITY_CONST( rcp_strong.strength(), RCP_STRONG );
683 TEST_EQUALITY_CONST( rcp_strong.is_null(), false );
684 TEST_EQUALITY_CONST( rcp_strong.strong_count(), 1 );
685 TEST_EQUALITY_CONST( rcp_strong.weak_count(), 0 );
686 TEST_EQUALITY_CONST( rcp_strong.total_count(), 1 );
687
688 ECHO(RCP<T> rcp_weak1 = rcp_strong.create_weak());
689
690 TEST_EQUALITY_CONST( rcp_weak1.strength(), RCP_WEAK );
691 TEST_EQUALITY_CONST( rcp_weak1.is_null(), false );
692 TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 1 );
693 TEST_EQUALITY_CONST( rcp_weak1.weak_count(), 1 );
694 TEST_EQUALITY_CONST( rcp_weak1.total_count(), 2 );
695
696 TEST_EQUALITY_CONST( rcp_strong.strong_count(), 1 );
697 TEST_EQUALITY_CONST( rcp_strong.is_null(), false );
698 TEST_EQUALITY_CONST( rcp_strong.weak_count(), 1 );
699 TEST_EQUALITY_CONST( rcp_strong.total_count(), 2 );
700
701 TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_strong), true );
702
703 TEST_EQUALITY( rcp_weak1.get(), rcp_weak1.getRawPtr() );
704 TEST_EQUALITY( rcp_weak1.get(), rcp_strong.get() );
705 TEST_EQUALITY( rcp_weak1.getRawPtr(), rcp_strong.getRawPtr() );
706
707 ECHO(RCP<T> rcp_weak2 = rcp_weak1);
708
709 TEST_EQUALITY_CONST( rcp_weak2.strength(), RCP_WEAK );
710 TEST_EQUALITY_CONST( rcp_weak2.is_null(), false );
711 TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 1 );
712 TEST_EQUALITY_CONST( rcp_weak2.weak_count(), 2 );
713 TEST_EQUALITY_CONST( rcp_weak2.total_count(), 3 );
714
715 TEST_EQUALITY_CONST( rcp_strong.strong_count(), 1 );
716 TEST_EQUALITY_CONST( rcp_strong.is_null(), false );
717 TEST_EQUALITY_CONST( rcp_strong.weak_count(), 2 );
718 TEST_EQUALITY_CONST( rcp_strong.total_count(), 3 );
719
720 TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_strong), true );
721 TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_weak2), true );
722 TEST_EQUALITY_CONST( rcp_weak2.shares_resource(rcp_strong), true );
723
724 TEST_EQUALITY( rcp_weak2.get(), rcp_strong.get() );
725 TEST_EQUALITY( rcp_weak2.getRawPtr(), rcp_strong.getRawPtr() );
726
727 ECHO(rcp_strong = null); // This deletes the underlying object of type T!
728
729 TEST_EQUALITY_CONST( rcp_strong.strength(), RCP_STRONG );
730 TEST_EQUALITY_CONST( rcp_strong.is_null(), true );
731 TEST_EQUALITY_CONST( rcp_strong.strong_count(), 0 );
732 TEST_EQUALITY_CONST( rcp_strong.strong_count(), 0 );
733 TEST_EQUALITY_CONST( rcp_strong.weak_count(), 0 );
734 TEST_EQUALITY_CONST( rcp_strong.total_count(), 0 );
735 TEST_EQUALITY_CONST( rcp_strong.is_valid_ptr(), true );
736
737 TEST_EQUALITY_CONST( rcp_strong.shares_resource(rcp_weak1), false );
738 TEST_EQUALITY_CONST( rcp_strong.shares_resource(rcp_weak2), false );
739
740 TEST_EQUALITY_CONST( rcp_weak1.has_ownership(), true );
741 TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
742 TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
743 TEST_EQUALITY_CONST( rcp_weak1.weak_count(), 2 );
744 TEST_EQUALITY_CONST( rcp_weak1.total_count(), 2 );
745 TEST_EQUALITY_CONST( rcp_weak1.is_valid_ptr(), false );
746
747 TEST_EQUALITY_CONST( rcp_weak2.has_ownership(), true );
748 TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
749 TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
750 TEST_EQUALITY_CONST( rcp_weak2.weak_count(), 2 );
751 TEST_EQUALITY_CONST( rcp_weak2.total_count(), 2 );
752 TEST_EQUALITY_CONST( rcp_weak2.is_valid_ptr(), false );
753
754 TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_weak2), true );
755
756 ECHO(rcp_weak1.assert_not_null()); // Does not throw!
757 ECHO(rcp_weak2.assert_not_null()); // Does not throw!
758
759 TEST_THROW( rcp_weak1.assert_valid_ptr(), DanglingReferenceError );
760#ifdef TEUCHOS_DEBUG
761 TEST_THROW( rcp_weak1.operator->(), DanglingReferenceError );
762 TEST_THROW( *rcp_weak1, DanglingReferenceError );
763 TEST_THROW( rcp_weak1.create_weak(), DanglingReferenceError );
764 TEST_THROW( rcp_weak1.get(), DanglingReferenceError );
765 TEST_THROW( rcp_weak1.getRawPtr(), DanglingReferenceError );
766 TEST_THROW( rcp_weak1(), DanglingReferenceError );
767 TEST_THROW( rcp_weak1.release(), DanglingReferenceError );
768#endif // TEUCHOS_DEBUG
769
770 ECHO(rcp_weak1 = null); // Just deicrements weak count!
771
772 TEST_EQUALITY_CONST( rcp_weak1.strength(), RCP_STRONG );
773 TEST_EQUALITY_CONST( rcp_weak1.is_null(), true );
774 TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
775 TEST_EQUALITY_CONST( rcp_weak1.strong_count(), 0 );
776 TEST_EQUALITY_CONST( rcp_weak1.weak_count(), 0 );
777 TEST_EQUALITY_CONST( rcp_weak1.total_count(), 0 );
778 TEST_EQUALITY_CONST( rcp_weak1.is_valid_ptr(), true );
779
780 TEST_EQUALITY_CONST( rcp_weak2.has_ownership(), true );
781 TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
782 TEST_EQUALITY_CONST( rcp_weak2.strong_count(), 0 );
783 TEST_EQUALITY_CONST( rcp_weak2.weak_count(), 1 );
784 TEST_EQUALITY_CONST( rcp_weak2.total_count(), 1 );
785 TEST_EQUALITY_CONST( rcp_weak2.is_valid_ptr(), false );
786
787 TEST_EQUALITY_CONST( rcp_weak1.shares_resource(rcp_weak2), false );
788
789 TEST_THROW( rcp_weak2.assert_valid_ptr(), DanglingReferenceError );
790#ifdef TEUCHOS_DEBUG
791 TEST_THROW( rcp_weak2.operator->(), DanglingReferenceError );
792 TEST_THROW( *rcp_weak2, DanglingReferenceError );
793 TEST_THROW( rcp_weak2.create_weak(), DanglingReferenceError );
794 TEST_THROW( rcp_weak2.get(), DanglingReferenceError );
795 TEST_THROW( rcp_weak2.getRawPtr(), DanglingReferenceError );
796 TEST_THROW( rcp_weak2(), DanglingReferenceError );
797 TEST_THROW( rcp_weak2.release(), DanglingReferenceError );
798#endif // TEUCHOS_DEBUG
799
800}
801
802
803TEUCHOS_UNIT_TEST( RCP, weak_strong )
804{
805
806 ECHO(RCP<A> rcp1(rcp(new A)));
807 TEST_EQUALITY_CONST( rcp1.strength(), RCP_STRONG );
808
809 ECHO(RCP<A> rcp2 = rcp1.create_weak());
810
811 TEST_EQUALITY_CONST( rcp2.strength(), RCP_WEAK );
812 TEST_EQUALITY_CONST( rcp1.strong_count(), 1 );
813 TEST_EQUALITY_CONST( rcp1.weak_count(), 1 );
814 TEST_EQUALITY_CONST( rcp2.strong_count(), 1 );
815 TEST_EQUALITY_CONST( rcp2.weak_count(), 1 );
816
817 ECHO(RCP<A> rcp3 = rcp2.create_strong());
818
819 TEST_EQUALITY_CONST( rcp3.strength(), RCP_STRONG );
820 TEST_EQUALITY_CONST( rcp1.strong_count(), 2 );
821 TEST_EQUALITY_CONST( rcp1.weak_count(), 1 );
822 TEST_EQUALITY_CONST( rcp2.strong_count(), 2 );
823 TEST_EQUALITY_CONST( rcp2.weak_count(), 1 );
824
825 // This will make the underlying object A gets deleted!
826 ECHO(rcp1 = null);
827 ECHO(rcp3 = null);
828
829 ECHO(rcp2 = null); // Should make the underlying node go away
830
831}
832
833
834//
835// circularReference
836//
837
838
839TEUCHOS_UNIT_TEST( RCP, circularReference_a_then_c )
840{
841 {
842 // Create objects a and c
843 ECHO(RCP<A> a = rcp(new A));
844 ECHO(RCP<C> c = rcp(new C));
845
846 // Create a circular reference where 'a' owns 'c' strongly but 'c' only
847 // owns 'a' weakly.
848 ECHO(a->set_C(c));
849 ECHO(c->set_A(a.create_weak()));
850
852 TEST_EQUALITY( c->call_A_g(), A_g_return );
853
854 // Remove 'a' first and then remove 'c'. Since 'a' is only weakly held by
855 // 'c', this will result in 'a' being deleted right away. In this case,
856 // if anyone tries to access 'a' after this debug mode will throw.
857
858 ECHO(a = null);
859
860 // c is now dead!
861#ifdef TEUCHOS_DEBUG
862 TEST_THROW(c->call_A_g(), DanglingReferenceError);
863#endif
864
865 // Finally, when 'c' goes away implicitly, it will do nothing because it
866 // only had weak ownership of a. So it will clean up with any trouble.
867 }
868}
869
870
871TEUCHOS_UNIT_TEST( RCP, circularReference_c_then_a )
872{
873 {
874 // Create objects a and c
875 ECHO(RCP<A> a = rcp(new A));
876 ECHO(RCP<C> c = rcp(new C));
877
878 // Create a circular reference where 'a' owns 'c' strongly but 'c' only
879 // owns 'a' weakly.
880 ECHO(a->set_C(c));
881 ECHO(c->set_A(a.create_weak()));
882
884 TEST_EQUALITY( c->call_A_g(), A_g_return );
885
886 // Remove 'c' first and then remove 'a' implicitly at the end of the
887 // block. Since 'c' is held strongly by 'a' and since we are keeping the
888 // strong pointer for 'a' alive, we can call functions on 'a' all we want
889 // with no fear of accessing dead memory.
890
891 ECHO(c = null);
892
893 TEST_EQUALITY( a->call_C_f(), C_f_return ); // a is still alive!
894
895 // Finally, when 'a' goes away implicitly, it will take 'c' with it. In
896 // the complex set of nested calls that take place due to the circular
897 // reference, everything will get cleaned up correctly. Also, if any
898 // client code where to try to access an object as it is being deleted, an
899 // exception will get thrown and no memory error will occur (unless an
900 // abort(...) is called when an exception gets thrown from a destructor
901 // when an exception is already active).
902 }
903}
904
905
906TEUCHOS_UNIT_TEST( RCP, circularReference_self )
907{
908 {
909 // Create one 'c' object
910 ECHO(RCP<C> c = rcp(new C));
911 // Create a weak circular reference where 'c' points back to itself
912 ECHO(c->set_A(c.create_weak()));
913 // Now, try to set 'c' to null.
914 ECHO(c = null); // All memory should be cleaned up here!
915 }
916}
917
918
919TEUCHOS_UNIT_TEST( RCP, danglingPtr1 )
920{
921 ECHO(RCP<A> a_rcp = rcp(new A));
922 ECHO(Ptr<A> a_ptr = a_rcp());
923 ECHO(A *badPtr = a_rcp.getRawPtr());
924 ECHO(a_rcp = null);
925#ifdef TEUCHOS_DEBUG
926 TEST_THROW( *a_ptr, DanglingReferenceError );
927 (void)badPtr;
928#else
929 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
930#endif
931}
932
933
934TEUCHOS_UNIT_TEST( RCP, danglingPtr2 )
935{
936 ECHO(Ptr<A> a_ptr);
937 ECHO(A *badPtr = 0);
938 {
939 ECHO(RCP<A> a_rcp = rcp(new A));
940 ECHO(badPtr = a_rcp.getRawPtr());
941 ECHO(a_ptr = a_rcp.ptr());
942 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
943 }
944#ifdef TEUCHOS_DEBUG
945 TEST_THROW( *a_ptr, DanglingReferenceError );
946 (void)badPtr;
947#else
948 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
949#endif
950}
951
952
953TEUCHOS_UNIT_TEST( RCP, danglingPtr3 )
954{
955 ECHO(Ptr<A> a_ptr);
956 ECHO(A *badPtr = 0);
957 {
958 ECHO(RCP<A> a_rcp = rcp(new A));
959 ECHO(badPtr = a_rcp.getRawPtr());
960 ECHO(Ptr<A> a_ptr2(a_rcp.ptr()));
961 ECHO(Ptr<A> a_ptr3(a_ptr2));
962 ECHO(a_ptr = a_ptr3);
963 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
964 }
965#ifdef TEUCHOS_DEBUG
966 TEST_THROW( *a_ptr, DanglingReferenceError );
967 (void)badPtr;
968#else
969 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
970#endif
971}
972
973
974TEUCHOS_UNIT_TEST( RCP, danglingPtr4 )
975{
976 ECHO(Ptr<A> a_ptr);
977 ECHO(A *badPtr = 0);
978 {
979 ECHO(RCP<C> c_rcp = rcp(new C));
980 ECHO(badPtr = c_rcp.getRawPtr());
981 ECHO(Ptr<A> a_ptr2(c_rcp.ptr()));
982 ECHO(a_ptr = a_ptr2);
983 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
984 }
985#ifdef TEUCHOS_DEBUG
986 TEST_THROW( *a_ptr, DanglingReferenceError );
987 (void)badPtr;
988#else
989 TEST_EQUALITY( a_ptr.getRawPtr(), badPtr );
990#endif
991}
992
993
994#ifdef TEUCHOS_DEBUG
995
996/* ToDo: Comment this back in once I have everything working
997
998// Test that the RCPNode tracing machinary can detect if an owning RCPNode is
999// being created that would result in a double delete.
1000TEUCHOS_UNIT_TEST( RCP, multiRcpCreateError )
1001{
1002 C *c_ptr = new C;
1003#if !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
1004 Teuchos::setTracingActiveRCPNodes(true);
1005#endif
1006 RCP<C> c_rcp = rcp(c_ptr); // Okay
1007 RCP<C> c_rcp2;
1008 TEST_THROW(c_rcp2 = rcp(c_ptr), DuplicateOwningRCPError);
1009#if !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
1010 Teuchos::setTracingActiveRCPNodes(false);
1011#endif
1012 // Clean up memory so no leaks and not double deletes no matter what.
1013 c_rcp.release();
1014 c_rcp2.release();
1015 delete c_ptr;
1016}
1017
1018*/
1019
1020#endif // TEUCHOS_DEBUG
1021
1022
1023//
1024// invertObjectOwnership
1025//
1026
1027
1028RCP<C> createCAFactory()
1029{
1030 RCP<C> c = rcp(new C);
1031 c->set_A(rcp(new A));
1032 return c;
1033}
1034
1035
1036RCP<A> createACFactory()
1037{
1038 RCP<C> c = createCAFactory();
1039 return Teuchos::rcpWithInvertedObjOwnership(c->get_A(), c);
1040}
1041
1042
1043RCP<C> extractCFromA(const RCP<A> &a)
1044{
1046}
1047
1048
1049TEUCHOS_UNIT_TEST( RCP, invertObjectOwnership_basic )
1050{
1051 RCP<A> a = createACFactory();
1052 RCP<C> c = extractCFromA(a);
1053 TEST_EQUALITY_CONST( a.strong_count(), 1 );
1054 TEST_EQUALITY_CONST( c->get_A().strong_count(), 3 );
1055 TEST_ASSERT( !a.shares_resource(c->get_A()) );
1056 TEST_EQUALITY( a.getRawPtr(), c->get_A().getRawPtr() );
1057 TEST_EQUALITY( a->A_g(), A_g_return );
1058 TEST_EQUALITY( c->C_g(), C_g_return );
1059}
1060
1061
1062// This unit test shows that you can remove the RCP in the C object
1063// and the A object will still live on.
1064TEUCHOS_UNIT_TEST( RCP, invertObjectOwnership_remove_A )
1065{
1066 RCP<A> a = createACFactory();
1067 extractCFromA(a)->set_A(null);
1068 RCP<C> c = extractCFromA(a);
1069 TEST_EQUALITY_CONST( a.strong_count(), 1 );
1070 TEST_EQUALITY_CONST( c->get_A(), null );
1071 TEST_EQUALITY( a->A_g(), A_g_return );
1072 TEST_EQUALITY( c->C_g(), C_g_return );
1073}
1074
1075
1076//
1077// createRCPWithBadDealloc
1078//
1079
1080
1081RCP<A> createRCPWithBadDealloc()
1082{
1083 return rcp(new A[1]); // Will use delete but should use delete []!
1084}
1085
1086
1087template<typename T>
1088class DeallocArrayDeleteExtraData {
1089public:
1090 static RCP<DeallocArrayDeleteExtraData<T> > create(T *ptr)
1091 { return rcp(new DeallocArrayDeleteExtraData(ptr)); }
1092 ~DeallocArrayDeleteExtraData() { delete [] ptr_; }
1093private:
1094 T *ptr_;
1095 DeallocArrayDeleteExtraData(T *ptr) : ptr_(ptr) {}
1096 // Not defined!
1097 DeallocArrayDeleteExtraData();
1098 DeallocArrayDeleteExtraData(const DeallocArrayDeleteExtraData&);
1099 DeallocArrayDeleteExtraData& operator=(const DeallocArrayDeleteExtraData&);
1100};
1101
1102
1103// This unit test shows how you can use extra data to fix a bad deallocation
1104// policy
1105TEUCHOS_UNIT_TEST( RCP, Fix_createRCPWithBadDealloc )
1106{
1107 using Teuchos::inOutArg;
1108 using Teuchos::set_extra_data;
1109 // Create object with bad deallocator
1110 RCP<A> a = createRCPWithBadDealloc();
1111 TEST_ASSERT(nonnull(a));
1112 // Disable default (incorrect) dealloc and set a new deallocation policy as extra data!
1113 a.release();
1114 set_extra_data( DeallocArrayDeleteExtraData<A>::create(a.getRawPtr()), "dealloc",
1115 inOutArg(a));
1116}
1117
1118
1122TEUCHOS_UNIT_TEST( RCP, aliasing_constructor )
1123{
1126 Teuchos::RCP<A> c_rcp(a_rcp, b_rcp.get());
1127
1129 TEST_EQUALITY_CONST(c_rcp.get(), b_rcp.get());
1130 TEST_EQUALITY(c_rcp->A_g(), b_rcp->A_g());
1131 TEST_EQUALITY(c_rcp->A_f(), b_rcp->A_f());
1132 TEST_ASSERT( c_rcp.shares_resource(a_rcp) );
1133}
1134
1135
1136//
1137// Test RCP/boost::shared_ptr covnersions
1138//
1139
1140
1141#ifdef HAVE_TEUCHOS_BOOST
1142
1143
1144TEUCHOS_UNIT_TEST( boost_shared_ptr, nonnull_is_null )
1145{
1146 using boost::shared_ptr;
1147 ECHO(shared_ptr<A> a_sptr(new A));
1148 TEST_EQUALITY_CONST(is_null(a_sptr), false);
1149 TEST_EQUALITY_CONST(nonnull(a_sptr), true);
1150 ECHO(a_sptr = shared_ptr<A>());
1151 TEST_EQUALITY_CONST(is_null(a_sptr), true);
1152 TEST_EQUALITY_CONST(nonnull(a_sptr), false);
1153}
1154
1155
1156#endif // HAVE_TEUCHOS_BOOST
1157
1158
1159//
1160// Test RCP/std::shared_ptr covnersions
1161//
1162
1163
1164#ifdef HAVE_TEUCHOSCORE_CXX11
1165
1166
1167TEUCHOS_UNIT_TEST( std_shared_ptr, nonnull_is_null )
1168{
1169 using std::shared_ptr;
1170 ECHO(shared_ptr<A> a_sptr(new A));
1171 TEST_EQUALITY_CONST(Teuchos::is_null(a_sptr), false);
1173 ECHO(a_sptr = shared_ptr<A>());
1175 TEST_EQUALITY_CONST(Teuchos::nonnull(a_sptr), false);
1176}
1177
1178
1179TEUCHOS_UNIT_TEST( std_shared_ptr, convert_to_RCP_null )
1180{
1181 const std::shared_ptr<A> a_sptr1;
1182 const RCP<A> a_rsptr1 = rcp(a_sptr1);
1183 TEST_EQUALITY( a_rsptr1.get(), a_sptr1.get() );
1184 TEST_ASSERT(is_null(a_rsptr1));
1185
1186 const std::shared_ptr<A> a_sptr2 = get_shared_ptr(a_rsptr1);
1187 TEST_EQUALITY( a_sptr1.get(), a_sptr1.get() );
1188 TEST_ASSERT(Teuchos::is_null(a_sptr2));
1189}
1190
1191
1192TEUCHOS_UNIT_TEST( std_shared_ptr, convert_to_RCP )
1193{
1194 const std::shared_ptr<A> a_sptr1(new C());
1195 const RCP<A> a_rsptr1 = rcp(a_sptr1);
1196 TEST_EQUALITY( a_rsptr1.get(), a_sptr1.get() );
1197 TEST_EQUALITY( a_rsptr1.getRawPtr(), a_sptr1.get() );
1198 TEST_EQUALITY( a_rsptr1.get(), a_rsptr1.getRawPtr() );
1199
1200 const std::shared_ptr<A> a_sptr2 = get_shared_ptr(a_rsptr1);
1201 TEST_EQUALITY( a_sptr1.get(), a_sptr1.get() );
1202 // NOTE: There is no portable way to check that two std::shared_ptr objects
1203 // share the same underlying shared node :-(
1204}
1205
1206
1207TEUCHOS_UNIT_TEST( std_shared_ptr, convert_from_RCP_null )
1208{
1209 const RCP<A> a_rcp1;
1210 const std::shared_ptr<A> a_sptr1(get_shared_ptr(a_rcp1));
1211 TEST_EQUALITY( a_rcp1.get(), a_sptr1.get() );
1212 TEST_ASSERT(Teuchos::is_null(a_sptr1));
1213
1214 const RCP<A> a_rcp2 = rcp(a_sptr1);
1215 TEST_EQUALITY(a_rcp2.get(), a_sptr1.get());
1216 TEST_ASSERT(is_null(a_rcp2));
1217}
1218
1219
1220TEUCHOS_UNIT_TEST( std_shared_ptr, convert_from_RCP )
1221{
1222 const RCP<A> a_rcp1(new C());
1223 const std::shared_ptr<A> a_sptr1(get_shared_ptr(a_rcp1));
1224 TEST_EQUALITY( a_rcp1.get(), a_sptr1.get() );
1225 TEST_EQUALITY( a_rcp1.getRawPtr(), a_sptr1.get() );
1226 TEST_EQUALITY( a_sptr1.get(), a_rcp1.getRawPtr() );
1227
1228 const RCP<A> a_rcp2 = rcp(a_sptr1);
1229 TEST_EQUALITY( a_rcp2.get(), a_sptr1.get() );
1230 TEST_EQUALITY( a_rcp2.get(), a_rcp1.get() );
1231 TEST_ASSERT( a_rcp1.shares_resource(a_rcp2) );
1232}
1233
1234
1235#ifdef TEUCHOS_DEBUG
1236
1237
1238TEUCHOS_UNIT_TEST( std_shared_ptr, convert_from_RCP_lookup_node )
1239{
1240 const RCP<A> a_rcp1(new C());
1241 const std::shared_ptr<A> a_sptr1(get_shared_ptr(a_rcp1));
1242 TEST_EQUALITY( a_sptr1.get(), a_rcp1.get() );
1243
1244 const RCP<C> c_rcp1 = rcp(std::dynamic_pointer_cast<C>(a_sptr1));
1245 TEST_EQUALITY( c_rcp1.get(), a_rcp1.get() );
1246 TEST_ASSERT( c_rcp1.shares_resource(a_rcp1) );
1247 // NOTE: The above test shows how Teuchos::RCP machinery will automatically
1248 // look up the underlying RCPNode object and use it!
1249}
1250
1251
1252#endif // TEUCHOS_DEBUG
1253
1254
1255#endif // HAVE_TEUCHOSCORE_CXX11
1256
1257
1258
1259//
1260// Template Instantiations
1261//
1262
1263
1264#ifdef TEUCHOS_DEBUG
1265
1266# define DEBUG_UNIT_TEST_GROUP( T ) \
1267
1268#else
1269
1270# define DEBUG_UNIT_TEST_GROUP( T )
1271
1272#endif
1273
1274
1275#define UNIT_TEST_GROUP( T ) \
1276 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCP, weakDelete, T ) \
1277 DEBUG_UNIT_TEST_GROUP(T)
1278
1279
1284
1285
1286} // namespace
#define UNIT_TEST_GROUP(T)
const int C_f_return
const int A_g_return
const int C_g_return
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEST_INEQUALITY_CONST(v1, v2)
Assert the inequality of v1 and constant v2.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_NOTHROW(code)
Asserr that the statement 'code' does not thrown any excpetions.
#define TEST_THROW(code, ExceptType)
Assert that the statement 'code' throws the exception 'ExceptType' (otherwise the test fails).
#define ECHO(statement)
Echo the given statement before it is executed.
#define SET_RCPNODE_TRACING()
Reference-counted pointer class and non-member templated function implementations.
Unit testing support.
#define TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(TEST_GROUP, TEST_NAME, TYPE)
Macro for defining a templated unit test with one template parameter.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
int call_C_f()
void set_C(const Teuchos::RCP< C > &c)
Dangling reference error exception class.
Thrown if a duplicate owning RCP is creatd the the same object.
Null reference error exception class.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
Debug-mode RCPNode tracing class.
Smart reference counting pointer class for automatic garbage collection.
Concrete serial communicator subclass.
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool nonnull(const boost::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.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
Definition PackageA.cpp:3
Definition PackageC.cpp:3
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.