Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
RCPNodeHandle_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_RCPNode.hpp"
46#include "Teuchos_getConst.hpp"
48#include "TestClasses.hpp"
49
50
51namespace Teuchos {
52
53
54template<class T>
55class MockRCP {
56public:
58 {
59 return (T*)(0x777777); // Just some bogus address printed to out
60 }
61};
62
63
64template<class T>
65RCPNode* basicRCPNodeNoAlloc(T* p, const bool has_ownership)
66{
68 new RCPNodeTmpl<T,DeallocDelete<T> >(p, DeallocDelete<T>(), has_ownership);
69 return rcpNode;
70}
71
72
73template<class T>
74RCPNode* basicRCPNode(const bool has_ownership, T **p_out = 0)
75{
76 T *p = new T;
77 if (p_out)
78 *p_out = p;
79 RCPNode *rcpNode = basicRCPNodeNoAlloc<T>(p, has_ownership);
80 return rcpNode;
81}
82
83
85{
88 (*node)->delete_obj();
89 delete (*node);
90 *node = 0;
91}
92
93
94template<class T>
95RCPNodeHandle basicRCPNodeHandle(const bool has_ownership, T **p_out = 0)
96{
97 T *p = 0;
98 RCPNode *rcpNode = basicRCPNode(has_ownership, &p);
99 if (p_out)
100 *p_out = p;
101#ifdef TEUCHOS_DEBUG
102 return RCPNodeHandle(rcpNode, p, typeName(*p), concreteTypeName(*p), has_ownership);
103#else
104 return RCPNodeHandle(rcpNode);
105#endif
106}
107
108
112
113
114//
115// Non-templated tests
116//
117
118
124
125
127{
129 TEST_EQUALITY_CONST( nodeRef.strong_count(), 0 );
130 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false );
131 nodeRef.has_ownership(true);
132 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false );
133#ifdef TEUCHOS_DEBUG
134 TEST_EQUALITY_CONST( nodeRef.get_base_obj_map_key_void_ptr(), static_cast<void*>(0) );
135 TEST_THROW({nodeRef.set_extra_data(any(),"", PRE_DESTROY, true);},
137 TEST_THROW({any &a = nodeRef.get_extra_data("int","blob"); (void)a;},
139 TEST_THROW({const any &a = getConst(nodeRef).get_extra_data("int","blob"); (void)a;},
141 TEST_THROW({any *a = nodeRef.get_optional_extra_data("int","blob"); (void)a;},
143 TEST_THROW({const any *a = getConst(nodeRef).get_optional_extra_data("int","blob"); (void)a;},
145#endif // TEUCHOS_DEBUG
146}
147
148
149#ifdef TEUCHOS_DEBUG
150
151
152TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_basic )
153{
154
155 typedef RCPNodeTracer::RCPNodeStatistics RCPNodeStatistics;
156
158
159 RCPNode *node = basicRCPNode<A>(true);
160
161 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes();
162 const RCPNodeStatistics rcpNodeStatisticsBefore = RCPNodeTracer::getRCPNodeStatistics();
163
164 out << std::endl;
165 ECHO(RCPNodeTracer::addNewRCPNode(node, "dummy"));
166
167 out << std::endl;
168 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
169
170 out << std::endl;
171 const RCPNodeStatistics rcpNodeStatistics1 = RCPNodeTracer::getRCPNodeStatistics();
172 TEST_COMPARE(rcpNodeStatistics1.maxNumRCPNodes, >=,
173 rcpNodeStatisticsBefore.maxNumRCPNodes);
174 TEST_EQUALITY(rcpNodeStatistics1.totalNumRCPNodeAllocations,
175 rcpNodeStatisticsBefore.totalNumRCPNodeAllocations+1);
176 TEST_EQUALITY(rcpNodeStatistics1.totalNumRCPNodeDeletions,
177 rcpNodeStatisticsBefore.totalNumRCPNodeDeletions);
178
179 out << std::endl;
181
182 out << std::endl;
183 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase);
184
185 out << std::endl;
186 const RCPNodeStatistics rcpNodeStatistics2 = RCPNodeTracer::getRCPNodeStatistics();
187 TEST_COMPARE(rcpNodeStatistics2.maxNumRCPNodes, >=,
188 rcpNodeStatisticsBefore.maxNumRCPNodes);
189 TEST_EQUALITY(rcpNodeStatistics2.totalNumRCPNodeAllocations,
190 rcpNodeStatisticsBefore.totalNumRCPNodeAllocations+1);
191 TEST_EQUALITY(rcpNodeStatistics2.totalNumRCPNodeDeletions,
192 rcpNodeStatisticsBefore.totalNumRCPNodeDeletions+1);
193
194 out << std::endl;
195 std::ostringstream statsOut_oss;
196 RCPNodeTracer::printRCPNodeStatistics(rcpNodeStatistics2, statsOut_oss);
197 std::ostringstream expectedStatsOut_oss;
198 expectedStatsOut_oss
199 << "\n***"
200 << "\n*** RCPNode Tracing statistics:"
201 << "\n**\n"
202 << "\n maxNumRCPNodes = "<<rcpNodeStatistics2.maxNumRCPNodes
203 << "\n totalNumRCPNodeAllocations = "<<rcpNodeStatistics2.totalNumRCPNodeAllocations
204 << "\n totalNumRCPNodeDeletions = "<<rcpNodeStatistics2.totalNumRCPNodeDeletions
205 << "\n";
206 TEST_EQUALITY(statsOut_oss.str(), expectedStatsOut_oss.str());
207
208 deleteRCPNode(&node);
209
210}
211
212
213TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_owning_twice_error )
214{
216#ifdef HAVE_TEUCHOS_STACKTRACE
217 // Make sure that you store a stacktrace so as not to affect the RCPNode count below!
219#endif
220 A *a_ptr = new A;
221 RCPNode *node1 = basicRCPNodeNoAlloc<A>(a_ptr, true);
222 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes();
223 ECHO(RCPNodeTracer::addNewRCPNode(node1, "dummy1"));
224 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
225 RCPNode *node2 = basicRCPNodeNoAlloc<A>(a_ptr, true);
226 TEST_THROW(RCPNodeTracer::addNewRCPNode(node2, "dummy2"), DuplicateOwningRCPError);
228 deleteRCPNode(&node1);
229 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase);
230 node2->has_ownership(false);
231 deleteRCPNode(&node2);
232}
233
234
235TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_nonowning_twice_okay_1 )
236{
238 A *a_ptr = new A;
239 RCPNode *node1 = basicRCPNodeNoAlloc<A>(a_ptr, true);
240 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes();
241 ECHO(RCPNodeTracer::addNewRCPNode(node1, "dummy1"));
242 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
243 RCPNode *node2 = basicRCPNodeNoAlloc<A>(a_ptr, false);
244 ECHO(RCPNodeTracer::addNewRCPNode(node2, "dummy2"));
245 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+2);
248 deleteRCPNode(&node2);
249 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
251 deleteRCPNode(&node1);
252 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase);
253}
254
255
256TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_nonowning_twice_okay_2 )
257{
259 A *a_ptr = new A;
260 RCPNode *node1 = basicRCPNodeNoAlloc<A>(a_ptr, false);
261 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes();
262 ECHO(RCPNodeTracer::addNewRCPNode(node1, "dummy1"));
263 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
264 RCPNode *node2 = basicRCPNodeNoAlloc<A>(a_ptr, true);
265 ECHO(RCPNodeTracer::addNewRCPNode(node2, "dummy2"));
266 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+2);
269 deleteRCPNode(&node2);
270 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
272 deleteRCPNode(&node1);
273 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase);
274}
275
276
277TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_two_nodes_same_obj )
278{
280 ECHO(C *c_ptr = new C);
281 ECHO(RCPNode *node_c = basicRCPNodeNoAlloc<C>(c_ptr, true));
282 ECHO(RCPNode *node_b1 = basicRCPNodeNoAlloc<B1>(c_ptr, true));
283 ECHO(const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes());
284 ECHO(RCPNodeTracer::addNewRCPNode(node_c, "dummy"));
285 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
286#ifdef HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR
287 // We can detect that these are the same object!
288 TEST_THROW(RCPNodeTracer::addNewRCPNode(node_b1, "dummy"), DuplicateOwningRCPError);
289#else
290 // We can not detect if these are the same object!
291 ECHO(RCPNodeTracer::addNewRCPNode(node_b1, "dummy"));
292 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+2);
294#endif
295 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1);
297 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase);
298 ECHO(node_b1->has_ownership(false));
299 ECHO(deleteRCPNode(&node_b1));
300 ECHO(deleteRCPNode(&node_c));
301}
302
303
304#ifdef HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING
305TEUCHOS_UNIT_TEST( RCPNodeHandle, remove_RCPNode_missing_node )
306{
308 RCPNode *node = basicRCPNode<A>(true);
309 TEST_THROW(RCPNodeTracer::removeRCPNode(node), std::logic_error);
310 deleteRCPNode(&node);
311}
312#endif // HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING
313
314
315#endif // TEUCHOS_DEBUG
316
317
318//
319// Templated tests
320//
321
322
324{
325 T *p = 0;
327 TEST_EQUALITY_CONST( nodeRef.strong_count(), 1 );
328 TEST_EQUALITY_CONST( nodeRef.has_ownership(), true );
329 nodeRef.has_ownership(false);
330 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false );
331#ifdef TEUCHOS_DEBUG
332 TEST_INEQUALITY_CONST( nodeRef.get_base_obj_map_key_void_ptr(), static_cast<void*>(0) );
333 TEST_EQUALITY( nodeRef.get_base_obj_map_key_void_ptr(), static_cast<void*>(p) );
334 TEST_THROW({any &a = nodeRef.get_extra_data("int","blob"); (void)a;},
335 std::invalid_argument);
336 TEST_THROW({const any &a = getConst(nodeRef).get_extra_data("int","blob"); (void)a;},
337 std::invalid_argument);
338#endif // TEUCHOS_DEBUG
339 TEST_EQUALITY_CONST(nodeRef.get_optional_extra_data("int","blob"), 0);
340 TEST_EQUALITY_CONST(getConst(nodeRef).get_optional_extra_data("int","blob"), 0);
341 nodeRef.has_ownership(true);
342}
343
344
346{
348 TEST_EQUALITY_CONST( nodeRef.strong_count(), 1 );
349 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false );
350 nodeRef.has_ownership(true);
351 TEST_EQUALITY_CONST( nodeRef.has_ownership(), true );
352}
353
354
356{
357
359 TEST_EQUALITY_CONST( nodeRef1.strength(), RCP_STRONG );
360
361 ECHO(RCPNodeHandle nodeRef2 = nodeRef1.create_weak());
362
363 TEST_EQUALITY_CONST( nodeRef2.strength(), RCP_WEAK );
364 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 1 );
365 TEST_EQUALITY_CONST( nodeRef1.weak_count(), 1 );
366 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 1 );
367 TEST_EQUALITY_CONST( nodeRef2.weak_count(), 1 );
368
369 ECHO(RCPNodeHandle nodeRef3 = nodeRef2.create_strong());
370
371 TEST_EQUALITY_CONST( nodeRef3.strength(), RCP_STRONG );
372 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 2 );
373 TEST_EQUALITY_CONST( nodeRef1.weak_count(), 1 );
374 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 2 );
375 TEST_EQUALITY_CONST( nodeRef2.weak_count(), 1 );
376
378 ECHO(nodeRef2.debug_assert_valid_ptr(mockRCP)); // Should not throw!
379
380 // This will make the underlying object T get deleted!
381 ECHO(nodeRef1 = null);
382 ECHO(nodeRef3 = null);
383
384 TEST_EQUALITY_CONST( nodeRef1.node_ptr()==0, true );
385 TEST_EQUALITY_CONST( nodeRef1.is_node_null(), true );
386 TEST_EQUALITY_CONST( nodeRef1.is_valid_ptr(), true );
387
388 TEST_EQUALITY_CONST( nodeRef2.node_ptr()!=0, true );
389 TEST_EQUALITY_CONST( nodeRef2.is_node_null(), false );
390 TEST_EQUALITY_CONST( nodeRef2.is_valid_ptr(), false );
391
392#ifdef TEUCHOS_DEBUG
393 TEST_THROW( nodeRef2.debug_assert_valid_ptr(mockRCP),
395#endif
396
397 ECHO(nodeRef2 = null); // Should make the underlying node go away
398
399}
400
401
403{
404
406 TEST_EQUALITY_CONST( nodeRef1.strength(), RCP_STRONG );
407
408 ECHO(RCPNodeHandle nodeRef2 = nodeRef1.create_weak());
409 TEST_EQUALITY_CONST( nodeRef2.strength(), RCP_WEAK );
410 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 1 );
411 TEST_EQUALITY_CONST( nodeRef1.weak_count(), 1 );
412 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 1 );
413 TEST_EQUALITY_CONST( nodeRef2.weak_count(), 1 );
414
416
417 ECHO(nodeRef2.debug_assert_valid_ptr(mockRCP)); // Should not throw!
418
419 ECHO(nodeRef2 = null); // The underlying object stays alive!
420
421 TEST_EQUALITY_CONST( nodeRef2.node_ptr()==0, true );
422 TEST_EQUALITY_CONST( nodeRef2.is_node_null(), true );
423 TEST_EQUALITY_CONST( nodeRef2.is_valid_ptr(), true );
424
425 TEST_EQUALITY_CONST( nodeRef1.node_ptr()!=0, true );
426 TEST_EQUALITY_CONST( nodeRef1.is_node_null(), false );
427 TEST_EQUALITY_CONST( nodeRef1.is_valid_ptr(), true );
428
429 nodeRef1.debug_assert_valid_ptr(mockRCP); // Should not throw!
430
431}
432
433//
434// Test behavior of RCP node tracing but only if it is off by default
435//
436// NOTE: If node tracing is on by default then we can't control how many nodes
437// get created in other code not in the unit test.
438//
439
440#if defined(TEUCHOS_DEBUG) && !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
441# define DO_RCPNODE_TRACING_TESTS 1
442#endif
443
444
445#ifdef DO_RCPNODE_TRACING_TESTS
446
447
448TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, debugWithNodeTracingPrint, T )
449{
450
452 RCPNodeTracer::setTracingActiveRCPNodes(true);
454
455 {
456
457 T *p = new T; // Never do this in production code!
458 const std::string T_name = "T_name";
459 const std::string concreateT_name = "concreateT_name";
460 const bool has_ownership = true;
461 RCPNode *node = new RCPNodeTmpl<T,DeallocDelete<T> >(
462 p, DeallocDelete<T>(), has_ownership);
463
464 RCPNodeHandle nodeRef(node, p, T_name, concreateT_name, has_ownership);
465
467
468 out << "\nMake sure output is printed when there is an active node with tracing ...\n";
469
470 const void* rcpNodeKey = RCPNodeTracer::getRCPNodeBaseObjMapKeyVoidPtr(p);
471
472 std::ostringstream expendedOutput_oss;
473 expendedOutput_oss
475 << "\n"
476 << " 0: RCPNode (map_key_void_ptr=" << rcpNodeKey << ")\n"
477 << " Information = {T="<<T_name<<", ConcreteT="<<concreateT_name<<", p="<<p<<", has_ownership="<<has_ownership<<"}\n"
478 << " RCPNode address = " << node << "\n"
479 << " insertionNumber = " << node->insertion_number()
480 << "\n\n"
482
483 std::ostringstream printActiveRCPNodes_out;
484 RCPNodeTracer::printActiveRCPNodes(printActiveRCPNodes_out);
485 TEST_EQUALITY( printActiveRCPNodes_out.str(), expendedOutput_oss.str() );
486
487 // NOTE: The above test basically copied and pasted the ouptut stream code
488 // from printActiveRCPNodes(...) and will need to be maintained
489 // with this code. However, this is a good test because it ensures that
490 // the arguments node, p, T_name, and concreateT_name are passed, stored,
491 // and retrieved correctly. It is also a good test because it ensures
492 // that output is printed when node tracing is turned on.
493 //
494 // This is the very definition of a "white box" test but that is just fine
495 // for a unit test.
496
497 }
498
500
501 out << "\nMake sure no output is printed when there are no active nodes ...\n";
502 const std::string expendedOutput = "";
503 std::ostringstream printActiveRCPNodes_out;
504 RCPNodeTracer::printActiveRCPNodes(printActiveRCPNodes_out);
505 TEST_EQUALITY( printActiveRCPNodes_out.str(), expendedOutput );
506
507 RCPNodeTracer::setTracingActiveRCPNodes(false);
509
510}
511
512
513TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, debugWithoutNodeTracingPrint, T )
514{
515
517 RCPNodeTracer::setTracingActiveRCPNodes(false);
519
520 T *p = new T; // Never do this in production code!
521 const std::string T_name = "T_name";
522 const std::string concreateT_name = "concreateT_name";
523 const bool has_ownership = true;
524 RCPNode *node = new RCPNodeTmpl<T,DeallocDelete<T> >(
525 p, DeallocDelete<T>(), has_ownership);
526
527 RCPNodeHandle nodeRef(node, p, T_name, concreateT_name, has_ownership);
528
530
531 out << "\nMake sure no output is printed when there are no active nodes without tracing ...\n";
532 const std::string expendedOutput = "";
533 std::ostringstream printActiveRCPNodes_out;
534 RCPNodeTracer::printActiveRCPNodes(printActiveRCPNodes_out);
535 TEST_EQUALITY( printActiveRCPNodes_out.str(), expendedOutput );
536
537}
538
539
540#endif // DO_RCPNODE_TRACING_TESTS
541
542
544{
547 TEST_EQUALITY( nodeRef1.node_ptr(), nodeRef2.node_ptr() );
548 TEST_EQUALITY_CONST( nodeRef1.same_node(nodeRef2), true );
549 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 2 );
550 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 2 );
551 TEST_EQUALITY_CONST( nodeRef1.has_ownership(), true );
552 TEST_EQUALITY_CONST( nodeRef2.has_ownership(), true );
553}
554
555
557{
559 RCPNodeHandle nodeRef2(std::move(nodeRef1));
560 TEST_EQUALITY_CONST( nodeRef1.node_ptr(), 0 );
561 TEST_INEQUALITY_CONST( nodeRef2.node_ptr(), 0 );
562 TEST_EQUALITY_CONST( nodeRef1.same_node(nodeRef2), false );
563 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 0 );
564 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 1 );
565 TEST_EQUALITY_CONST( nodeRef1.has_ownership(), false );
566 TEST_EQUALITY_CONST( nodeRef2.has_ownership(), true );
567}
568
569
580
581
583{
586 nodeRef2 = std::move(nodeRef1);
587 TEST_EQUALITY_CONST( nodeRef1.node_ptr(), 0 );
588 TEST_INEQUALITY_CONST( nodeRef2.node_ptr(), 0 );
589 TEST_EQUALITY_CONST( nodeRef1.same_node(nodeRef2), false );
590 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 0 );
591 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 1 );
592 TEST_EQUALITY_CONST( nodeRef1.has_ownership(), false );
593 TEST_EQUALITY_CONST( nodeRef2.has_ownership(), true );
594}
595
596
598{
599
601
602 const int v1 = 2;
603 const any a1(v1);
604 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true);
605
606 any &a2 = nodeRef.get_extra_data(a1.typeName(), "a1");
607 TEST_EQUALITY_CONST( a1.same(a2), true );
609
610 any *a3 = nodeRef.get_optional_extra_data(a1.typeName(), "a1");
611 TEST_EQUALITY_CONST( a3!=0, true );
612 TEST_EQUALITY( &a2, a3 );
613 TEST_EQUALITY_CONST( a3->same(a1), true );
614
616
617 const int v2 = 3;
618 a2 = v2;
621
622 any &a4 = nodeRef2.get_extra_data(a1.typeName(), "a1");
623 TEST_EQUALITY( &a4, &a2 );
624 TEST_EQUALITY( &a4, a3 );
626
627}
628
629
631{
632
634
635 const int v1 = 2;
636 const any a1(v1);
637 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true);
638
640
641 const any &a2 = nodeRef2.get_extra_data(a1.typeName(), "a1");
642 TEST_EQUALITY_CONST( a1.same(a2), true );
644
645 const any *a3 = nodeRef2.get_optional_extra_data(a1.typeName(), "a1");
646 TEST_EQUALITY_CONST( a3!=0, true );
647 TEST_EQUALITY( &a2, a3 );
648 TEST_EQUALITY_CONST( a3->same(a1), true );
649
650}
651
652
654{
655
657
658 const int v1 = 2;
659 const any a1(v1);
660 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true);
661
662#ifdef TEUCHOS_DEBUG
663
664 TEST_THROW({nodeRef.get_extra_data("wrong type", "a1");},
665 std::invalid_argument);
666
667 TEST_THROW({nodeRef.get_extra_data(a1.typeName(), "wrong name");},
668 std::invalid_argument);
669
670#endif // TEUCHOS_DEBUG
671
672 any *a2 = nodeRef.get_optional_extra_data("wrong type", "a1");
674
675 any *a3 = nodeRef.get_optional_extra_data(a1.typeName(), "wrong name");
677
678}
679
680
682{
683
685
686 const int v1 = 2;
687 const any a1(v1);
688 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true);
689
691
692#ifdef TEUCHOS_DEBUG
693
694 TEST_THROW({nodeRef2.get_extra_data("wrong type", "a1");},
695 std::invalid_argument);
696
697 TEST_THROW({nodeRef2.get_extra_data(a1.typeName(), "wrong name");},
698 std::invalid_argument);
699
700#endif // TEUCHOS_DEBUG
701
702 const any *a2 = nodeRef2.get_optional_extra_data("wrong type", "a1");
704
705 const any *a3 = nodeRef2.get_optional_extra_data(a1.typeName(), "wrong name");
707
708}
709
710
711//
712// Instantiations
713//
714
715
716#ifdef DO_RCPNODE_TRACING_TESTS
717
718# define DEBUG_UNIT_TEST_GROUP( T ) \
719 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, debugWithNodeTracingPrint, T ) \
720 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, debugWithoutNodeTracingPrint, T )
721
722#else
723
724# define DEBUG_UNIT_TEST_GROUP( T )
725
726#endif
727
728
729#define UNIT_TEST_GROUP( T ) \
730 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, basicConstruct_owns_mem, T ) \
731 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, basicConstruct_no_owns_mem, T ) \
732 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, weakPtr_basic_1, T ) \
733 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, weakPtr_basic_2, T ) \
734 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, copyConstruct, T ) \
735 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, moveConstruct, T ) \
736 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, copyAssignmentOperator, T ) \
737 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, moveAssignmentOperator, T ) \
738 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_basic, T ) \
739 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_basic_const, T ) \
740 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_failed, T ) \
741 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_failed_const, T ) \
742 DEBUG_UNIT_TEST_GROUP(T)
743
744
746//UNIT_TEST_GROUP(B1)
747//UNIT_TEST_GROUP(B2)
749//UNIT_TEST_GROUP(D)
751
752// 2008/09/22: rabartl: Above: We don't need to test with all of these classes
753// in order to test this functionality.
754
755
756} // namespace Teuchos
#define UNIT_TEST_GROUP(T)
#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_THROW(code, ExceptType)
Assert that the statement 'code' throws the exception 'ExceptType' (otherwise the test fails).
#define TEST_COMPARE(v1, comp, v2)
Assert that v1 comp v2 (where comp = '==', '>=", "!=", etc).
#define ECHO(statement)
Echo the given statement before it is executed.
Reference-counted pointer node classes.
#define SET_RCPNODE_TRACING()
Defines basic traits returning the name of a type in a portable and readable way.
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.
Dangling reference error exception class.
Null reference error exception class.
Handle class that manages the RCPNode's reference counting.
static const void * getRCPNodeBaseObjMapKeyVoidPtr(T *p)
Get a const void* address to be used as the lookup key for an RCPNode given its embedded object's typ...
static std::string getCommonDebugNotesString()
Common error message string on how to debug RCPNode problems.
static void printRCPNodeStatistics(const RCPNodeStatistics &rcpNodeStatistics, std::ostream &out)
Print the RCPNode allocation statistics.
static RCPNode * getExistingRCPNode(T *p)
Return a raw pointer to an existing owning RCPNode given the address to the underlying object if it e...
static RCPNodeStatistics getRCPNodeStatistics()
Return the statistics on RCPNode allocations.
static int numActiveRCPNodes()
Print the number of active RCPNode objects currently being tracked.
static std::string getActiveRCPNodeHeaderString()
Header string used in printActiveRCPNodes().
static bool isTracingActiveRCPNodes()
Return if we are tracing active nodes or not.
static void removeRCPNode(RCPNode *rcp_node)
Remove an RCPNode from global list.
static void printActiveRCPNodes(std::ostream &out)
Print the list of currently active RCP nodes.
static void addNewRCPNode(RCPNode *rcp_node, const std::string &info)
Add new RCPNode to the global list.
Node class to keep track of address and the reference count for a reference-counted utility class and...
Concrete serial communicator subclass.
Modified boost::any class, which is a container for a templated value.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
Definition PackageA.cpp:3
Definition PackageC.cpp:3
RCPNodeHandle basicRCPNodeHandle(const bool has_ownership, T **p_out=0)
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
void deleteRCPNode(RCPNode **node)
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
RCPNode * basicRCPNode(const bool has_ownership, T **p_out=0)
RCPNode * basicRCPNodeNoAlloc(T *p, const bool has_ownership)